merge
commit
e0c9174609
130
.hgtags
130
.hgtags
|
|
@ -72,35 +72,35 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
|
|||
461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
|
||||
9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
|
||||
9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
|
||||
42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
|
||||
42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
|
||||
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
|
||||
c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
|
||||
c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
|
||||
c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
|
||||
c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
|
||||
56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
|
||||
d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
|
||||
d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
|
||||
42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
|
||||
42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
|
||||
c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
|
||||
c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
|
||||
214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
|
||||
214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
|
||||
52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
|
||||
ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
|
||||
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
|
||||
d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
|
||||
0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
|
||||
0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
|
||||
3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
|
||||
214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
|
||||
214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
|
||||
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
|
||||
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
|
||||
8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
|
||||
8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
|
||||
3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
|
||||
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
|
||||
7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
|
||||
800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
|
||||
bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
|
||||
bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
|
||||
5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
|
||||
dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
|
||||
dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
|
||||
5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
|
||||
beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
|
||||
beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
|
||||
be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
|
||||
|
|
@ -119,50 +119,50 @@ e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
|
|||
9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
|
||||
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
|
||||
e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
|
||||
6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
|
||||
fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
|
||||
6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
|
||||
6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
|
||||
be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
|
||||
be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
|
||||
057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
|
||||
057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
|
||||
19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
|
||||
09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
|
||||
09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
|
||||
6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
|
||||
6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
|
||||
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
|
||||
e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
|
||||
e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
|
||||
057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
|
||||
057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
|
||||
6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
|
||||
6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
|
||||
493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
|
||||
493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
|
||||
502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
|
||||
2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
|
||||
2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
|
||||
493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
|
||||
493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
|
||||
54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
|
||||
ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
|
||||
29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
|
||||
29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
|
||||
4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
|
||||
4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
|
||||
54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
|
||||
ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
|
||||
599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
|
||||
599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
|
||||
fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
|
||||
fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
|
||||
6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
|
||||
b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
|
||||
b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
|
||||
fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
|
||||
fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
|
||||
1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
|
||||
1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
|
||||
82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
|
||||
364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
|
||||
364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
|
||||
f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
|
||||
42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
|
||||
42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
|
||||
1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
|
||||
1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
|
||||
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
|
||||
e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
|
||||
b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
|
||||
|
|
@ -170,9 +170,9 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
|
|||
6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
|
||||
61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
|
||||
61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
|
||||
586907287be581817b2422b5137971b22d54ea48 3.0.4-start
|
||||
0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
|
||||
0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
|
||||
586907287be581817b2422b5137971b22d54ea48 3.0.4-start
|
||||
92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
|
||||
c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
|
||||
2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
|
||||
|
|
@ -193,11 +193,11 @@ e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
|
|||
c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
|
||||
9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
|
||||
9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
|
||||
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
|
||||
a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
|
||||
40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
|
||||
523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
|
||||
523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
|
||||
a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
|
||||
a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
|
||||
80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
|
||||
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
|
||||
3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
|
||||
|
|
@ -248,57 +248,68 @@ bb9932a7a5fd00edf52d95f354e3b37ae6a942db DRTVWR-156
|
|||
6414ecdabc5d89515b08d1f872cf923ed3a5523a DRTVWR-148
|
||||
2a3965b3ad202df7ea25d2be689291bb14a1280e DRTVWR-155
|
||||
24a7281bef42bd4430ceb25db8b195449c2c7de3 DRTVWR-153
|
||||
a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
|
||||
9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
|
||||
5910f8063a7e1ddddf504c2f35ca831cc5e8f469 DRTVWR-160
|
||||
f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 3.3.3-beta1
|
||||
f0a174c2adb4bc39b16722a61d7eeb4f2a1d4843 DRTVWR-144
|
||||
2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
|
||||
089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
|
||||
600f3b3920d94de805ac6dc8bb6def9c069dd360 DRTVWR-162
|
||||
c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
|
||||
2d6c0634b11e6f3df11002b8510a72a0433da00a DRTVWR-164
|
||||
80b5e5e9775966d3839331ffa7a16a60f9d7c930 DRTVWR-165
|
||||
fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2
|
||||
af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169
|
||||
4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3
|
||||
6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release
|
||||
a716684aa7c07c440b1de5815b8a1f3dd3fd8bfb DRTVWR-159
|
||||
9a78ac13f047056f788c4734dd91aebfe30970e3 DRTVWR-157
|
||||
089e5c84b2dece68f2b016c842ef9b5de4786842 DRTVWR-161
|
||||
c08e2ac17a99973b2a94477659220b99b8847ae2 DRTVWR-163
|
||||
b9d0170b62eb1c7c3adaa37a0b13a833e5e659f9 DRTVWR-171
|
||||
050e48759337249130f684b4a21080b683f61732 DRTVWR-168
|
||||
09ef7fd1b0781f33b8a3a9af6236b7bcb4831910 DRTVWR-170
|
||||
f87bfbe0b62d26f451d02a47c80ebef6b9168fc2 DRTVWR-158
|
||||
f91d003091a61937a044652c4c674447f7dcbb7a 3.3.4-beta1
|
||||
005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
|
||||
bce218b2b45b730b22cc51e4807aa8b571cadef3 DRTVWR-173
|
||||
cbea6356ce9cb0c313b6777f10c5c14783264fcc DRTVWR-174
|
||||
82b5330bc8b17d0d4b598832e9c5a92e90075682 3.3.4-beta2
|
||||
57d221de3df94f90b55204313c2cef044a3c0ae2 DRTVWR-176
|
||||
eb539c65e6ee26eea2bf373af2d0f4b52dc91289 DRTVWR-177
|
||||
a8057e1b9a1246b434a27405be35e030f7d28b0c 3.3.4-beta3
|
||||
888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
|
||||
4281aa899fb2cedb7a9ca7ce91c5c29d4aa69594 DRTVWR-180
|
||||
5c08e1d8edd871807153603b690e3ee9dbb548aa DRTVWR-183
|
||||
6c75f220b103db1420919c8b635fe53e2177f318 3.3.4-beta4
|
||||
9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
|
||||
ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
|
||||
28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
|
||||
005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167
|
||||
888768f162d2c0a8de1dcc5fb9a08bd8bd120a6b DRTVWR-175
|
||||
a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182
|
||||
1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1
|
||||
9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
|
||||
81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
|
||||
47f0d08ba7ade0a3905074009067c6d3df7e16ae DRTVWR-190
|
||||
cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
|
||||
c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
|
||||
9ee9387789701d597130f879d9011a4958753862 DRTVWR-189
|
||||
421126293dcbde918e0da027ca0ab9deb5b4fbf2 DRTVWR-192
|
||||
4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
|
||||
33a2fc7a910ae29ff8b4850316ed7fbff9f64d33 DRTVWR-195
|
||||
e9732c739c8a72a590216951505ea9c76a526a84 DRTVWR-193
|
||||
78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
|
||||
7602f61c804a512764e349c034c02ddabeefebc4 DRTVWR-196
|
||||
ae5c83dd61d2d37c45f1d5b8bf2b036d87599f1b DRTVWR-198
|
||||
507bdfbd6bf844a511c1ffeda4baa80016ed1346 DRTVWR-197
|
||||
b1dbb1a83f48f93f6f878cff9e52d2cb635e145c 3.4.0-beta2
|
||||
37402e2b19af970d51b0a814d79892cc5647532b DRTVWR-200
|
||||
182a9bf30e81070361bb020a78003b1cf398e79c 3.4.0-beta3
|
||||
248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
|
||||
6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
|
||||
7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
|
||||
7649a3dff5ec22d3727377e5f02efd0f421e4cb5 DRTVWR-201
|
||||
84fb70dfe3444e75a44fb4bee43e2fc8221cebdd 3.4.0-beta4
|
||||
de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
|
||||
092a9effbedd1a0276fa5ced520992ce00f96fbf CHUI-PV-0
|
||||
573e863be2f26d3687161def4b9fea9b7038dda8 3.4.0-beta5
|
||||
34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
|
||||
6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
|
||||
7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
|
||||
8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
|
||||
351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
|
||||
af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
|
||||
|
|
@ -309,6 +320,7 @@ ceed0b65a69f1eac20d523e0203320a32f9a3f3c DRTVWR-215
|
|||
97977c67245f52db20eb15f1918cc0f24778cabc 3.4.0-release
|
||||
5adb2b8f96c3cac88ad7c7d996d707f1b29df336 3.4.1-beta1
|
||||
b3f74858a1c8720c82d0978f3877a3fc8ba459ec 3.4.1-beta1a
|
||||
b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
|
||||
2b779f233ee6f38c89cb921650c773a96e63da92 DRTVWR-220
|
||||
0b9d95f4bfb6867cbf56eaec51633b0da2f1262d DRTVWR-221
|
||||
e6e553761829dc0270eaaa712b7cb0622535b076 3.4.1-beta3
|
||||
|
|
@ -333,36 +345,31 @@ baf97f06ae17223614c5e31aa42e71d87cff07fe DRTVWR-236
|
|||
b2f21e3442542283a80e7eaebae9f833e5a927b6 DRTVWR-237
|
||||
3f9be82de642d468c5fc272cb9d96b46b5498402 3.4.1-beta12
|
||||
e59ffd3fe0838ae6b09b242a6e9df71761b88f41 3.4.1-release
|
||||
81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186
|
||||
cc953f00956be52cc64c30637bbeec310eea603f DRTVWR-181
|
||||
c04e68e1b0034fd0a20815ae24c77e5f8428e822 DRTVWR-188
|
||||
4b2c52aecb7a75de31dbb12d9f5b9a251d8707be DRTVWR-191
|
||||
78ca0bbf43a92e8914d4cfa87d69a6717ef7d4cf DRTVWR-194
|
||||
248f4acd92a706c79e842bc83d80baa7369c0c2e DRTVWR-203
|
||||
de3be913f68813a9bac7d1c671fef96d1159bcd6 DRTVWR-202
|
||||
34dbbe2b00afe90352d3acf8290eb10ab90d1c8b oz-build-test-tag
|
||||
6ee71714935ffcd159db3d4f5800c1929aac54e1 DRTVWR-205
|
||||
7b22c612fc756e0ea63b10b163e81d107f85dbf8 DRTVWR-206
|
||||
b61afe175b829c149d369524a4e974dfda99facf DRTVWR-219
|
||||
32896d5e920ca9a29256ff3b747c2e99752aa5ae DRTVWR-217
|
||||
704bbae7b182a1f2811a47a054e680522966f54a 3.4.2-beta1
|
||||
288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216
|
||||
e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
|
||||
0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
|
||||
710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
|
||||
e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
|
||||
73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
|
||||
16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
|
||||
d799593b53ed733862e9a13871e318e886469377 DRTVWR-208
|
||||
e497dcde7a3653e384eb223a8a460030e89c294c DRTVWR-223
|
||||
288539fc0408ed4b69a99665de33bbbc2c3c08fe DRTVWR-216
|
||||
e664473c16df1d82ffaff382e7b3e023da202d52 3.4.2-beta2
|
||||
93ab02d83f51e30a3cabad98aff89601befd9413 DRTVWR-240
|
||||
0891d7a773a31397dcad48be3fa66531d567a821 DRTVWR-242
|
||||
710785535362b3cb801b6a3dc4703be3373bd0cd 3.4.2-beta3
|
||||
2aa72e3372a83dece4df9cf72fb1e7c34f90b5e3 DRTVWR-209
|
||||
f7bedce18ad52283e6072814db23318907261487 DRTVWR-238
|
||||
7b64c96fbcadf360bd2feaae19d330166b70877c DRTVWR-210
|
||||
e9a5886052433d5db9e504ffaca10890f9932979 DRTVWR-243
|
||||
73b84b9864dc650fe7c8fc9f52361450f0849004 3.4.2-beta4
|
||||
16310aabccf315870f7cc9bf966926c0ad6954fa 3.4.2-release
|
||||
5e4e4128b256525bafc07a62e35ae8527aaa9c9d DRTVWR-241
|
||||
f1d3b3fcab28ed9ea532bf50db0ba96f5c8cc8e9 DRTVWR-232
|
||||
4918b150e75df6b516fb6c2616d32043fa6b4cac DRTVWR-245
|
||||
94ab2b49458ab372a95d2d6949fdf574f413068d 3.4.3-beta1
|
||||
4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
|
||||
f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
|
||||
39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
|
||||
7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
|
||||
f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
|
||||
b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
|
||||
965b9a35e260c0f53be1a25f0db7abc8a67eaf47 DRTVWR-252
|
||||
bb10adc4f76cf0067fca7075146f00cdc0740e9d DRTVWR-251
|
||||
ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
|
||||
|
|
@ -371,31 +378,25 @@ ab0aa2f6ba22b52fed30a2337197f589156edc75 DRTVWR-253
|
|||
44e764a6ac9e672a4f3bce821a4b6a218590c374 DRTVWR-258
|
||||
c23d734065ed593b2413385aecd8366d8e0ee96b DRTVWR-257
|
||||
452ce96d4046dc05a3ecaecc203e2cc8ddd72e76 DRTVWR-259
|
||||
9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
|
||||
daca610d840625b5bebb966a57cb49581852c417 DRTVWR-265
|
||||
9afbdc4e24cc04feacfb2b7a10b78a64f780901a DRTVWR-266
|
||||
73280db02501f5ad041fc18b1eba68e73a81996c DRTVWR-267
|
||||
870e2d79e0063fda87187f17bbc2747766733194 3.4.3-beta3
|
||||
0a2ca6546b499239afeb66d17b2fadbcdbe36ab1 3.4.3-release
|
||||
4c3460cb1fb7c6da9965e09c734d282a8e9c81f0 DRTVWR-229
|
||||
f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246
|
||||
39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247
|
||||
7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249
|
||||
f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230
|
||||
b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255
|
||||
9aa1aa9f1fe13c194695a0b8f0af298296241dc2 DRTVWR-260
|
||||
84fbaf2d4141bd161731430e760949dc787ca206 DRTVWR-244
|
||||
083d2d36b5bb1c54fc3dd7caac0e7ac381a9cef0 3.4.4-beta1
|
||||
391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
|
||||
b634dec987c16e8c9c938e11e52591d9ead8fa9b DRTVWR-270
|
||||
cd39255bd23330fd30c04105f2811e941d8524fe 3.4.4-beta2
|
||||
2c4011bbc2b15b82198fd8b51f3a9fe765a08c4d DRTVWR-271
|
||||
2f8a3ef687bc55828abcb17ac1ad7cde70536d7e 3.4.4-beta3
|
||||
35cfd4cf5b895fa776592f2e630e330be7f0604e DRTVWR-273
|
||||
a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
|
||||
37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
|
||||
c374035d459af3c03dea2dd90880dfc25de64706 DRTVWR-275
|
||||
05d9f1dd7a954069af2a33abedb7713fa36a04cb 3.4.4-beta4
|
||||
e1bb1ae7d8b12faeb37933a737c199cc9b9f89cc 3.4.4-release
|
||||
391a8c74cec7275c5d26c85ad108d4782a3e3dd9 DRTVWR-268
|
||||
a36f1f354b02aa6e448ca13685de167d0a0a3d03 DRTVWR-272
|
||||
37dba00ad820de3a808d4039396b162a9c275b3e DRTVWR-269
|
||||
7c6dfdc1b7a2ce0d8e3a8f3ce3058547ea065c0f DRTVWR-250
|
||||
b9ff9730daa53a541925300cbd02bb14575a5705 DRTVWR-277
|
||||
af6b711a97073431953b55ee808aaa09900c27e5 DRTVWR-276
|
||||
|
|
@ -405,6 +406,8 @@ c296133849d1f103c0e2abc41e6599daed00b67b DRTVWR-280
|
|||
5df4802bec93c8d0a509946d826bb4c50c5442ec DRTVWR-281
|
||||
7c1c33ba4cfd2d15ca51cc1ac440eca551331a4a DRTVWR-283
|
||||
6b9c7dbebef793230d64e1b452577c8b142d4143 3.4.5-beta2
|
||||
37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282
|
||||
6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284
|
||||
ccf991e02dc2f63fb646324230d54832683f4a9b DRTVWR-286
|
||||
2d849850558a5a0324b398d1c102d30bcbdfb88f DRTVWR-287
|
||||
e06898df8644fe567bee94f817d03abc1c380993 3.4.5-beta3
|
||||
|
|
@ -416,3 +419,6 @@ b23419a2748483c98f3b84b630468a21c88feba5 DRTVWR-292
|
|||
1cce8447f8f574673e3f47d6fe584262e6964fe2 DRTVWR-296
|
||||
0a5d409161ef2a89b28c9a741051dd2dedc707d6 DRTVWR-297
|
||||
852b69ef0b5fe6b13b69cc2217282cc64de6afab 3.4.5-beta5
|
||||
a49c715243a36a8a380504d14cb7416b3039c956 3.4.5-release
|
||||
279ef1dfc9b749a6cc499cf190fec0c090b6d682 DRTVWR-288
|
||||
9b19edaf1d8ddf435f60fbbb444dd25db8f63953 3.5.0-beta1
|
||||
|
|
|
|||
12
BuildParams
12
BuildParams
|
|
@ -132,6 +132,18 @@ viewer-pathfinding.build_debug_release_separately = true
|
|||
viewer-pathfinding.build_CYGWIN_Debug = false
|
||||
viewer-pathfinding.build_viewer_update_version_manager = false
|
||||
|
||||
# ========================================
|
||||
# viewer-chui
|
||||
#
|
||||
# ========================================
|
||||
|
||||
viewer-chui.viewer_channel = "Project Viewer - CHUI"
|
||||
viewer-chui.login_channel = "Project Viewer - CHUI"
|
||||
viewer-chui.viewer_grid = agni
|
||||
viewer-chui.build_debug_release_separately = true
|
||||
viewer-chui.build_CYGWIN_Debug = false
|
||||
viewer-chui.build_viewer_update_version_manager = false
|
||||
|
||||
# =================================================================
|
||||
# asset delivery 2010 projects
|
||||
# =================================================================
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@
|
|||
#include "llvfs.h"
|
||||
#include "lltexlayerparams.h"
|
||||
#include "lltexturemanagerbridge.h"
|
||||
#include "llrender2dutils.h"
|
||||
//#include "llrender2dutils.h"
|
||||
#include "..\llui\llui.h"
|
||||
#include "llwearable.h"
|
||||
#include "llwearabledata.h"
|
||||
#include "llvertexbuffer.h"
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@
|
|||
#include "llquantize.h"
|
||||
#include "lltexlayer.h"
|
||||
#include "lltexturemanagerbridge.h"
|
||||
#include "llrender2dutils.h"
|
||||
//#include "llrender2dutils.h"
|
||||
#include "..\llui\llui.h"
|
||||
#include "llwearable.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -839,6 +839,10 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
|
|||
asp->play(audio_uuid);
|
||||
}
|
||||
|
||||
void LLAudioEngine::triggerSound(SoundData& soundData)
|
||||
{
|
||||
triggerSound(soundData.audio_uuid, soundData.owner_id, soundData.gain, soundData.type, soundData.pos_global);
|
||||
}
|
||||
|
||||
void LLAudioEngine::setListenerPos(LLVector3 aVec)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ class LLAudioChannel;
|
|||
class LLAudioChannelOpenAL;
|
||||
class LLAudioBuffer;
|
||||
class LLStreamingAudioInterface;
|
||||
struct SoundData;
|
||||
|
||||
|
||||
//
|
||||
|
|
@ -144,6 +145,8 @@ public:
|
|||
void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
|
||||
const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
|
||||
const LLVector3d &pos_global = LLVector3d::zero);
|
||||
void triggerSound(SoundData& soundData);
|
||||
|
||||
bool preloadSound(const LLUUID &id);
|
||||
|
||||
void addAudioSource(LLAudioSource *asp);
|
||||
|
|
@ -456,6 +459,27 @@ protected:
|
|||
LLFrameTimer mLastUseTimer;
|
||||
};
|
||||
|
||||
struct SoundData
|
||||
{
|
||||
LLUUID audio_uuid;
|
||||
LLUUID owner_id;
|
||||
F32 gain;
|
||||
S32 type;
|
||||
LLVector3d pos_global;
|
||||
|
||||
SoundData(const LLUUID &audio_uuid,
|
||||
const LLUUID& owner_id,
|
||||
const F32 gain,
|
||||
const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
|
||||
const LLVector3d &pos_global = LLVector3d::zero)
|
||||
{
|
||||
this->audio_uuid = audio_uuid;
|
||||
this->owner_id = owner_id;
|
||||
this->gain = gain;
|
||||
this->type = type;
|
||||
this->pos_global = pos_global;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
extern LLAudioEngine* gAudiop;
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ LLUUID const ANIM_AGENT_BLOW_KISS ("db84829b-462c-ee83-1e27-9bbee66b
|
|||
LLUUID const ANIM_AGENT_BORED ("b906c4ba-703b-1940-32a3-0c7f7d791510");
|
||||
LLUUID const ANIM_AGENT_BOW ("82e99230-c906-1403-4d9c-3889dd98daba");
|
||||
LLUUID const ANIM_AGENT_BRUSH ("349a3801-54f9-bf2c-3bd0-1ac89772af01");
|
||||
LLUUID const ANIM_AGENT_BUSY ("efcf670c-2d18-8128-973a-034ebc806b67");
|
||||
LLUUID const ANIM_AGENT_DO_NOT_DISTURB ("efcf670c-2d18-8128-973a-034ebc806b67");
|
||||
LLUUID const ANIM_AGENT_CLAP ("9b0c1c4e-8ac7-7969-1494-28c874c4f668");
|
||||
LLUUID const ANIM_AGENT_COURTBOW ("9ba1c942-08be-e43a-fb29-16ad440efc50");
|
||||
LLUUID const ANIM_AGENT_CROUCH ("201f3fdf-cb1f-dbec-201f-7333e328ae7c");
|
||||
|
|
@ -211,7 +211,7 @@ LLAnimationLibrary::LLAnimationLibrary() :
|
|||
mAnimMap[ANIM_AGENT_BORED]= mAnimStringTable.addString("express_bored");
|
||||
mAnimMap[ANIM_AGENT_BOW]= mAnimStringTable.addString("bow");
|
||||
mAnimMap[ANIM_AGENT_BRUSH]= mAnimStringTable.addString("brush");
|
||||
mAnimMap[ANIM_AGENT_BUSY]= mAnimStringTable.addString("busy");
|
||||
mAnimMap[ANIM_AGENT_DO_NOT_DISTURB]= mAnimStringTable.addString("busy");
|
||||
mAnimMap[ANIM_AGENT_CLAP]= mAnimStringTable.addString("clap");
|
||||
mAnimMap[ANIM_AGENT_COURTBOW]= mAnimStringTable.addString("courtbow");
|
||||
mAnimMap[ANIM_AGENT_CROUCH]= mAnimStringTable.addString("crouch");
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ extern const LLUUID ANIM_AGENT_BLOW_KISS;
|
|||
extern const LLUUID ANIM_AGENT_BORED;
|
||||
extern const LLUUID ANIM_AGENT_BOW;
|
||||
extern const LLUUID ANIM_AGENT_BRUSH;
|
||||
extern const LLUUID ANIM_AGENT_BUSY;
|
||||
extern const LLUUID ANIM_AGENT_DO_NOT_DISTURB;
|
||||
extern const LLUUID ANIM_AGENT_CLAP;
|
||||
extern const LLUUID ANIM_AGENT_COURTBOW;
|
||||
extern const LLUUID ANIM_AGENT_CROUCH;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
|
|||
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
|
||||
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
|
||||
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
|
||||
addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
|
||||
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ public:
|
|||
AT_WIDGET = 40,
|
||||
// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
|
||||
|
||||
AT_PERSON = 45,
|
||||
// A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
|
||||
|
||||
AT_MESH = 49,
|
||||
// Mesh data in our proprietary SLM format
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "llavatarname.h"
|
||||
|
||||
#include "lldate.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llsd.h"
|
||||
|
||||
// Store these in pre-built std::strings to avoid memory allocations in
|
||||
|
|
@ -42,6 +43,14 @@ static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default");
|
|||
static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
|
||||
static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
|
||||
|
||||
bool LLAvatarName::sUseDisplayNames = true;
|
||||
|
||||
// Minimum time-to-live (in seconds) for a name entry.
|
||||
// Avatar name should always guarantee to expire reasonably soon by default
|
||||
// so if the failure to get a valid expiration time was due to something temporary
|
||||
// we will eventually request and get the right data.
|
||||
const F64 MIN_ENTRY_LIFETIME = 60.0;
|
||||
|
||||
LLAvatarName::LLAvatarName()
|
||||
: mUsername(),
|
||||
mDisplayName(),
|
||||
|
|
@ -61,6 +70,17 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const
|
|||
return mUsername < rhs.mUsername;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLAvatarName::setUseDisplayNames(bool use)
|
||||
{
|
||||
sUseDisplayNames = use;
|
||||
}
|
||||
//static
|
||||
bool LLAvatarName::useDisplayNames()
|
||||
{
|
||||
return sUseDisplayNames;
|
||||
}
|
||||
|
||||
LLSD LLAvatarName::asLLSD() const
|
||||
{
|
||||
LLSD sd;
|
||||
|
|
@ -85,21 +105,75 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
|
|||
mExpires = expires.secondsSinceEpoch();
|
||||
LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE];
|
||||
mNextUpdate = next_update.secondsSinceEpoch();
|
||||
|
||||
// Some avatars don't have explicit display names set. Force a legible display name here.
|
||||
if (mDisplayName.empty())
|
||||
{
|
||||
mDisplayName = mUsername;
|
||||
}
|
||||
}
|
||||
|
||||
// Transform a string (typically provided by the legacy service) into a decent
|
||||
// avatar name instance.
|
||||
void LLAvatarName::fromString(const std::string& full_name)
|
||||
{
|
||||
mDisplayName = full_name;
|
||||
std::string::size_type index = full_name.find(' ');
|
||||
if (index != std::string::npos)
|
||||
{
|
||||
// The name is in 2 parts (first last)
|
||||
mLegacyFirstName = full_name.substr(0, index);
|
||||
mLegacyLastName = full_name.substr(index+1);
|
||||
if (mLegacyLastName != "Resident")
|
||||
{
|
||||
mUsername = mLegacyFirstName + "." + mLegacyLastName;
|
||||
mDisplayName = full_name;
|
||||
LLStringUtil::toLower(mUsername);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Very old names do have a dummy "Resident" last name
|
||||
// that we choose to hide from users.
|
||||
mUsername = mLegacyFirstName;
|
||||
mDisplayName = mLegacyFirstName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mLegacyFirstName = full_name;
|
||||
mLegacyLastName = "";
|
||||
mUsername = full_name;
|
||||
mDisplayName = full_name;
|
||||
}
|
||||
mIsDisplayNameDefault = true;
|
||||
mIsTemporaryName = true;
|
||||
setExpires(MIN_ENTRY_LIFETIME);
|
||||
}
|
||||
|
||||
void LLAvatarName::setExpires(F64 expires)
|
||||
{
|
||||
mExpires = LLFrameTimer::getTotalSeconds() + expires;
|
||||
}
|
||||
|
||||
std::string LLAvatarName::getCompleteName() const
|
||||
{
|
||||
std::string name;
|
||||
if (mUsername.empty() || mIsDisplayNameDefault)
|
||||
// If the display name feature is off
|
||||
// OR this particular display name is defaulted (i.e. based on user name),
|
||||
// then display only the easier to read instance of the person's name.
|
||||
if (sUseDisplayNames)
|
||||
{
|
||||
name = mDisplayName;
|
||||
if (mUsername.empty() || mIsDisplayNameDefault)
|
||||
{
|
||||
// If this particular display name is defaulted (i.e. based on user name),
|
||||
// then display only the easier to read instance of the person's name.
|
||||
name = mDisplayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = mDisplayName + " (" + mUsername + ")";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = mDisplayName + " (" + mUsername + ")";
|
||||
name = getUserName();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
|
@ -118,3 +192,48 @@ std::string LLAvatarName::getLegacyName() const
|
|||
name += mLegacyLastName;
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string LLAvatarName::getDisplayName() const
|
||||
{
|
||||
if (sUseDisplayNames)
|
||||
{
|
||||
return mDisplayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return getUserName();
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLAvatarName::getUserName() const
|
||||
{
|
||||
std::string name;
|
||||
if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
|
||||
{
|
||||
if (mLegacyFirstName.empty())
|
||||
{
|
||||
// If we cannot create a user name from the legacy strings, use the display name
|
||||
name = mDisplayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The last name might be empty if it defaulted to "Resident"
|
||||
name = mLegacyFirstName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
name = mLegacyFirstName + " " + mLegacyLastName;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
void LLAvatarName::dump() const
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarName: "
|
||||
<< "user '" << mUsername << "' "
|
||||
<< "display '" << mDisplayName << "' "
|
||||
<< "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,10 +39,27 @@ public:
|
|||
|
||||
bool operator<(const LLAvatarName& rhs) const;
|
||||
|
||||
// Conversion to and from LLSD (cache file or server response)
|
||||
LLSD asLLSD() const;
|
||||
|
||||
void fromLLSD(const LLSD& sd);
|
||||
|
||||
// Used only in legacy mode when the display name capability is not provided server side
|
||||
// or to otherwise create a temporary valid item.
|
||||
void fromString(const std::string& full_name);
|
||||
|
||||
// Set the name object to become invalid in "expires" seconds from now
|
||||
void setExpires(F64 expires);
|
||||
|
||||
// Set and get the display name flag set by the user in preferences.
|
||||
static void setUseDisplayNames(bool use);
|
||||
static bool useDisplayNames();
|
||||
|
||||
// A name object is valid if not temporary and not yet expired (default is expiration not checked)
|
||||
bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
|
||||
|
||||
// Return true if the name is made up from legacy or temporary data
|
||||
bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
|
||||
|
||||
// For normal names, returns "James Linden (james.linden)"
|
||||
// When display names are disabled returns just "James Linden"
|
||||
std::string getCompleteName() const;
|
||||
|
|
@ -51,11 +68,38 @@ public:
|
|||
// compatibility with systems like voice and muting
|
||||
// *TODO: Eliminate this in favor of username only
|
||||
std::string getLegacyName() const;
|
||||
|
||||
// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
|
||||
// Takes the display name preference into account. This is truly the name that should
|
||||
// be used for all UI where an avatar name has to be used unless we truly want something else (rare)
|
||||
std::string getDisplayName() const;
|
||||
|
||||
// Returns "James Linden" or "bobsmith123 Resident"
|
||||
// Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
|
||||
// Also used for backwards compatibility with systems like voice and muting
|
||||
std::string getUserName() const;
|
||||
|
||||
// Returns "james.linden" or the legacy name for very old names
|
||||
std::string getAccountName() const { return mUsername; }
|
||||
|
||||
// Debug print of the object
|
||||
void dump() const;
|
||||
|
||||
// Names can change, so need to keep track of when name was
|
||||
// last checked.
|
||||
// Unix time-from-epoch seconds for efficiency
|
||||
F64 mExpires;
|
||||
|
||||
// You can only change your name every N hours, so record
|
||||
// when the next update is allowed
|
||||
// Unix time-from-epoch seconds
|
||||
F64 mNextUpdate;
|
||||
|
||||
private:
|
||||
// "bobsmith123" or "james.linden", US-ASCII only
|
||||
std::string mUsername;
|
||||
|
||||
// "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode
|
||||
// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
|
||||
// Contains data whether or not user has explicitly set
|
||||
// a display name; may duplicate their username.
|
||||
std::string mDisplayName;
|
||||
|
|
@ -81,15 +125,9 @@ public:
|
|||
// shown in UI, but are not serialized.
|
||||
bool mIsTemporaryName;
|
||||
|
||||
// Names can change, so need to keep track of when name was
|
||||
// last checked.
|
||||
// Unix time-from-epoch seconds for efficiency
|
||||
F64 mExpires;
|
||||
|
||||
// You can only change your name every N hours, so record
|
||||
// when the next update is allowed
|
||||
// Unix time-from-epoch seconds
|
||||
F64 mNextUpdate;
|
||||
// Global flag indicating if display name should be used or not
|
||||
// This will affect the output of the high level "get" methods
|
||||
static bool sUseDisplayNames;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -194,13 +194,6 @@ public:
|
|||
return mHandle;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef LLHandle<T> handle_type_t;
|
||||
LLHandleProvider()
|
||||
{
|
||||
// provided here to enforce T deriving from LLHandleProvider<T>
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
|
||||
{
|
||||
|
|
@ -209,6 +202,12 @@ protected:
|
|||
return downcast_handle;
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef LLHandle<T> handle_type_t;
|
||||
LLHandleProvider()
|
||||
{
|
||||
// provided here to enforce T deriving from LLHandleProvider<T>
|
||||
}
|
||||
|
||||
private:
|
||||
mutable LLRootHandle<T> mHandle;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ namespace LLInitParam
|
|||
{
|
||||
const U8* my_addr = reinterpret_cast<const U8*>(this);
|
||||
const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
|
||||
mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
|
||||
U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
|
||||
mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
|
||||
mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -112,6 +114,35 @@ namespace LLInitParam
|
|||
std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
|
||||
}
|
||||
|
||||
void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name)
|
||||
{
|
||||
// create a copy of the param descriptor in mAllParams
|
||||
// so other data structures can store a pointer to it
|
||||
mAllParams.push_back(in_param);
|
||||
ParamDescriptorPtr param(mAllParams.back());
|
||||
|
||||
std::string name(char_name);
|
||||
if ((size_t)param->mParamHandle > mMaxParamOffset)
|
||||
{
|
||||
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
|
||||
}
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
mUnnamedParams.push_back(param);
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't use insert, since we want to overwrite existing entries
|
||||
mNamedParams[name] = param;
|
||||
}
|
||||
|
||||
if (param->mValidationFunc)
|
||||
{
|
||||
mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
|
||||
}
|
||||
}
|
||||
|
||||
BlockDescriptor::BlockDescriptor()
|
||||
: mMaxParamOffset(0),
|
||||
mInitializationState(UNINITIALIZED),
|
||||
|
|
@ -150,7 +181,8 @@ namespace LLInitParam
|
|||
|
||||
bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
|
||||
{
|
||||
if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
|
||||
Parser::name_stack_range_t range = std::make_pair(name_stack.begin(), name_stack.end());
|
||||
if (!deserializeBlock(p, range, true))
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
|
|
@ -196,12 +228,7 @@ namespace LLInitParam
|
|||
if (serialize_func)
|
||||
{
|
||||
const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
|
||||
// each param descriptor remembers its serial number
|
||||
// so we can inspect the same param under different names
|
||||
// and see that it has the same number
|
||||
name_stack.push_back(std::make_pair("", true));
|
||||
serialize_func(*param, parser, name_stack, diff_param);
|
||||
name_stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +322,7 @@ namespace LLInitParam
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
|
||||
bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool ignored)
|
||||
{
|
||||
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
|
||||
bool names_left = name_stack_range.first != name_stack_range.second;
|
||||
|
|
@ -308,15 +335,12 @@ namespace LLInitParam
|
|||
{
|
||||
const std::string& top_name = name_stack_range.first->first;
|
||||
|
||||
ParamDescriptor::deserialize_func_t deserialize_func = NULL;
|
||||
Param* paramp = NULL;
|
||||
|
||||
BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
|
||||
if (found_it != block_data.mNamedParams.end())
|
||||
{
|
||||
// find pointer to member parameter from offset table
|
||||
paramp = getParamFromHandle(found_it->second->mParamHandle);
|
||||
deserialize_func = found_it->second->mDeserializeFunc;
|
||||
Param* paramp = getParamFromHandle(found_it->second->mParamHandle);
|
||||
ParamDescriptor::deserialize_func_t deserialize_func = found_it->second->mDeserializeFunc;
|
||||
|
||||
Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
|
||||
++new_name_stack.first;
|
||||
|
|
@ -358,36 +382,6 @@ namespace LLInitParam
|
|||
return false;
|
||||
}
|
||||
|
||||
//static
|
||||
void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
|
||||
{
|
||||
// create a copy of the param descriptor in mAllParams
|
||||
// so other data structures can store a pointer to it
|
||||
block_data.mAllParams.push_back(in_param);
|
||||
ParamDescriptorPtr param(block_data.mAllParams.back());
|
||||
|
||||
std::string name(char_name);
|
||||
if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
|
||||
{
|
||||
llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
|
||||
}
|
||||
|
||||
if (name.empty())
|
||||
{
|
||||
block_data.mUnnamedParams.push_back(param);
|
||||
}
|
||||
else
|
||||
{
|
||||
// don't use insert, since we want to overwrite existing entries
|
||||
block_data.mNamedParams[name] = param;
|
||||
}
|
||||
|
||||
if (param->mValidationFunc)
|
||||
{
|
||||
block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
|
||||
}
|
||||
}
|
||||
|
||||
void BaseBlock::addSynonym(Param& param, const std::string& synonym)
|
||||
{
|
||||
BlockDescriptor& block_data = mostDerivedBlockDescriptor();
|
||||
|
|
@ -460,7 +454,7 @@ namespace LLInitParam
|
|||
if (merge_func)
|
||||
{
|
||||
Param* paramp = getParamFromHandle((*it)->mParamHandle);
|
||||
llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
|
||||
llassert(paramp->getEnclosingBlockOffset() == (*it)->mParamHandle);
|
||||
some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -43,7 +43,7 @@
|
|||
* semantics: one instance per process, rather than one instance per module as
|
||||
* sometimes happens with data simply declared static.
|
||||
*/
|
||||
class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
|
||||
class LL_COMMON_API LLInstanceTrackerBase
|
||||
{
|
||||
protected:
|
||||
/// Get a process-unique void* pointer slot for the specified type_info
|
||||
|
|
@ -210,6 +210,9 @@ protected:
|
|||
virtual const KEY& getKey() const { return mInstanceKey; }
|
||||
|
||||
private:
|
||||
LLInstanceTracker( const LLInstanceTracker& );
|
||||
const LLInstanceTracker& operator=( const LLInstanceTracker& );
|
||||
|
||||
void add_(KEY key)
|
||||
{
|
||||
mInstanceKey = key;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#define LLREFCOUNT_H
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
|
||||
#define LL_REF_COUNT_DEBUG 0
|
||||
#if LL_REF_COUNT_DEBUG
|
||||
|
|
@ -86,4 +87,22 @@ private:
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* intrusive pointer support
|
||||
* this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
|
||||
*/
|
||||
namespace boost
|
||||
{
|
||||
inline void intrusive_ptr_add_ref(LLRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -307,6 +307,10 @@ public:
|
|||
virtual ~StaticRegistrar() {}
|
||||
StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
|
||||
{
|
||||
if (singleton_t::instance().exists(key))
|
||||
{
|
||||
llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl;
|
||||
}
|
||||
singleton_t::instance().mStaticScope->add(key, value);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -223,10 +223,14 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
|
|||
{
|
||||
bool new_traversal = it->second;
|
||||
|
||||
LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
|
||||
|
||||
if (child_sd->isArray())
|
||||
LLSD* child_sd;
|
||||
if (it->first.empty())
|
||||
{
|
||||
child_sd = sd_to_write;
|
||||
if (child_sd->isUndefined())
|
||||
{
|
||||
*child_sd = LLSD::emptyArray();
|
||||
}
|
||||
if (new_traversal)
|
||||
{
|
||||
// write to new element at end
|
||||
|
|
@ -240,22 +244,7 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
|
|||
}
|
||||
else
|
||||
{
|
||||
if (new_traversal
|
||||
&& child_sd->isDefined()
|
||||
&& !child_sd->isArray())
|
||||
{
|
||||
// copy child contents into first element of an array
|
||||
LLSD new_array = LLSD::emptyArray();
|
||||
new_array.append(*child_sd);
|
||||
// assign array to slot that previously held the single value
|
||||
*child_sd = new_array;
|
||||
// return next element in that array
|
||||
sd_to_write = &((*child_sd)[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sd_to_write = child_sd;
|
||||
}
|
||||
sd_to_write = &(*sd_to_write)[it->first];
|
||||
}
|
||||
it->second = false;
|
||||
}
|
||||
|
|
@ -283,8 +272,9 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
|
|||
it != sd.endArray();
|
||||
++it)
|
||||
{
|
||||
stack.back().second = true;
|
||||
stack.push_back(make_pair(std::string(), true));
|
||||
readSDValues(cb, *it, stack);
|
||||
stack.pop_back();
|
||||
}
|
||||
}
|
||||
else if (sd.isUndefined())
|
||||
|
|
@ -313,8 +303,14 @@ namespace LLInitParam
|
|||
{
|
||||
// LLSD specialization
|
||||
// block param interface
|
||||
bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
|
||||
bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name)
|
||||
{
|
||||
if (name_stack.first == name_stack.second
|
||||
&& p.readValue<LLSD>(mValue))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
|
||||
|
||||
LLSD::String string;
|
||||
|
|
@ -328,15 +324,18 @@ namespace LLInitParam
|
|||
}
|
||||
|
||||
//static
|
||||
void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
|
||||
void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
|
||||
{
|
||||
p.writeValue<LLSD::String>(sd.asString(), name_stack);
|
||||
}
|
||||
|
||||
void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
|
||||
void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
|
||||
{
|
||||
// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
|
||||
Parser::name_stack_t stack;
|
||||
LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
|
||||
// attempt to write LLSD out directly
|
||||
if (!p.writeValue<LLSD>(mValue, name_stack))
|
||||
{
|
||||
// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
|
||||
LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "llapp.h"
|
||||
#include "llapr.h"
|
||||
#include "apr_thread_cond.h"
|
||||
#include "boost/intrusive_ptr.hpp"
|
||||
|
||||
class LLThread;
|
||||
class LLMutex;
|
||||
|
|
@ -284,6 +285,22 @@ private:
|
|||
S32 mRef;
|
||||
};
|
||||
|
||||
/**
|
||||
* intrusive pointer support for LLThreadSafeRefCount
|
||||
* this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
|
||||
*/
|
||||
namespace boost
|
||||
{
|
||||
inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->ref();
|
||||
}
|
||||
|
||||
inline void intrusive_ptr_release(LLThreadSafeRefCount* p)
|
||||
{
|
||||
p->unref();
|
||||
}
|
||||
};
|
||||
//============================================================================
|
||||
|
||||
// Simple responder for self destructing callbacks
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
#define LL_LLVERSIONVIEWER_H
|
||||
|
||||
const S32 LL_VERSION_MAJOR = 3;
|
||||
const S32 LL_VERSION_MINOR = 4;
|
||||
const S32 LL_VERSION_PATCH = 5;
|
||||
const S32 LL_VERSION_MINOR = 5;
|
||||
const S32 LL_VERSION_PATCH = 0;
|
||||
const S32 LL_VERSION_BUILD = 264760;
|
||||
|
||||
const char * const LL_CHANNEL = "Second Life Developer";
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ enum EDragAndDropType
|
|||
DAD_LINK = 14,
|
||||
DAD_MESH = 15,
|
||||
DAD_WIDGET = 16,
|
||||
DAD_COUNT = 17, // number of types in this enum
|
||||
DAD_PERSON = 17,
|
||||
DAD_COUNT = 18, // number of types in this enum
|
||||
};
|
||||
|
||||
// Reasons for drags to be denied.
|
||||
|
|
|
|||
|
|
@ -580,8 +580,13 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
|
|||
const size_t body_size(op->mReqBody->size());
|
||||
if (body_size <= op->mCurlBodyPos)
|
||||
{
|
||||
LL_WARNS("HttpCore") << "Request body position beyond body size. Aborting request."
|
||||
<< LL_ENDL;
|
||||
if (body_size < op->mCurlBodyPos)
|
||||
{
|
||||
// Warn but continue if the read position moves beyond end-of-body
|
||||
// for some reason.
|
||||
LL_WARNS("HttpCore") << "Request body position beyond body size. Truncating request body."
|
||||
<< LL_ENDL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,13 +75,15 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
|
|||
mUUID(uuid),
|
||||
mParentUUID(parent_uuid),
|
||||
mType(type),
|
||||
mName(name)
|
||||
mName(name),
|
||||
mCreationDate(0)
|
||||
{
|
||||
correctInventoryName(mName);
|
||||
}
|
||||
|
||||
LLInventoryObject::LLInventoryObject() :
|
||||
mType(LLAssetType::AT_NONE)
|
||||
mType(LLAssetType::AT_NONE),
|
||||
mCreationDate(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -275,6 +277,18 @@ void LLInventoryObject::correctInventoryName(std::string& name)
|
|||
LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN);
|
||||
}
|
||||
|
||||
time_t LLInventoryObject::getCreationDate() const
|
||||
{
|
||||
return mCreationDate;
|
||||
}
|
||||
|
||||
void LLInventoryObject::setCreationDate(time_t creation_date_utc)
|
||||
{
|
||||
mCreationDate = creation_date_utc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLInventoryItem
|
||||
|
|
@ -297,9 +311,10 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid,
|
|||
mDescription(desc),
|
||||
mSaleInfo(sale_info),
|
||||
mInventoryType(inv_type),
|
||||
mFlags(flags),
|
||||
mCreationDate(creation_date_utc)
|
||||
mFlags(flags)
|
||||
{
|
||||
mCreationDate = creation_date_utc;
|
||||
|
||||
LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
|
||||
LLStringUtil::replaceChar(mDescription, '|', ' ');
|
||||
mPermissions.initMasks(inv_type);
|
||||
|
|
@ -312,9 +327,9 @@ LLInventoryItem::LLInventoryItem() :
|
|||
mDescription(),
|
||||
mSaleInfo(),
|
||||
mInventoryType(LLInventoryType::IT_NONE),
|
||||
mFlags(0),
|
||||
mCreationDate(0)
|
||||
mFlags(0)
|
||||
{
|
||||
mCreationDate = 0;
|
||||
}
|
||||
|
||||
LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) :
|
||||
|
|
@ -384,11 +399,6 @@ const std::string& LLInventoryItem::getActualDescription() const
|
|||
return mDescription;
|
||||
}
|
||||
|
||||
time_t LLInventoryItem::getCreationDate() const
|
||||
{
|
||||
return mCreationDate;
|
||||
}
|
||||
|
||||
U32 LLInventoryItem::getCRC32() const
|
||||
{
|
||||
// *FIX: Not a real crc - more of a checksum.
|
||||
|
|
@ -445,11 +455,6 @@ void LLInventoryItem::setFlags(U32 flags)
|
|||
mFlags = flags;
|
||||
}
|
||||
|
||||
void LLInventoryItem::setCreationDate(time_t creation_date_utc)
|
||||
{
|
||||
mCreationDate = creation_date_utc;
|
||||
}
|
||||
|
||||
// Currently only used in the Viewer to handle calling cards
|
||||
// where the creator is actually used to store the target.
|
||||
void LLInventoryItem::setCreator(const LLUUID& creator)
|
||||
|
|
@ -511,6 +516,12 @@ U32 LLInventoryItem::getFlags() const
|
|||
return mFlags;
|
||||
}
|
||||
|
||||
time_t LLInventoryItem::getCreationDate() const
|
||||
{
|
||||
return mCreationDate;
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void LLInventoryItem::packMessage(LLMessageSystem* msg) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ public:
|
|||
virtual LLAssetType::EType getType() const;
|
||||
LLAssetType::EType getActualType() const; // bypasses indirection for linked items
|
||||
BOOL getIsLinkType() const;
|
||||
virtual time_t getCreationDate() const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Mutators
|
||||
|
|
@ -83,6 +84,7 @@ public:
|
|||
virtual void rename(const std::string& new_name);
|
||||
void setParent(const LLUUID& new_parent);
|
||||
void setType(LLAssetType::EType type);
|
||||
virtual void setCreationDate(time_t creation_date_utc); // only stored for items
|
||||
|
||||
private:
|
||||
// in place correction for inventory name string
|
||||
|
|
@ -111,6 +113,7 @@ protected:
|
|||
LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL.
|
||||
LLAssetType::EType mType;
|
||||
std::string mName;
|
||||
time_t mCreationDate; // seconds from 1/1/1970, UTC
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
@ -176,7 +179,6 @@ public:
|
|||
void setPermissions(const LLPermissions& perm);
|
||||
void setInventoryType(LLInventoryType::EType inv_type);
|
||||
void setFlags(U32 flags);
|
||||
void setCreationDate(time_t creation_date_utc);
|
||||
void setCreator(const LLUUID& creator); // only used for calling cards
|
||||
|
||||
// Check for changes in permissions masks and sale info
|
||||
|
|
@ -222,7 +224,6 @@ protected:
|
|||
LLSaleInfo mSaleInfo;
|
||||
LLInventoryType::EType mInventoryType;
|
||||
U32 mFlags;
|
||||
time_t mCreationDate; // seconds from 1/1/1970, UTC
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
|
|||
addEntry(LLInventoryType::IT_GESTURE, new InventoryEntry("gesture", "gesture", 1, LLAssetType::AT_GESTURE));
|
||||
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
|
||||
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
|
||||
addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -140,7 +141,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
|
|||
LLInventoryType::IT_NONE, // 42 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 43 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 44 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 45 AT_NONE
|
||||
LLInventoryType::IT_PERSON, // 45 AT_PERSON
|
||||
LLInventoryType::IT_NONE, // 46 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 47 AT_NONE
|
||||
LLInventoryType::IT_NONE, // 48 AT_NONE
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@ public:
|
|||
IT_GESTURE = 20,
|
||||
IT_MESH = 22,
|
||||
IT_WIDGET = 23,
|
||||
IT_COUNT = 24,
|
||||
IT_PERSON = 24,
|
||||
IT_COUNT = 25,
|
||||
|
||||
IT_NONE = -1
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,26 +43,26 @@ namespace LLAvatarNameCache
|
|||
{
|
||||
use_display_name_signal_t mUseDisplayNamesSignal;
|
||||
|
||||
// Manual override for display names - can disable even if the region
|
||||
// supports it.
|
||||
bool sUseDisplayNames = true;
|
||||
|
||||
// Cache starts in a paused state until we can determine if the
|
||||
// current region supports display names.
|
||||
bool sRunning = false;
|
||||
|
||||
// Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
|
||||
// For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
|
||||
bool sUsePeopleAPI = true;
|
||||
|
||||
// Base lookup URL for name service.
|
||||
// On simulator, loaded from indra.xml
|
||||
// On viewer, usually a simulator capability (at People API team's request)
|
||||
// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
|
||||
std::string sNameLookupURL;
|
||||
|
||||
// accumulated agent IDs for next query against service
|
||||
// Accumulated agent IDs for next query against service
|
||||
typedef std::set<LLUUID> ask_queue_t;
|
||||
ask_queue_t sAskQueue;
|
||||
|
||||
// agent IDs that have been requested, but with no reply
|
||||
// maps agent ID to frame time request was made
|
||||
// Agent IDs that have been requested, but with no reply.
|
||||
// Maps agent ID to frame time request was made.
|
||||
typedef std::map<LLUUID, F64> pending_queue_t;
|
||||
pending_queue_t sPendingQueue;
|
||||
|
||||
|
|
@ -73,21 +73,21 @@ namespace LLAvatarNameCache
|
|||
typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
|
||||
signal_map_t sSignalMap;
|
||||
|
||||
// names we know about
|
||||
// The cache at last, i.e. avatar names we know about.
|
||||
typedef std::map<LLUUID, LLAvatarName> cache_t;
|
||||
cache_t sCache;
|
||||
|
||||
// Send bulk lookup requests a few times a second at most
|
||||
// only need per-frame timing resolution
|
||||
// Send bulk lookup requests a few times a second at most.
|
||||
// Only need per-frame timing resolution.
|
||||
LLFrameTimer sRequestTimer;
|
||||
|
||||
/// Maximum time an unrefreshed cache entry is allowed
|
||||
// Maximum time an unrefreshed cache entry is allowed.
|
||||
const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
|
||||
|
||||
/// Time when unrefreshed cached names were checked last
|
||||
// Time when unrefreshed cached names were checked last.
|
||||
static F64 sLastExpireCheck;
|
||||
|
||||
/// Time-to-live for a temp cache entry.
|
||||
// Time-to-live for a temp cache entry.
|
||||
const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
|
@ -95,26 +95,21 @@ namespace LLAvatarNameCache
|
|||
//-----------------------------------------------------------------------
|
||||
|
||||
// Handle name response off network.
|
||||
// Optionally skip adding to cache, used when this is a fallback to the
|
||||
// legacy name system.
|
||||
void processName(const LLUUID& agent_id,
|
||||
const LLAvatarName& av_name,
|
||||
bool add_to_cache);
|
||||
const LLAvatarName& av_name);
|
||||
|
||||
void requestNamesViaCapability();
|
||||
|
||||
// Legacy name system callback
|
||||
// Legacy name system callbacks
|
||||
void legacyNameCallback(const LLUUID& agent_id,
|
||||
const std::string& full_name,
|
||||
bool is_group
|
||||
);
|
||||
|
||||
bool is_group);
|
||||
void legacyNameFetch(const LLUUID& agent_id,
|
||||
const std::string& full_name,
|
||||
bool is_group);
|
||||
|
||||
void requestNamesViaLegacy();
|
||||
|
||||
// Fill in an LLAvatarName with the legacy name data
|
||||
void buildLegacyName(const std::string& full_name,
|
||||
LLAvatarName* av_name);
|
||||
|
||||
// Do a single callback to a given slot
|
||||
void fireSignal(const LLUUID& agent_id,
|
||||
const callback_slot_t& slot,
|
||||
|
|
@ -209,20 +204,11 @@ public:
|
|||
// Use expiration time from header
|
||||
av_name.mExpires = expires;
|
||||
|
||||
// Some avatars don't have explicit display names set
|
||||
if (av_name.mDisplayName.empty())
|
||||
{
|
||||
av_name.mDisplayName = av_name.mUsername;
|
||||
}
|
||||
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " "
|
||||
<< "user '" << av_name.mUsername << "' "
|
||||
<< "display '" << av_name.mDisplayName << "' "
|
||||
<< "expires in " << expires - now << " seconds"
|
||||
<< LL_ENDL;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
|
||||
av_name.dump();
|
||||
|
||||
// cache it and fire signals
|
||||
LLAvatarNameCache::processName(agent_id, av_name, true);
|
||||
LLAvatarNameCache::processName(agent_id, av_name);
|
||||
}
|
||||
|
||||
// Same logic as error response case
|
||||
|
|
@ -279,40 +265,34 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
|
|||
LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
|
||||
<< agent_id << LL_ENDL;
|
||||
gCacheName->get(agent_id, false, // legacy compatibility
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback,
|
||||
_1, _2, _3));
|
||||
boost::bind(&LLAvatarNameCache::legacyNameFetch, _1, _2, _3));
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have a chached (but probably expired) entry - since that would have
|
||||
// we have a cached (but probably expired) entry - since that would have
|
||||
// been returned by the get method, there is no need to signal anyone
|
||||
|
||||
// Clear this agent from the pending list
|
||||
LLAvatarNameCache::sPendingQueue.erase(agent_id);
|
||||
|
||||
LLAvatarName& av_name = existing->second;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
|
||||
<< agent_id
|
||||
<< "user '" << av_name.mUsername << "' "
|
||||
<< "display '" << av_name.mDisplayName << "' "
|
||||
<< "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
|
||||
<< LL_ENDL;
|
||||
av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
|
||||
av_name.dump();
|
||||
|
||||
// Reset expiry time so we don't constantly rerequest.
|
||||
av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::processName(const LLUUID& agent_id,
|
||||
const LLAvatarName& av_name,
|
||||
bool add_to_cache)
|
||||
void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name)
|
||||
{
|
||||
if (add_to_cache)
|
||||
{
|
||||
sCache[agent_id] = av_name;
|
||||
}
|
||||
// Add to the cache
|
||||
sCache[agent_id] = av_name;
|
||||
|
||||
// Suppress request from the queue
|
||||
sPendingQueue.erase(agent_id);
|
||||
|
||||
// signal everyone waiting on this name
|
||||
// Signal everyone waiting on this name
|
||||
signal_map_t::iterator sig_it = sSignalMap.find(agent_id);
|
||||
if (sig_it != sSignalMap.end())
|
||||
{
|
||||
|
|
@ -389,22 +369,33 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
|
|||
const std::string& full_name,
|
||||
bool is_group)
|
||||
{
|
||||
// Construct a dummy record for this name. By convention, SLID is blank
|
||||
// Never expires, but not written to disk, so lasts until end of session.
|
||||
LLAvatarName av_name;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
|
||||
<< "agent " << agent_id << " "
|
||||
<< "full name '" << full_name << "'"
|
||||
<< ( is_group ? " [group]" : "" )
|
||||
<< LL_ENDL;
|
||||
buildLegacyName(full_name, &av_name);
|
||||
// Put the received data in the cache
|
||||
legacyNameFetch(agent_id, full_name, is_group);
|
||||
|
||||
// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
|
||||
// protocol, we do not get an expiration date for each name and there's no reason to ask the
|
||||
// data again and again so we set the expiration time to the largest value admissible.
|
||||
std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id);
|
||||
LLAvatarName& av_name = av_record->second;
|
||||
av_name.setExpires(MAX_UNREFRESHED_TIME);
|
||||
}
|
||||
|
||||
// Add to cache, because if we don't we'll keep rerequesting the
|
||||
// same record forever. buildLegacyName should always guarantee
|
||||
// that these records expire reasonably soon
|
||||
// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
|
||||
// to something temporary we will eventually request and get the right data.
|
||||
processName(agent_id, av_name, true);
|
||||
void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,
|
||||
const std::string& full_name,
|
||||
bool is_group)
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameFetch "
|
||||
<< "agent " << agent_id << " "
|
||||
<< "full name '" << full_name << "'"
|
||||
<< ( is_group ? " [group]" : "" )
|
||||
<< LL_ENDL;
|
||||
|
||||
// Construct an av_name record from this name.
|
||||
LLAvatarName av_name;
|
||||
av_name.fromString(full_name);
|
||||
|
||||
// Add to cache: we're still using the new cache even if we're using the old (legacy) protocol.
|
||||
processName(agent_id, av_name);
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::requestNamesViaLegacy()
|
||||
|
|
@ -426,18 +417,19 @@ void LLAvatarNameCache::requestNamesViaLegacy()
|
|||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
|
||||
|
||||
gCacheName->get(agent_id, false, // legacy compatibility
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback,
|
||||
_1, _2, _3));
|
||||
boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3));
|
||||
}
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::initClass(bool running)
|
||||
void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
|
||||
{
|
||||
sRunning = running;
|
||||
sUsePeopleAPI = usePeopleAPI;
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::cleanupClass()
|
||||
{
|
||||
sCache.clear();
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::importFile(std::istream& istr)
|
||||
|
|
@ -478,7 +470,7 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
|
|||
const LLUUID& agent_id = it->first;
|
||||
const LLAvatarName& av_name = it->second;
|
||||
// Do not write temporary or expired entries to the stored cache
|
||||
if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)
|
||||
if (av_name.isValidName(max_unrefreshed))
|
||||
{
|
||||
// key must be a string
|
||||
agents[agent_id.asString()] = av_name.asLLSD();
|
||||
|
|
@ -499,6 +491,11 @@ bool LLAvatarNameCache::hasNameLookupURL()
|
|||
return !sNameLookupURL.empty();
|
||||
}
|
||||
|
||||
bool LLAvatarNameCache::usePeopleAPI()
|
||||
{
|
||||
return hasNameLookupURL() && sUsePeopleAPI;
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::idle()
|
||||
{
|
||||
// By convention, start running at first idle() call
|
||||
|
|
@ -515,13 +512,12 @@ void LLAvatarNameCache::idle()
|
|||
|
||||
if (!sAskQueue.empty())
|
||||
{
|
||||
if (useDisplayNames())
|
||||
if (usePeopleAPI())
|
||||
{
|
||||
requestNamesViaCapability();
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...fall back to legacy name cache system
|
||||
requestNamesViaLegacy();
|
||||
}
|
||||
}
|
||||
|
|
@ -566,7 +562,7 @@ void LLAvatarNameCache::eraseUnrefreshed()
|
|||
if (av_name.mExpires < max_unrefreshed)
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << it->first
|
||||
<< " user '" << av_name.mUsername << "' "
|
||||
<< " user '" << av_name.getAccountName() << "' "
|
||||
<< "expired " << now - av_name.mExpires << " secs ago"
|
||||
<< LL_ENDL;
|
||||
sCache.erase(it++);
|
||||
|
|
@ -580,20 +576,6 @@ void LLAvatarNameCache::eraseUnrefreshed()
|
|||
}
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
|
||||
LLAvatarName* av_name)
|
||||
{
|
||||
llassert(av_name);
|
||||
av_name->mUsername = "";
|
||||
av_name->mDisplayName = full_name;
|
||||
av_name->mIsDisplayNameDefault = true;
|
||||
av_name->mIsTemporaryName = true;
|
||||
av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
|
||||
<< full_name
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
// fills in av_name if it has it in the cache, even if expired (can check expiry time)
|
||||
// returns bool specifying if av_name was filled, false otherwise
|
||||
bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
|
||||
|
|
@ -601,38 +583,24 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
|
|||
if (sRunning)
|
||||
{
|
||||
// ...only do immediate lookups when cache is running
|
||||
if (useDisplayNames())
|
||||
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
|
||||
if (it != sCache.end())
|
||||
{
|
||||
// ...use display names cache
|
||||
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
|
||||
if (it != sCache.end())
|
||||
{
|
||||
*av_name = it->second;
|
||||
*av_name = it->second;
|
||||
|
||||
// re-request name if entry is expired
|
||||
if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
|
||||
{
|
||||
if (!isRequestPending(agent_id))
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
|
||||
<< "refresh agent " << agent_id
|
||||
<< LL_ENDL;
|
||||
sAskQueue.insert(agent_id);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...use legacy names cache
|
||||
std::string full_name;
|
||||
if (gCacheName->getFullName(agent_id, full_name))
|
||||
// re-request name if entry is expired
|
||||
if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
|
||||
{
|
||||
buildLegacyName(full_name, av_name);
|
||||
return true;
|
||||
if (!isRequestPending(agent_id))
|
||||
{
|
||||
LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
|
||||
<< "refresh agent " << agent_id
|
||||
<< LL_ENDL;
|
||||
sAskQueue.insert(agent_id);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -663,30 +631,14 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
|
|||
if (sRunning)
|
||||
{
|
||||
// ...only do immediate lookups when cache is running
|
||||
if (useDisplayNames())
|
||||
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
|
||||
if (it != sCache.end())
|
||||
{
|
||||
// ...use new cache
|
||||
std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
|
||||
if (it != sCache.end())
|
||||
const LLAvatarName& av_name = it->second;
|
||||
|
||||
if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
|
||||
{
|
||||
const LLAvatarName& av_name = it->second;
|
||||
|
||||
if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
|
||||
{
|
||||
// ...name already exists in cache, fire callback now
|
||||
fireSignal(agent_id, slot, av_name);
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ...use old name system
|
||||
std::string full_name;
|
||||
if (gCacheName->getFullName(agent_id, full_name))
|
||||
{
|
||||
LLAvatarName av_name;
|
||||
buildLegacyName(full_name, &av_name);
|
||||
// ...name already exists in cache, fire callback now
|
||||
fireSignal(agent_id, slot, av_name);
|
||||
return connection;
|
||||
}
|
||||
|
|
@ -721,22 +673,13 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
|
|||
|
||||
void LLAvatarNameCache::setUseDisplayNames(bool use)
|
||||
{
|
||||
if (use != sUseDisplayNames)
|
||||
if (use != LLAvatarName::useDisplayNames())
|
||||
{
|
||||
sUseDisplayNames = use;
|
||||
// flush our cache
|
||||
sCache.clear();
|
||||
|
||||
LLAvatarName::setUseDisplayNames(use);
|
||||
mUseDisplayNamesSignal();
|
||||
}
|
||||
}
|
||||
|
||||
bool LLAvatarNameCache::useDisplayNames()
|
||||
{
|
||||
// Must be both manually set on and able to look up names.
|
||||
return sUseDisplayNames && !sNameLookupURL.empty();
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::erase(const LLUUID& agent_id)
|
||||
{
|
||||
sCache.erase(agent_id);
|
||||
|
|
|
|||
|
|
@ -37,33 +37,33 @@ class LLUUID;
|
|||
|
||||
namespace LLAvatarNameCache
|
||||
{
|
||||
|
||||
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
|
||||
|
||||
// Until the cache is set running, immediate lookups will fail and
|
||||
// async lookups will be queued. This allows us to block requests
|
||||
// until we know if the first region supports display names.
|
||||
void initClass(bool running);
|
||||
void initClass(bool running, bool usePeopleAPI);
|
||||
void cleanupClass();
|
||||
|
||||
// Import/export the name cache to file.
|
||||
void importFile(std::istream& istr);
|
||||
void exportFile(std::ostream& ostr);
|
||||
|
||||
// On the viewer, usually a simulator capabilitity
|
||||
// If empty, name cache will fall back to using legacy name
|
||||
// lookup system
|
||||
// On the viewer, usually a simulator capabilitity.
|
||||
// If empty, name cache will fall back to using legacy name lookup system.
|
||||
void setNameLookupURL(const std::string& name_lookup_url);
|
||||
|
||||
// Do we have a valid lookup URL, hence are we trying to use the
|
||||
// new display name lookup system?
|
||||
// Do we have a valid lookup URL, i.e. are we trying to use the
|
||||
// more recent display name lookup system?
|
||||
bool hasNameLookupURL();
|
||||
bool usePeopleAPI();
|
||||
|
||||
// Periodically makes a batch request for display names not already in
|
||||
// cache. Call once per frame.
|
||||
// cache. Called once per frame.
|
||||
void idle();
|
||||
|
||||
// If name is in cache, returns true and fills in provided LLAvatarName
|
||||
// otherwise returns false
|
||||
// otherwise returns false.
|
||||
bool get(const LLUUID& agent_id, LLAvatarName *av_name);
|
||||
|
||||
// Callback types for get() below
|
||||
|
|
@ -73,21 +73,19 @@ namespace LLAvatarNameCache
|
|||
typedef callback_signal_t::slot_type callback_slot_t;
|
||||
typedef boost::signals2::connection callback_connection_t;
|
||||
|
||||
// Fetches name information and calls callback.
|
||||
// If name information is in cache, callback will be called immediately.
|
||||
// Fetches name information and calls callbacks.
|
||||
// If name information is in cache, callbacks will be called immediately.
|
||||
callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
|
||||
|
||||
// Allow display names to be explicitly disabled for testing.
|
||||
// Set display name: flips the switch and triggers the callbacks.
|
||||
void setUseDisplayNames(bool use);
|
||||
bool useDisplayNames();
|
||||
|
||||
|
||||
void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
void erase(const LLUUID& agent_id);
|
||||
|
||||
/// Provide some fallback for agents that return errors
|
||||
/// Provide some fallback for agents that return errors.
|
||||
void handleAgentError(const LLUUID& agent_id);
|
||||
|
||||
void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
|
||||
// Compute name expiration time from HTTP Cache-Control header,
|
||||
// or return default value, in seconds from epoch.
|
||||
F64 nameExpirationFromHeaders(LLSD headers);
|
||||
|
|
|
|||
|
|
@ -525,6 +525,7 @@ std::string LLCacheName::cleanFullName(const std::string& full_name)
|
|||
}
|
||||
|
||||
//static
|
||||
// Transform hard-coded name provided by server to a more legible username
|
||||
std::string LLCacheName::buildUsername(const std::string& full_name)
|
||||
{
|
||||
// rare, but handle hard-coded error names returned from server
|
||||
|
|
@ -550,8 +551,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
|
|||
return username;
|
||||
}
|
||||
|
||||
// if the input wasn't a correctly formatted legacy name just return it unchanged
|
||||
return full_name;
|
||||
// if the input wasn't a correctly formatted legacy name, just return it
|
||||
// cleaned up from a potential terminal "Resident"
|
||||
return cleanFullName(full_name);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ typedef boost::signals2::signal<void (const LLUUID& id,
|
|||
bool is_group)> LLCacheNameSignal;
|
||||
typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
|
||||
|
||||
// Old callback with user data for compatability
|
||||
// Old callback with user data for compatibility
|
||||
typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*);
|
||||
|
||||
// Here's the theory:
|
||||
|
|
|
|||
|
|
@ -156,18 +156,6 @@ const S32 DB_USER_SKILLS_BUF_SIZE = 255;
|
|||
const S32 DB_NV_NAME_STR_LEN = 128;
|
||||
const S32 DB_NV_NAME_BUF_SIZE = 129;
|
||||
|
||||
// votes.vote_text varchar(254)
|
||||
const S32 DB_VOTE_TEXT_STR_LEN = 254;
|
||||
const S32 DB_VOTE_TEXT_BUF_SIZE = 255;
|
||||
|
||||
// vpte type text varchar(9)
|
||||
const S32 DB_VOTE_TYPE_STR_LEN = 9;
|
||||
const S32 DB_VOTE_TYPE_BUF_SIZE = 10;
|
||||
|
||||
// vote result text
|
||||
const S32 DB_VOTE_RESULT_BUF_LEN = 8;
|
||||
const S32 DB_VOTE_RESULT_BUF_SIZE = 9;
|
||||
|
||||
// user_start_location.location_name varchar(254)
|
||||
const S32 DB_START_LOCATION_STR_LEN = 254;
|
||||
const S32 DB_START_LOCATION_BUF_SIZE = 255;
|
||||
|
|
|
|||
|
|
@ -43,14 +43,6 @@
|
|||
const U8 IM_ONLINE = 0;
|
||||
const U8 IM_OFFLINE = 1;
|
||||
|
||||
const S32 VOTE_YES = 1;
|
||||
const S32 VOTE_NO = 0;
|
||||
const S32 VOTE_ABSTAIN = -1;
|
||||
|
||||
const S32 VOTE_MAJORITY = 0;
|
||||
const S32 VOTE_SUPER_MAJORITY = 1;
|
||||
const S32 VOTE_UNANIMOUS = 2;
|
||||
|
||||
const char EMPTY_BINARY_BUCKET[] = "";
|
||||
const S32 EMPTY_BINARY_BUCKET_SIZE = 1;
|
||||
const U32 NO_TIMESTAMP = 0;
|
||||
|
|
@ -69,7 +61,6 @@ LLIMInfo::LLIMInfo() :
|
|||
mViewerThinksToIsOnline(false),
|
||||
mIMType(IM_NOTHING_SPECIAL),
|
||||
mTimeStamp(0),
|
||||
mSource(IM_FROM_SIM),
|
||||
mTTL(IM_TTL)
|
||||
{
|
||||
}
|
||||
|
|
@ -88,7 +79,6 @@ LLIMInfo::LLIMInfo(
|
|||
LLSD data,
|
||||
U8 offline,
|
||||
U32 timestamp,
|
||||
EIMSource source,
|
||||
S32 ttl) :
|
||||
mFromID(from_id),
|
||||
mFromGroup(from_group),
|
||||
|
|
@ -104,14 +94,12 @@ LLIMInfo::LLIMInfo(
|
|||
mName(name),
|
||||
mMessage(message),
|
||||
mData(data),
|
||||
mSource(source),
|
||||
mTTL(ttl)
|
||||
{
|
||||
}
|
||||
|
||||
LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
|
||||
LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) :
|
||||
mViewerThinksToIsOnline(false),
|
||||
mSource(source),
|
||||
mTTL(ttl)
|
||||
{
|
||||
unpackMessageBlock(msg);
|
||||
|
|
@ -326,7 +314,6 @@ LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
|
|||
param_message["region_id"] = im_info->mRegionID;
|
||||
param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
|
||||
param_message["data"] = im_info->mData;
|
||||
param_message["source"]= im_info->mSource;
|
||||
param_message["ttl"] = im_info->mTTL;
|
||||
|
||||
LLSD param_agent;
|
||||
|
|
@ -359,7 +346,6 @@ LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
|
|||
param_message["data"],
|
||||
(U8) param_message["offline"].asInteger(),
|
||||
(U32) param_message["timestamp"].asInteger(),
|
||||
(EIMSource)param_message["source"].asInteger(),
|
||||
param_message["ttl"].asInteger());
|
||||
|
||||
return im_info;
|
||||
|
|
@ -381,7 +367,6 @@ LLPointer<LLIMInfo> LLIMInfo::clone()
|
|||
mData,
|
||||
mOffline,
|
||||
mTimeStamp,
|
||||
mSource,
|
||||
mTTL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,8 +115,8 @@ enum EInstantMessage
|
|||
// viewer, since you can't IM an object yet.
|
||||
IM_FROM_TASK = 19,
|
||||
|
||||
// sent an IM to a busy user, this is the auto response
|
||||
IM_BUSY_AUTO_RESPONSE = 20,
|
||||
// sent an IM to a do not disturb user, this is the auto response
|
||||
IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20,
|
||||
|
||||
// Shows the message in the console and chat history
|
||||
IM_CONSOLE_AND_CHAT_HISTORY = 21,
|
||||
|
|
@ -164,57 +164,9 @@ enum EInstantMessage
|
|||
};
|
||||
|
||||
|
||||
// Hooks for quickly hacking in experimental admin debug messages
|
||||
// without needing to recompile the viewer
|
||||
// *NOTE: This functionality has been moved to be a string based
|
||||
// operation so that we don't even have to do a full recompile. This
|
||||
// enumeration will be phased out soon.
|
||||
enum EGodlikeRequest
|
||||
{
|
||||
GOD_WANTS_NOTHING,
|
||||
|
||||
// for requesting physics information about an object
|
||||
GOD_WANTS_PHYSICS_INFO,
|
||||
|
||||
// two unused requests that can be appropriated for debug
|
||||
// purposes (no viewer recompile necessary)
|
||||
GOD_WANTS_FOO,
|
||||
GOD_WANTS_BAR,
|
||||
|
||||
// to dump simulator terrain data to terrain.raw file
|
||||
GOD_WANTS_TERRAIN_SAVE,
|
||||
// to load simulator terrain data from terrain.raw file
|
||||
GOD_WANTS_TERRAIN_LOAD,
|
||||
|
||||
GOD_WANTS_TOGGLE_AVATAR_GEOMETRY, // HACK for testing new avatar geom
|
||||
|
||||
// real-time telehub operations
|
||||
GOD_WANTS_TELEHUB_INFO,
|
||||
GOD_WANTS_CONNECT_TELEHUB,
|
||||
GOD_WANTS_DELETE_TELEHUB,
|
||||
GOD_WANTS_ADD_TELEHUB_SPAWNPOINT,
|
||||
GOD_WANTS_REMOVE_TELEHUB_SPAWNPOINT,
|
||||
|
||||
};
|
||||
|
||||
enum EIMSource
|
||||
{
|
||||
IM_FROM_VIEWER,
|
||||
IM_FROM_DATASERVER,
|
||||
IM_FROM_SIM
|
||||
};
|
||||
|
||||
extern const U8 IM_ONLINE;
|
||||
extern const U8 IM_OFFLINE;
|
||||
|
||||
extern const S32 VOTE_YES;
|
||||
extern const S32 VOTE_NO;
|
||||
extern const S32 VOTE_ABSTAIN;
|
||||
|
||||
extern const S32 VOTE_MAJORITY;
|
||||
extern const S32 VOTE_SUPER_MAJORITY;
|
||||
extern const S32 VOTE_UNANIMOUS;
|
||||
|
||||
extern const char EMPTY_BINARY_BUCKET[];
|
||||
extern const S32 EMPTY_BINARY_BUCKET_SIZE;
|
||||
|
||||
|
|
@ -234,7 +186,6 @@ protected:
|
|||
|
||||
public:
|
||||
LLIMInfo(LLMessageSystem* msg,
|
||||
EIMSource source = IM_FROM_SIM,
|
||||
S32 ttl = IM_TTL);
|
||||
|
||||
LLIMInfo(
|
||||
|
|
@ -251,7 +202,6 @@ public:
|
|||
LLSD data,
|
||||
U8 offline,
|
||||
U32 timestamp,
|
||||
EIMSource source,
|
||||
S32 ttl = IM_TTL);
|
||||
|
||||
void packInstantMessage(LLMessageSystem* msg) const;
|
||||
|
|
@ -274,7 +224,6 @@ public:
|
|||
std::string mMessage;
|
||||
LLSD mData;
|
||||
|
||||
EIMSource mSource;
|
||||
S32 mTTL;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,13 +43,11 @@ set(llrender_SOURCE_FILES
|
|||
llimagegl.cpp
|
||||
llpostprocess.cpp
|
||||
llrender.cpp
|
||||
llrender2dutils.cpp
|
||||
llrendernavprim.cpp
|
||||
llrendersphere.cpp
|
||||
llrendertarget.cpp
|
||||
llshadermgr.cpp
|
||||
lltexture.cpp
|
||||
lluiimage.cpp
|
||||
llvertexbuffer.cpp
|
||||
)
|
||||
|
||||
|
|
@ -71,12 +69,10 @@ set(llrender_HEADER_FILES
|
|||
llimagegl.h
|
||||
llpostprocess.h
|
||||
llrender.h
|
||||
llrender2dutils.h
|
||||
llrendernavprim.h
|
||||
llrendersphere.h
|
||||
llshadermgr.h
|
||||
lltexture.h
|
||||
lluiimage.h
|
||||
llvertexbuffer.h
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -57,8 +57,13 @@
|
|||
BOOL gDebugSession = FALSE;
|
||||
BOOL gDebugGL = FALSE;
|
||||
BOOL gClothRipple = FALSE;
|
||||
BOOL gHeadlessClient = FALSE;
|
||||
BOOL gGLActive = FALSE;
|
||||
|
||||
static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
|
||||
static const std::string HEADLESS_RENDERER_STRING("Headless");
|
||||
static const std::string HEADLESS_VERSION_STRING("1.0");
|
||||
|
||||
std::ofstream gFailLog;
|
||||
|
||||
#if GL_ARB_debug_output
|
||||
|
|
@ -388,7 +393,7 @@ PFNGLACTIVETEXTUREARBPROC glActiveTextureARB = NULL;
|
|||
PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
|
||||
PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements = NULL;
|
||||
#endif // LL_LINUX_NV_GL_HEADERS
|
||||
#endif // (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
#endif
|
||||
|
||||
LLGLManager gGLManager;
|
||||
|
||||
|
|
@ -592,12 +597,11 @@ bool LLGLManager::initGL()
|
|||
if (mGLVendor.substr(0,4) == "ATI ")
|
||||
{
|
||||
mGLVendorShort = "ATI";
|
||||
// "mobile" appears to be unused, and this code was causing warnings.
|
||||
//BOOL mobile = FALSE;
|
||||
//if (mGLRenderer.find("MOBILITY") != std::string::npos)
|
||||
//{
|
||||
// mobile = TRUE;
|
||||
//}
|
||||
BOOL mobile = FALSE;
|
||||
if (mGLRenderer.find("MOBILITY") != std::string::npos)
|
||||
{
|
||||
mobile = TRUE;
|
||||
}
|
||||
mIsATI = TRUE;
|
||||
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
|
|
@ -784,9 +788,19 @@ void LLGLManager::setToDebugGPU()
|
|||
|
||||
void LLGLManager::getGLInfo(LLSD& info)
|
||||
{
|
||||
info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
|
||||
info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
|
||||
info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
info["GLInfo"]["GLVendor"] = HEADLESS_VENDOR_STRING;
|
||||
info["GLInfo"]["GLRenderer"] = HEADLESS_RENDERER_STRING;
|
||||
info["GLInfo"]["GLVersion"] = HEADLESS_VERSION_STRING;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
|
||||
info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
|
||||
info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
|
||||
}
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
|
||||
|
|
@ -803,9 +817,18 @@ std::string LLGLManager::getGLInfoString()
|
|||
{
|
||||
std::string info_str;
|
||||
|
||||
info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
info_str += std::string("GL_VENDOR ") + HEADLESS_VENDOR_STRING + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + HEADLESS_RENDERER_STRING + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + HEADLESS_VERSION_STRING + std::string("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
|
||||
}
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
|
|
@ -818,9 +841,18 @@ std::string LLGLManager::getGLInfoString()
|
|||
|
||||
void LLGLManager::printGLInfoString()
|
||||
{
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << HEADLESS_VENDOR_STRING << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << HEADLESS_RENDERER_STRING << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << HEADLESS_VERSION_STRING << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
|
||||
}
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
|
|
@ -832,7 +864,14 @@ void LLGLManager::printGLInfoString()
|
|||
std::string LLGLManager::getRawGLString()
|
||||
{
|
||||
std::string gl_string;
|
||||
gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
|
||||
if (gHeadlessClient)
|
||||
{
|
||||
gl_string = HEADLESS_VENDOR_STRING + " " + HEADLESS_RENDERER_STRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
|
||||
}
|
||||
return gl_string;
|
||||
}
|
||||
|
||||
|
|
@ -898,7 +937,7 @@ void LLGLManager::initExtensions()
|
|||
mHasCubeMap = FALSE;
|
||||
mHasOcclusionQuery = FALSE;
|
||||
mHasPointParameters = FALSE;
|
||||
mHasShaderObjects = TRUE;
|
||||
mHasShaderObjects = FALSE;
|
||||
mHasVertexShader = FALSE;
|
||||
mHasFragmentShader = FALSE;
|
||||
mHasTextureRectangle = FALSE;
|
||||
|
|
@ -1451,7 +1490,8 @@ void assert_glerror()
|
|||
void clear_glerror()
|
||||
{
|
||||
// Create or update texture to be used with this data
|
||||
glGetError();
|
||||
GLenum error;
|
||||
error = glGetError();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
|
@ -1950,10 +1990,7 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
|
|||
if (mState)
|
||||
{
|
||||
mWasEnabled = sStateMap[state];
|
||||
if (gDebugGL)
|
||||
{
|
||||
llassert(mWasEnabled == glIsEnabled(state));
|
||||
}
|
||||
llassert(mWasEnabled == glIsEnabled(state));
|
||||
setEnabled(enabled);
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -457,6 +457,7 @@ void init_glstates();
|
|||
void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
|
||||
|
||||
extern BOOL gClothRipple;
|
||||
extern BOOL gHeadlessClient;
|
||||
extern BOOL gGLActive;
|
||||
|
||||
// Deal with changing glext.h definitions for newer SDK versions, specifically
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,164 +0,0 @@
|
|||
/**
|
||||
* @file llrender2dutils.h
|
||||
* @brief GL function declarations for immediate-mode gl drawing.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// All immediate-mode gl drawing should happen here.
|
||||
|
||||
|
||||
#ifndef LL_RENDER2DUTILS_H
|
||||
#define LL_RENDER2DUTILS_H
|
||||
|
||||
#include "llpointer.h" // LLPointer<>
|
||||
#include "llrect.h"
|
||||
#include "llglslshader.h"
|
||||
|
||||
class LLColor4;
|
||||
class LLVector3;
|
||||
class LLVector2;
|
||||
class LLUIImage;
|
||||
class LLUUID;
|
||||
|
||||
extern const LLColor4 UI_VERTEX_COLOR;
|
||||
|
||||
BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
|
||||
void gl_state_for_2d(S32 width, S32 height);
|
||||
|
||||
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
|
||||
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
|
||||
void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
|
||||
void gl_rect_2d_simple( S32 width, S32 height );
|
||||
|
||||
void gl_draw_x(const LLRect& rect, const LLColor4& color);
|
||||
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
|
||||
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
|
||||
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
|
||||
void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
|
||||
void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
|
||||
void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
|
||||
|
||||
void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
|
||||
|
||||
void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
|
||||
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
|
||||
void gl_deep_circle( F32 radius, F32 depth );
|
||||
void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
|
||||
void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
|
||||
void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
|
||||
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
|
||||
|
||||
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
|
||||
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
|
||||
|
||||
void gl_rect_2d_simple_tex( S32 width, S32 height );
|
||||
|
||||
// segmented rectangles
|
||||
|
||||
/*
|
||||
TL |______TOP_________| TR
|
||||
/| |\
|
||||
_/_|__________________|_\_
|
||||
L| | MIDDLE | |R
|
||||
_|_|__________________|_|_
|
||||
\ | BOTTOM | /
|
||||
BL\|__________________|/ BR
|
||||
| |
|
||||
*/
|
||||
|
||||
typedef enum e_rounded_edge
|
||||
{
|
||||
ROUNDED_RECT_LEFT = 0x1,
|
||||
ROUNDED_RECT_TOP = 0x2,
|
||||
ROUNDED_RECT_RIGHT = 0x4,
|
||||
ROUNDED_RECT_BOTTOM = 0x8,
|
||||
ROUNDED_RECT_ALL = 0xf
|
||||
}ERoundedEdge;
|
||||
|
||||
|
||||
void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
|
||||
void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
|
||||
void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
|
||||
void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
|
||||
|
||||
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
|
||||
{
|
||||
gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
|
||||
}
|
||||
|
||||
inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
|
||||
{
|
||||
gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
|
||||
}
|
||||
|
||||
class LLImageProviderInterface;
|
||||
|
||||
class LLRender2D
|
||||
{
|
||||
LOG_CLASS(LLRender2D);
|
||||
public:
|
||||
static void initClass(LLImageProviderInterface* image_provider,
|
||||
const LLVector2* scale_factor);
|
||||
static void cleanupClass();
|
||||
|
||||
static void pushMatrix();
|
||||
static void popMatrix();
|
||||
static void loadIdentity();
|
||||
static void translate(F32 x, F32 y, F32 z = 0.0f);
|
||||
|
||||
static void setLineWidth(F32 width);
|
||||
static void setScaleFactor(const LLVector2& scale_factor);
|
||||
|
||||
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
|
||||
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
|
||||
|
||||
static LLVector2 sGLScaleFactor;
|
||||
private:
|
||||
static LLImageProviderInterface* sImageProvider;
|
||||
};
|
||||
|
||||
class LLImageProviderInterface
|
||||
{
|
||||
protected:
|
||||
LLImageProviderInterface() {};
|
||||
virtual ~LLImageProviderInterface() {};
|
||||
public:
|
||||
virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
|
||||
virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
|
||||
virtual void cleanUp() = 0;
|
||||
};
|
||||
|
||||
|
||||
extern LLGLSLShader gSolidColorProgram;
|
||||
extern LLGLSLShader gUIProgram;
|
||||
|
||||
#endif // LL_RENDER2DUTILS_H
|
||||
|
||||
|
|
@ -37,6 +37,7 @@ set(llui_SOURCE_FILES
|
|||
llbadgeholder.cpp
|
||||
llbadgeowner.cpp
|
||||
llbutton.cpp
|
||||
llchatentry.cpp
|
||||
llcheckboxctrl.cpp
|
||||
llclipboard.cpp
|
||||
llcombobox.cpp
|
||||
|
|
@ -50,12 +51,16 @@ set(llui_SOURCE_FILES
|
|||
lleditmenuhandler.cpp
|
||||
llf32uictrl.cpp
|
||||
llfiltereditor.cpp
|
||||
llflashtimer.cpp
|
||||
llflatlistview.cpp
|
||||
llfloater.cpp
|
||||
llfloaterreg.cpp
|
||||
llfloaterreglistener.cpp
|
||||
llflyoutbutton.cpp
|
||||
llfocusmgr.cpp
|
||||
llfolderview.cpp
|
||||
llfolderviewitem.cpp
|
||||
llfolderviewmodel.cpp
|
||||
llfunctorregistry.cpp
|
||||
lliconctrl.cpp
|
||||
llkeywords.cpp
|
||||
|
|
@ -70,7 +75,6 @@ set(llui_SOURCE_FILES
|
|||
llmultislider.cpp
|
||||
llmultisliderctrl.cpp
|
||||
llnotifications.cpp
|
||||
llnotificationslistener.cpp
|
||||
llnotificationsutil.cpp
|
||||
llpanel.cpp
|
||||
llprogressbar.cpp
|
||||
|
|
@ -113,6 +117,7 @@ set(llui_SOURCE_FILES
|
|||
lluicolortable.cpp
|
||||
lluictrl.cpp
|
||||
lluictrlfactory.cpp
|
||||
lluiimage.cpp
|
||||
lluistring.cpp
|
||||
llundo.cpp
|
||||
llurlaction.cpp
|
||||
|
|
@ -138,6 +143,7 @@ set(llui_HEADER_FILES
|
|||
llbadgeowner.h
|
||||
llbutton.h
|
||||
llcallbackmap.h
|
||||
llchatentry.h
|
||||
llcheckboxctrl.h
|
||||
llclipboard.h
|
||||
llcombobox.h
|
||||
|
|
@ -151,12 +157,16 @@ set(llui_HEADER_FILES
|
|||
lleditmenuhandler.h
|
||||
llf32uictrl.h
|
||||
llfiltereditor.h
|
||||
llflashtimer.h
|
||||
llflatlistview.h
|
||||
llfloater.h
|
||||
llfloaterreg.h
|
||||
llfloaterreglistener.h
|
||||
llflyoutbutton.h
|
||||
llfocusmgr.h
|
||||
llfolderview.h
|
||||
llfolderviewitem.h
|
||||
llfolderviewmodel.h
|
||||
llfunctorregistry.h
|
||||
llhelp.h
|
||||
lliconctrl.h
|
||||
|
|
@ -174,7 +184,6 @@ set(llui_HEADER_FILES
|
|||
llmultislider.h
|
||||
llnotificationptr.h
|
||||
llnotifications.h
|
||||
llnotificationslistener.h
|
||||
llnotificationsutil.h
|
||||
llnotificationtemplate.h
|
||||
llnotificationvisibilityrule.h
|
||||
|
|
@ -222,6 +231,7 @@ set(llui_HEADER_FILES
|
|||
lluifwd.h
|
||||
llui.h
|
||||
lluicolor.h
|
||||
lluiimage.h
|
||||
lluistring.h
|
||||
llundo.h
|
||||
llurlaction.h
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string
|
|||
if (mHeaderTextbox)
|
||||
{
|
||||
std::string text = mHeaderTextbox->getText();
|
||||
mStyleParams.font(mHeaderTextbox->getDefaultFont());
|
||||
mStyleParams.font(mHeaderTextbox->getFont());
|
||||
mStyleParams.font.style(style);
|
||||
mHeaderTextbox->setText(text, mStyleParams);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ LLButton::Params::Params()
|
|||
badge("badge"),
|
||||
handle_right_mouse("handle_right_mouse"),
|
||||
held_down_delay("held_down_delay"),
|
||||
button_flash_enable("button_flash_enable", false),
|
||||
button_flash_count("button_flash_count"),
|
||||
button_flash_rate("button_flash_rate")
|
||||
{
|
||||
|
|
@ -171,9 +172,24 @@ LLButton::LLButton(const LLButton::Params& p)
|
|||
mHeldDownSignal(NULL),
|
||||
mUseDrawContextAlpha(p.use_draw_context_alpha),
|
||||
mHandleRightMouse(p.handle_right_mouse),
|
||||
mButtonFlashCount(p.button_flash_count),
|
||||
mButtonFlashRate(p.button_flash_rate)
|
||||
mFlashingTimer(NULL)
|
||||
{
|
||||
if (p.button_flash_enable)
|
||||
{
|
||||
// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
|
||||
// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
|
||||
// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
|
||||
// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
|
||||
S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
|
||||
F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
|
||||
mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
mButtonFlashCount = p.button_flash_count;
|
||||
mButtonFlashRate = p.button_flash_rate;
|
||||
}
|
||||
|
||||
static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
|
||||
static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
|
||||
|
||||
|
|
@ -267,6 +283,11 @@ LLButton::~LLButton()
|
|||
delete mMouseDownSignal;
|
||||
delete mMouseUpSignal;
|
||||
delete mHeldDownSignal;
|
||||
|
||||
if (mFlashingTimer)
|
||||
{
|
||||
mFlashingTimer->unset();
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: Committing a button is the same as instantly clicking it.
|
||||
|
|
@ -591,22 +612,6 @@ void LLButton::draw()
|
|||
{
|
||||
static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
|
||||
F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
|
||||
bool flash = FALSE;
|
||||
|
||||
if( mFlashing)
|
||||
{
|
||||
if ( sEnableButtonFlashing)
|
||||
{
|
||||
F32 elapsed = mFlashingTimer.getElapsedTimeF32();
|
||||
S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
|
||||
// flash on or off?
|
||||
flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
|
||||
}
|
||||
else
|
||||
{ // otherwise just highlight button in flash color
|
||||
flash = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool pressed_by_keyboard = FALSE;
|
||||
if (hasFocus())
|
||||
|
|
@ -631,9 +636,21 @@ void LLButton::draw()
|
|||
bool selected = getToggleState();
|
||||
|
||||
bool use_glow_effect = FALSE;
|
||||
LLColor4 glow_color = LLColor4::white;
|
||||
LLColor4 highlighting_color = LLColor4::white;
|
||||
LLColor4 glow_color;
|
||||
LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
|
||||
LLUIImage* imagep = NULL;
|
||||
|
||||
// Cancel sticking of color, if the button is pressed,
|
||||
// or when a flashing of the previously selected button is ended
|
||||
if (mFlashingTimer
|
||||
&& ((selected && !mFlashingTimer->isFlashingInProgress()) || pressed))
|
||||
{
|
||||
mFlashing = false;
|
||||
}
|
||||
|
||||
bool flash = mFlashing && sEnableButtonFlashing;
|
||||
|
||||
if (pressed && mDisplayPressedState)
|
||||
{
|
||||
imagep = selected ? mImagePressedSelected : mImagePressed;
|
||||
|
|
@ -699,15 +716,20 @@ void LLButton::draw()
|
|||
imagep = mImageFlash;
|
||||
}
|
||||
// else use usual flashing via flash_color
|
||||
else
|
||||
else if (mFlashingTimer)
|
||||
{
|
||||
LLColor4 flash_color = mFlashBgColor.get();
|
||||
use_glow_effect = TRUE;
|
||||
glow_type = LLRender::BT_ALPHA; // blend the glow
|
||||
if (mNeedsHighlight) // highlighted AND flashing
|
||||
glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
|
||||
else
|
||||
|
||||
if (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress())
|
||||
{
|
||||
glow_color = flash_color;
|
||||
}
|
||||
else if (mNeedsHighlight)
|
||||
{
|
||||
glow_color = highlighting_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -756,8 +778,7 @@ void LLButton::draw()
|
|||
if (use_glow_effect)
|
||||
{
|
||||
mCurGlowStrength = lerp(mCurGlowStrength,
|
||||
mFlashing ? (flash? 1.0 : 0.0)
|
||||
: mHoverGlowStrength,
|
||||
mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength,
|
||||
LLCriticalDamp::getInterpolant(0.05f));
|
||||
}
|
||||
else
|
||||
|
|
@ -944,21 +965,26 @@ void LLButton::setToggleState(BOOL b)
|
|||
{
|
||||
setControlValue(b); // will fire LLControlVariable callbacks (if any)
|
||||
setValue(b); // may or may not be redundant
|
||||
setFlashing(false); // stop flash state whenever the selected/unselected state if reset
|
||||
// Unselected label assignments
|
||||
autoResize();
|
||||
}
|
||||
}
|
||||
|
||||
void LLButton::setFlashing( BOOL b )
|
||||
void LLButton::setFlashing(bool b)
|
||||
{
|
||||
if ((bool)b != mFlashing)
|
||||
if (mFlashingTimer)
|
||||
{
|
||||
mFlashing = b;
|
||||
mFlashingTimer.reset();
|
||||
(b ? mFlashingTimer->startFlashing() : mFlashingTimer->stopFlashing());
|
||||
}
|
||||
else if (b != mFlashing)
|
||||
{
|
||||
mFlashing = b;
|
||||
mFrameTimer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL LLButton::toggleState()
|
||||
{
|
||||
bool flipped = ! getToggleState();
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "lluuid.h"
|
||||
#include "llbadgeowner.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llflashtimer.h"
|
||||
#include "lluictrl.h"
|
||||
#include "v4color.h"
|
||||
#include "llframetimer.h"
|
||||
|
|
@ -133,6 +134,7 @@ public:
|
|||
|
||||
Optional<bool> handle_right_mouse;
|
||||
|
||||
Optional<bool> button_flash_enable;
|
||||
Optional<S32> button_flash_count;
|
||||
Optional<F32> button_flash_rate;
|
||||
|
||||
|
|
@ -199,8 +201,9 @@ public:
|
|||
void setToggleState(BOOL b);
|
||||
|
||||
void setHighlight(bool b);
|
||||
void setFlashing( BOOL b );
|
||||
void setFlashing( bool b );
|
||||
BOOL getFlashing() const { return mFlashing; }
|
||||
LLFlashTimer* getFlashTimer() {return mFlashingTimer;}
|
||||
|
||||
void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; }
|
||||
LLFontGL::HAlign getHAlign() const { return mHAlign; }
|
||||
|
|
@ -373,7 +376,8 @@ protected:
|
|||
bool mForcePressedState;
|
||||
bool mDisplayPressedState;
|
||||
|
||||
LLFrameTimer mFlashingTimer;
|
||||
LLFrameTimer mFrameTimer;
|
||||
LLFlashTimer * mFlashingTimer;
|
||||
|
||||
bool mHandleRightMouse;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* @file llchatentry.cpp
|
||||
* @brief LLChatEntry implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llchatentry.h"
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLChatEntry> r("chat_editor");
|
||||
|
||||
LLChatEntry::Params::Params()
|
||||
: has_history("has_history", true),
|
||||
is_expandable("is_expandable", false),
|
||||
expand_lines_count("expand_lines_count", 1)
|
||||
{}
|
||||
|
||||
LLChatEntry::LLChatEntry(const Params& p)
|
||||
: LLTextEditor(p),
|
||||
mTextExpandedSignal(NULL),
|
||||
mHasHistory(p.has_history),
|
||||
mIsExpandable(p.is_expandable),
|
||||
mExpandLinesCount(p.expand_lines_count),
|
||||
mPrevLinesCount(0)
|
||||
{
|
||||
// Initialize current history line iterator
|
||||
mCurrentHistoryLine = mLineHistory.begin();
|
||||
|
||||
mAutoIndent = false;
|
||||
}
|
||||
|
||||
LLChatEntry::~LLChatEntry()
|
||||
{
|
||||
delete mTextExpandedSignal;
|
||||
}
|
||||
|
||||
void LLChatEntry::draw()
|
||||
{
|
||||
if(mIsExpandable)
|
||||
{
|
||||
expandText();
|
||||
}
|
||||
|
||||
LLTextEditor::draw();
|
||||
}
|
||||
|
||||
void LLChatEntry::onCommit()
|
||||
{
|
||||
updateHistory();
|
||||
LLTextEditor::onCommit();
|
||||
}
|
||||
|
||||
boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_signal_t::slot_type& cb)
|
||||
{
|
||||
if (!mTextExpandedSignal)
|
||||
{
|
||||
mTextExpandedSignal = new commit_signal_t();
|
||||
}
|
||||
return mTextExpandedSignal->connect(cb);
|
||||
}
|
||||
|
||||
void LLChatEntry::expandText()
|
||||
{
|
||||
int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
|
||||
bool can_expand = getLineCount() <= mExpandLinesCount;
|
||||
|
||||
// true if pasted text has more lines than expand height limit and expand limit is not reached yet
|
||||
bool text_pasted = (getLineCount() > mExpandLinesCount) && (visible_lines_count < mExpandLinesCount);
|
||||
|
||||
if (mIsExpandable && (can_expand || text_pasted) && getLineCount() != mPrevLinesCount)
|
||||
{
|
||||
int lines_height = 0;
|
||||
if (text_pasted)
|
||||
{
|
||||
// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
|
||||
// so lines_height is the sum of the last 'mExpandLinesCount' lines height
|
||||
lines_height = (mLineInfoList.end() - mExpandLinesCount)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
lines_height = mLineInfoList.begin()->mRect.mTop - mLineInfoList.back().mRect.mBottom;
|
||||
}
|
||||
|
||||
int height = mVPad * 2 + lines_height;
|
||||
|
||||
LLRect doc_rect = getRect();
|
||||
doc_rect.setOriginAndSize(doc_rect.mLeft, doc_rect.mBottom, doc_rect.getWidth(), height);
|
||||
setShape(doc_rect);
|
||||
|
||||
mPrevLinesCount = getLineCount();
|
||||
|
||||
if (mTextExpandedSignal)
|
||||
{
|
||||
(*mTextExpandedSignal)(this, LLSD() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// line history support
|
||||
void LLChatEntry::updateHistory()
|
||||
{
|
||||
// On history enabled, remember committed line and
|
||||
// reset current history line number.
|
||||
// Be sure only to remember lines that are not empty and that are
|
||||
// different from the last on the list.
|
||||
if (mHasHistory && getLength())
|
||||
{
|
||||
// Add text to history, ignoring duplicates
|
||||
if (mLineHistory.empty() || getText() != mLineHistory.back())
|
||||
{
|
||||
mLineHistory.push_back(getText());
|
||||
}
|
||||
|
||||
mCurrentHistoryLine = mLineHistory.end();
|
||||
}
|
||||
}
|
||||
|
||||
void LLChatEntry::beforeValueChange()
|
||||
{
|
||||
if(this->getLength() == 0 && !mLabel.empty())
|
||||
{
|
||||
this->clearSegments();
|
||||
}
|
||||
}
|
||||
|
||||
void LLChatEntry::onValueChange(S32 start, S32 end)
|
||||
{
|
||||
//Internally resetLabel() must meet a condition before it can reset the label
|
||||
resetLabel();
|
||||
}
|
||||
|
||||
bool LLChatEntry::useLabel()
|
||||
{
|
||||
return !getLength() && !mLabel.empty();
|
||||
}
|
||||
|
||||
void LLChatEntry::onFocusReceived()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLChatEntry::onFocusLost()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
||||
LLTextEditor::handleSpecialKey(key, mask);
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case KEY_RETURN:
|
||||
if (MASK_NONE == mask)
|
||||
{
|
||||
needsReflow();
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
if (mHasHistory && MASK_CONTROL == mask)
|
||||
{
|
||||
if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin())
|
||||
{
|
||||
setText(*(--mCurrentHistoryLine));
|
||||
endOfDoc();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::reportBadKeystroke();
|
||||
}
|
||||
handled = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
if (mHasHistory && MASK_CONTROL == mask)
|
||||
{
|
||||
if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1) )
|
||||
{
|
||||
setText(*(++mCurrentHistoryLine));
|
||||
endOfDoc();
|
||||
}
|
||||
else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1) )
|
||||
{
|
||||
mCurrentHistoryLine++;
|
||||
std::string empty("");
|
||||
setText(empty);
|
||||
needsReflow();
|
||||
endOfDoc();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLUI::reportBadKeystroke();
|
||||
}
|
||||
handled = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/**
|
||||
* @file llchatentry.h
|
||||
* @author Paul Guslisty
|
||||
* @brief Text editor widget which is used for user input
|
||||
*
|
||||
* Features:
|
||||
* Optional line history so previous entries can be recalled by CTRL UP/DOWN
|
||||
* Optional auto-resize behavior on input chat field
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LLCHATENTRY_H_
|
||||
#define LLCHATENTRY_H_
|
||||
|
||||
#include "lltexteditor.h"
|
||||
|
||||
class LLChatEntry : public LLTextEditor
|
||||
{
|
||||
public:
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
|
||||
{
|
||||
Optional<bool> has_history,
|
||||
is_expandable;
|
||||
|
||||
Optional<int> expand_lines_count;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
virtual ~LLChatEntry();
|
||||
|
||||
protected:
|
||||
|
||||
friend class LLUICtrlFactory;
|
||||
LLChatEntry(const Params& p);
|
||||
/*virtual*/ void beforeValueChange();
|
||||
/*virtual*/ void onValueChange(S32 start, S32 end);
|
||||
/*virtual*/ bool useLabel();
|
||||
|
||||
public:
|
||||
|
||||
virtual void draw();
|
||||
virtual void onCommit();
|
||||
/*virtual*/ void onFocusReceived();
|
||||
/*virtual*/ void onFocusLost();
|
||||
|
||||
boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Implements auto-resize behavior.
|
||||
* When user's typing reaches the right edge of the chat field
|
||||
* the chat field expands vertically by one line. The bottom of
|
||||
* the chat field remains bottom-justified. The chat field does
|
||||
* not expand beyond mExpandLinesCount.
|
||||
*/
|
||||
void expandText();
|
||||
|
||||
/**
|
||||
* Implements line history so previous entries can be recalled by CTRL UP/DOWN
|
||||
*/
|
||||
void updateHistory();
|
||||
|
||||
BOOL handleSpecialKey(const KEY key, const MASK mask);
|
||||
|
||||
|
||||
// Fired when text height expanded to mExpandLinesCount
|
||||
commit_signal_t* mTextExpandedSignal;
|
||||
|
||||
// line history support:
|
||||
typedef std::vector<std::string> line_history_t;
|
||||
line_history_t::iterator mCurrentHistoryLine; // currently browsed history line
|
||||
line_history_t mLineHistory; // line history storage
|
||||
bool mHasHistory; // flag for enabled/disabled line history
|
||||
bool mIsExpandable;
|
||||
|
||||
int mExpandLinesCount;
|
||||
int mPrevLinesCount;
|
||||
};
|
||||
|
||||
#endif /* LLCHATENTRY_H_ */
|
||||
|
|
@ -107,7 +107,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
|
|||
LLButton::Params params = p.check_button;
|
||||
params.rect(btn_rect);
|
||||
//params.control_name(p.control_name);
|
||||
params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onButtonPress, this, _2));
|
||||
params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onCommit, this));
|
||||
params.commit_on_return(false);
|
||||
// Checkboxes only allow boolean initial values, but buttons can
|
||||
// take any LLSD.
|
||||
|
|
@ -123,18 +123,6 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
|
|||
// Children all cleaned up by default view destructor.
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLCheckBoxCtrl::onButtonPress( const LLSD& data )
|
||||
{
|
||||
//if (mRadioStyle)
|
||||
//{
|
||||
// setValue(TRUE);
|
||||
//}
|
||||
|
||||
onCommit();
|
||||
}
|
||||
|
||||
void LLCheckBoxCtrl::onCommit()
|
||||
{
|
||||
if( getEnabled() )
|
||||
|
|
|
|||
|
|
@ -103,8 +103,6 @@ public:
|
|||
|
||||
virtual void setControlName(const std::string& control_name, LLView* context);
|
||||
|
||||
void onButtonPress(const LLSD& data);
|
||||
|
||||
virtual BOOL isDirty() const; // Returns TRUE if the user has modified this control.
|
||||
virtual void resetDirty(); // Clear dirty state
|
||||
|
||||
|
|
|
|||
|
|
@ -551,7 +551,7 @@ void LLComboBox::showList()
|
|||
LLCoordWindow window_size;
|
||||
getWindow()->getSize(&window_size);
|
||||
//HACK: shouldn't have to know about scale here
|
||||
mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::getScaleFactor().mV[VY]) - 50 );
|
||||
mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 );
|
||||
|
||||
// Make sure that we can see the whole list
|
||||
LLRect root_view_local;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ LLCommand::Params::Params()
|
|||
, is_running_parameters("is_running_parameters")
|
||||
, is_starting_function("is_starting_function")
|
||||
, is_starting_parameters("is_starting_parameters")
|
||||
, is_flashing_allowed("is_flashing_allowed", false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -83,6 +84,7 @@ LLCommand::LLCommand(const LLCommand::Params& p)
|
|||
, mIsRunningParameters(p.is_running_parameters)
|
||||
, mIsStartingFunction(p.is_starting_function)
|
||||
, mIsStartingParameters(p.is_starting_parameters)
|
||||
, mIsFlashingAllowed(p.is_flashing_allowed)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,8 @@ public:
|
|||
Optional<std::string> is_starting_function;
|
||||
Optional<LLSD> is_starting_parameters;
|
||||
|
||||
Optional<bool> is_flashing_allowed;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
|
|
@ -138,6 +140,8 @@ public:
|
|||
const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
|
||||
const LLSD& isStartingParameters() const { return mIsStartingParameters; }
|
||||
|
||||
bool isFlashingAllowed() const { return mIsFlashingAllowed; }
|
||||
|
||||
private:
|
||||
LLCommandId mIdentifier;
|
||||
|
||||
|
|
@ -161,6 +165,8 @@ private:
|
|||
|
||||
std::string mIsStartingFunction;
|
||||
LLSD mIsStartingParameters;
|
||||
|
||||
bool mIsFlashingAllowed;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
|
||||
LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
||||
const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
|
||||
mDockWidget(dockWidget),
|
||||
mDockableFloater(dockableFloater),
|
||||
mDockTongue(dockTongue),
|
||||
mDockTongueX(0),
|
||||
|
|
@ -39,6 +38,11 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
|||
{
|
||||
mDockAt = dockAt;
|
||||
|
||||
if (dockWidget != NULL)
|
||||
{
|
||||
mDockWidgetHandle = dockWidget->getHandle();
|
||||
}
|
||||
|
||||
if (dockableFloater->isDocked())
|
||||
{
|
||||
on();
|
||||
|
|
@ -62,7 +66,7 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
|
|||
repositionDockable();
|
||||
}
|
||||
|
||||
if (mDockWidget != NULL)
|
||||
if (getDock() != NULL)
|
||||
{
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
|
|
@ -78,14 +82,15 @@ LLDockControl::~LLDockControl()
|
|||
|
||||
void LLDockControl::setDock(LLView* dockWidget)
|
||||
{
|
||||
mDockWidget = dockWidget;
|
||||
if (mDockWidget != NULL)
|
||||
if (dockWidget != NULL)
|
||||
{
|
||||
mDockWidgetHandle = dockWidget->getHandle();
|
||||
repositionDockable();
|
||||
mDockWidgetVisible = isDockVisible();
|
||||
}
|
||||
else
|
||||
{
|
||||
mDockWidgetHandle = LLHandle<LLView>();
|
||||
mDockWidgetVisible = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -97,8 +102,8 @@ void LLDockControl::getAllowedRect(LLRect& rect)
|
|||
|
||||
void LLDockControl::repositionDockable()
|
||||
{
|
||||
if (!mDockWidget) return;
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
if (!getDock()) return;
|
||||
LLRect dockRect = getDock()->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
LLRect floater_rect = mDockableFloater->calcScreenRect();
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
|
@ -150,13 +155,13 @@ bool LLDockControl::isDockVisible()
|
|||
{
|
||||
bool res = true;
|
||||
|
||||
if (mDockWidget != NULL)
|
||||
if (getDock() != NULL)
|
||||
{
|
||||
//we should check all hierarchy
|
||||
res = mDockWidget->isInVisibleChain();
|
||||
res = getDock()->isInVisibleChain();
|
||||
if (res)
|
||||
{
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect dockRect = getDock()->calcScreenRect();
|
||||
|
||||
switch (mDockAt)
|
||||
{
|
||||
|
|
@ -169,7 +174,7 @@ bool LLDockControl::isDockVisible()
|
|||
// assume that parent for all dockable floaters
|
||||
// is the root view
|
||||
LLRect dockParentRect =
|
||||
mDockWidget->getRootView()->calcScreenRect();
|
||||
getDock()->getRootView()->calcScreenRect();
|
||||
if (dockRect.mRight <= dockParentRect.mLeft
|
||||
|| dockRect.mLeft >= dockParentRect.mRight)
|
||||
{
|
||||
|
|
@ -189,7 +194,7 @@ bool LLDockControl::isDockVisible()
|
|||
void LLDockControl::moveDockable()
|
||||
{
|
||||
// calculate new dockable position
|
||||
LLRect dockRect = mDockWidget->calcScreenRect();
|
||||
LLRect dockRect = getDock()->calcScreenRect();
|
||||
LLRect rootRect;
|
||||
mGetAllowedRectCallback(rootRect);
|
||||
|
||||
|
|
@ -263,7 +268,7 @@ void LLDockControl::moveDockable()
|
|||
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
dockParentRect = getDock()->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
|
|
@ -299,7 +304,7 @@ void LLDockControl::moveDockable()
|
|||
}
|
||||
|
||||
// calculate dock tongue position
|
||||
dockParentRect = mDockWidget->getParent()->calcScreenRect();
|
||||
dockParentRect = getDock()->getParent()->calcScreenRect();
|
||||
if (dockRect.getCenterX() < dockParentRect.mLeft)
|
||||
{
|
||||
mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ public:
|
|||
void setDock(LLView* dockWidget);
|
||||
LLView* getDock()
|
||||
{
|
||||
return mDockWidget;
|
||||
return mDockWidgetHandle.get();
|
||||
}
|
||||
void repositionDockable();
|
||||
void drawToungue();
|
||||
|
|
@ -83,7 +83,7 @@ private:
|
|||
bool mRecalculateDockablePosition;
|
||||
bool mDockWidgetVisible;
|
||||
DocAt mDockAt;
|
||||
LLView* mDockWidget;
|
||||
LLHandle<LLView> mDockWidgetHandle;
|
||||
LLRect mPrevDockRect;
|
||||
LLRect mRootRect;
|
||||
LLRect mFloaterRect;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @file llflashtimer.cpp
|
||||
* @brief LLFlashTimer class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#include "../newview/llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llflashtimer.h"
|
||||
#include "../newview/llviewercontrol.h"
|
||||
#include "lleventtimer.h"
|
||||
|
||||
LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
|
||||
: LLEventTimer(period)
|
||||
, mCallback(cb)
|
||||
, mCurrentTickCount(0)
|
||||
, mIsFlashingInProgress(false)
|
||||
, mIsCurrentlyHighlighted(false)
|
||||
, mUnset(false)
|
||||
{
|
||||
mEventTimer.stop();
|
||||
|
||||
// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
|
||||
// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
|
||||
// in runtime. So, both settings are made as required restart.
|
||||
mFlashCount = 2 * ((count > 0) ? count : gSavedSettings.getS32("FlashCount"));
|
||||
if (mPeriod <= 0)
|
||||
{
|
||||
mPeriod = gSavedSettings.getF32("FlashPeriod");
|
||||
}
|
||||
}
|
||||
|
||||
void LLFlashTimer::unset()
|
||||
{
|
||||
mUnset = true;
|
||||
mCallback = NULL;
|
||||
}
|
||||
|
||||
BOOL LLFlashTimer::tick()
|
||||
{
|
||||
mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
|
||||
|
||||
if (mCallback)
|
||||
{
|
||||
mCallback(mIsCurrentlyHighlighted);
|
||||
}
|
||||
|
||||
if (++mCurrentTickCount >= mFlashCount)
|
||||
{
|
||||
stopFlashing();
|
||||
}
|
||||
|
||||
return mUnset;
|
||||
}
|
||||
|
||||
void LLFlashTimer::startFlashing()
|
||||
{
|
||||
mIsFlashingInProgress = true;
|
||||
mIsCurrentlyHighlighted = true;
|
||||
mEventTimer.start();
|
||||
}
|
||||
|
||||
void LLFlashTimer::stopFlashing()
|
||||
{
|
||||
mEventTimer.stop();
|
||||
mIsFlashingInProgress = false;
|
||||
mIsCurrentlyHighlighted = false;
|
||||
mCurrentTickCount = 0;
|
||||
}
|
||||
|
||||
bool LLFlashTimer::isFlashingInProgress()
|
||||
{
|
||||
return mIsFlashingInProgress;
|
||||
}
|
||||
|
||||
bool LLFlashTimer::isCurrentlyHighlighted()
|
||||
{
|
||||
return mIsCurrentlyHighlighted;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* @file llflashtimer.h
|
||||
* @brief LLFlashTimer class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_FLASHTIMER_H
|
||||
#define LL_FLASHTIMER_H
|
||||
|
||||
#include "lleventtimer.h"
|
||||
|
||||
class LLFlashTimer : public LLEventTimer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::function<void (bool)> callback_t;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param count - how many times callback should be called (twice to not change original state)
|
||||
* @param period - how frequently callback should be called
|
||||
* @param cb - callback to be called each tick
|
||||
*/
|
||||
LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
|
||||
~LLFlashTimer() {};
|
||||
|
||||
/*virtual*/ BOOL tick();
|
||||
|
||||
void startFlashing();
|
||||
void stopFlashing();
|
||||
|
||||
bool isFlashingInProgress();
|
||||
bool isCurrentlyHighlighted();
|
||||
/*
|
||||
* Use this instead of deleting this object.
|
||||
* The next call to tick() will return true and that will destroy this object.
|
||||
*/
|
||||
void unset();
|
||||
|
||||
private:
|
||||
callback_t mCallback;
|
||||
/**
|
||||
* How many times parent will blink.
|
||||
*/
|
||||
S32 mFlashCount;
|
||||
S32 mCurrentTickCount;
|
||||
bool mIsCurrentlyHighlighted;
|
||||
bool mIsFlashingInProgress;
|
||||
bool mUnset;
|
||||
};
|
||||
|
||||
#endif /* LL_FLASHTIMER_H */
|
||||
|
|
@ -64,6 +64,8 @@
|
|||
// use this to control "jumping" behavior when Ctrl-Tabbing
|
||||
const S32 TABBED_FLOATER_OFFSET = 0;
|
||||
|
||||
extern LLControlGroup gSavedSettings;
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
|
||||
|
|
@ -627,6 +629,17 @@ void LLFloater::setVisible( BOOL visible )
|
|||
storeVisibilityControl();
|
||||
}
|
||||
|
||||
|
||||
void LLFloater::setIsSingleInstance(BOOL is_single_instance)
|
||||
{
|
||||
mSingleInstance = is_single_instance;
|
||||
if (!mIsReuseInitialized)
|
||||
{
|
||||
mReuseInstance = is_single_instance; // reuse single-instance floaters by default
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// virtual
|
||||
void LLFloater::handleVisibilityChange ( BOOL new_visibility )
|
||||
{
|
||||
|
|
@ -642,14 +655,20 @@ void LLFloater::openFloater(const LLSD& key)
|
|||
{
|
||||
llinfos << "Opening floater " << getName() << llendl;
|
||||
mKey = key; // in case we need to open ourselves again
|
||||
|
||||
|
||||
if (getSoundFlags() != SILENT
|
||||
// don't play open sound for hosted (tabbed) windows
|
||||
&& !getHost()
|
||||
&& !getFloaterHost()
|
||||
&& (!getVisible() || isMinimized()))
|
||||
{
|
||||
make_ui_sound("UISndWindowOpen");
|
||||
//Don't play a sound for incoming voice call based upon chat preference setting
|
||||
bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE);
|
||||
|
||||
if(playSound)
|
||||
{
|
||||
make_ui_sound("UISndWindowOpen");
|
||||
}
|
||||
}
|
||||
|
||||
//RN: for now, we don't allow rehosting from one multifloater to another
|
||||
|
|
@ -713,6 +732,33 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
make_ui_sound("UISndWindowClose");
|
||||
}
|
||||
|
||||
gFocusMgr.clearLastFocusForGroup(this);
|
||||
|
||||
if (hasFocus())
|
||||
{
|
||||
// Do this early, so UI controls will commit before the
|
||||
// window is taken down.
|
||||
releaseFocus();
|
||||
|
||||
// give focus to dependee floater if it exists, and we had focus first
|
||||
if (isDependent())
|
||||
{
|
||||
LLFloater* dependee = mDependeeHandle.get();
|
||||
if (dependee && !dependee->isDead())
|
||||
{
|
||||
dependee->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//If floater is a dependent, remove it from parent (dependee)
|
||||
LLFloater* dependee = mDependeeHandle.get();
|
||||
if (dependee)
|
||||
{
|
||||
dependee->removeDependentFloater(this);
|
||||
}
|
||||
|
||||
// now close dependent floater
|
||||
for(handle_set_iter_t dependent_it = mDependents.begin();
|
||||
dependent_it != mDependents.end(); )
|
||||
|
|
@ -731,28 +777,6 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
}
|
||||
|
||||
cleanupHandles();
|
||||
gFocusMgr.clearLastFocusForGroup(this);
|
||||
|
||||
if (hasFocus())
|
||||
{
|
||||
// Do this early, so UI controls will commit before the
|
||||
// window is taken down.
|
||||
releaseFocus();
|
||||
|
||||
// give focus to dependee floater if it exists, and we had focus first
|
||||
if (isDependent())
|
||||
{
|
||||
LLFloater* dependee = mDependeeHandle.get();
|
||||
if (dependee && !dependee->isDead())
|
||||
{
|
||||
dependee->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// STORM-1879: since this floater has focus, treat the closeFloater- call
|
||||
// like a click on the close-button, and close gear- and contextmenus
|
||||
LLMenuGL::sMenuContainer->hideMenus();
|
||||
}
|
||||
|
||||
dirtyRect();
|
||||
|
||||
|
|
@ -788,6 +812,20 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLFloater::closeHostedFloater()
|
||||
{
|
||||
// When toggling *visibility*, close the host instead of the floater when hosted
|
||||
if (getHost())
|
||||
{
|
||||
getHost()->closeFloater();
|
||||
}
|
||||
else
|
||||
{
|
||||
closeFloater();
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
|
|
@ -1188,7 +1226,6 @@ void LLFloater::setMinimized(BOOL minimize)
|
|||
{
|
||||
// minimized flag should be turned on before release focus
|
||||
mMinimized = TRUE;
|
||||
|
||||
mExpandedRect = getRect();
|
||||
|
||||
// If the floater has been dragged while minimized in the
|
||||
|
|
@ -1261,7 +1298,6 @@ void LLFloater::setMinimized(BOOL minimize)
|
|||
}
|
||||
|
||||
setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom );
|
||||
|
||||
if (mButtonsEnabled[BUTTON_RESTORE])
|
||||
{
|
||||
mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
|
||||
|
|
@ -1297,7 +1333,6 @@ void LLFloater::setMinimized(BOOL minimize)
|
|||
|
||||
// Reshape *after* setting mMinimized
|
||||
reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
|
||||
applyPositioning(NULL, false);
|
||||
}
|
||||
|
||||
make_ui_sound("UISndWindowClose");
|
||||
|
|
@ -1419,7 +1454,6 @@ void LLFloater::setHost(LLMultiFloater* host)
|
|||
mButtonScale = 1.f;
|
||||
//mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE;
|
||||
}
|
||||
updateTitleButtons();
|
||||
if (host)
|
||||
{
|
||||
mHostHandle = host->getHandle();
|
||||
|
|
@ -1429,6 +1463,8 @@ void LLFloater::setHost(LLMultiFloater* host)
|
|||
{
|
||||
mHostHandle.markDead();
|
||||
}
|
||||
|
||||
updateTitleButtons();
|
||||
}
|
||||
|
||||
void LLFloater::moveResizeHandlesToFront()
|
||||
|
|
@ -1587,8 +1623,17 @@ void LLFloater::bringToFront( S32 x, S32 y )
|
|||
// virtual
|
||||
void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
|
||||
{
|
||||
setVisible(TRUE);
|
||||
setFrontmost(take_focus);
|
||||
LLMultiFloater* hostp = getHost();
|
||||
if (hostp)
|
||||
{
|
||||
hostp->setVisible(TRUE);
|
||||
hostp->setFrontmost(take_focus);
|
||||
}
|
||||
else
|
||||
{
|
||||
setVisible(TRUE);
|
||||
setFrontmost(take_focus);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloater::setFrontmost(BOOL take_focus)
|
||||
|
|
@ -1670,10 +1715,12 @@ void LLFloater::onClickTearOff(LLFloater* self)
|
|||
gFloaterView->addChild(self);
|
||||
|
||||
self->openFloater(self->getKey());
|
||||
|
||||
// only force position for floaters that don't have that data saved
|
||||
if (self->mRectControl.empty())
|
||||
if (self->mSaveRect && !self->mRectControl.empty())
|
||||
{
|
||||
self->applyRectControl();
|
||||
}
|
||||
else
|
||||
{ // only force position for floaters that don't have that data saved
|
||||
new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
|
||||
self->setRect(new_rect);
|
||||
}
|
||||
|
|
@ -1687,6 +1734,10 @@ void LLFloater::onClickTearOff(LLFloater* self)
|
|||
LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get();
|
||||
if (new_host)
|
||||
{
|
||||
if (self->mSaveRect)
|
||||
{
|
||||
self->storeRectControl();
|
||||
}
|
||||
self->setMinimized(FALSE); // to reenable minimize button if it was minimized
|
||||
new_host->showFloater(self);
|
||||
// make sure host is visible
|
||||
|
|
@ -1695,6 +1746,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
|
|||
self->setTornOff(false);
|
||||
}
|
||||
self->updateTitleButtons();
|
||||
self->setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -1720,6 +1772,18 @@ void LLFloater::onClickHelp( LLFloater* self )
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloater::initRectControl()
|
||||
{
|
||||
// save_rect and save_visibility only apply to registered floaters
|
||||
if (mSaveRect)
|
||||
{
|
||||
std::string ctrl_name = getControlName(mInstanceName, mKey);
|
||||
mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
|
||||
mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
|
||||
mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloater::closeFrontmostFloater()
|
||||
{
|
||||
|
|
@ -2164,7 +2228,8 @@ LLFloaterView::LLFloaterView (const Params& p)
|
|||
mFocusCycleMode(FALSE),
|
||||
mMinimizePositionVOffset(0),
|
||||
mSnapOffsetBottom(0),
|
||||
mSnapOffsetRight(0)
|
||||
mSnapOffsetRight(0),
|
||||
mFrontChild(NULL)
|
||||
{
|
||||
mSnapView = getHandle();
|
||||
}
|
||||
|
|
@ -2313,6 +2378,17 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
|
|||
|
||||
void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
|
||||
{
|
||||
if (mFrontChild == child)
|
||||
{
|
||||
if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
|
||||
{
|
||||
child->setFocus(TRUE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mFrontChild = child;
|
||||
|
||||
// *TODO: make this respect floater's mAutoFocus value, instead of
|
||||
// using parameter
|
||||
if (child->getHost())
|
||||
|
|
@ -2320,15 +2396,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
|
|||
// this floater is hosted elsewhere and hence not one of our children, abort
|
||||
return;
|
||||
}
|
||||
std::vector<LLView*> floaters_to_move;
|
||||
std::vector<LLFloater*> floaters_to_move;
|
||||
// Look at all floaters...tab
|
||||
for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
|
||||
for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
|
||||
{
|
||||
LLView* viewp = *child_it;
|
||||
LLFloater *floater = (LLFloater *)viewp;
|
||||
LLFloater* floater = dynamic_cast<LLFloater*>(*child_it);
|
||||
|
||||
// ...but if I'm a dependent floater...
|
||||
if (child->isDependent())
|
||||
if (floater && child->isDependent())
|
||||
{
|
||||
// ...look for floaters that have me as a dependent...
|
||||
LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle());
|
||||
|
|
@ -2336,15 +2411,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
|
|||
if (found_dependent != floater->mDependents.end())
|
||||
{
|
||||
// ...and make sure all children of that floater (including me) are brought to front...
|
||||
for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
|
||||
dependent_it != floater->mDependents.end(); )
|
||||
for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
|
||||
dependent_it != floater->mDependents.end(); ++dependent_it)
|
||||
{
|
||||
LLFloater* sibling = dependent_it->get();
|
||||
if (sibling)
|
||||
{
|
||||
floaters_to_move.push_back(sibling);
|
||||
}
|
||||
++dependent_it;
|
||||
}
|
||||
//...before bringing my parent to the front...
|
||||
floaters_to_move.push_back(floater);
|
||||
|
|
@ -2352,10 +2426,10 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<LLView*>::iterator view_it;
|
||||
for(view_it = floaters_to_move.begin(); view_it != floaters_to_move.end(); ++view_it)
|
||||
std::vector<LLFloater*>::iterator floater_it;
|
||||
for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it)
|
||||
{
|
||||
LLFloater* floaterp = (LLFloater*)(*view_it);
|
||||
LLFloater* floaterp = *floater_it;
|
||||
sendChildToFront(floaterp);
|
||||
|
||||
// always unminimize dependee, but allow dependents to stay minimized
|
||||
|
|
@ -2367,23 +2441,19 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
|
|||
floaters_to_move.clear();
|
||||
|
||||
// ...then bringing my own dependents to the front...
|
||||
for(LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
|
||||
dependent_it != child->mDependents.end(); )
|
||||
for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
|
||||
dependent_it != child->mDependents.end(); ++dependent_it)
|
||||
{
|
||||
LLFloater* dependent = dependent_it->get();
|
||||
if (dependent)
|
||||
{
|
||||
sendChildToFront(dependent);
|
||||
//don't un-minimize dependent windows automatically
|
||||
// respect user's wishes
|
||||
//dependent->setMinimized(FALSE);
|
||||
}
|
||||
++dependent_it;
|
||||
}
|
||||
|
||||
// ...and finally bringing myself to front
|
||||
// (do this last, so that I'm left in front at end of this call)
|
||||
if( *getChildList()->begin() != child )
|
||||
if (*beginChild() != child)
|
||||
{
|
||||
sendChildToFront(child);
|
||||
}
|
||||
|
|
@ -2923,21 +2993,14 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
|
|||
|
||||
void LLFloater::setInstanceName(const std::string& name)
|
||||
{
|
||||
if (name == mInstanceName)
|
||||
return;
|
||||
if (name != mInstanceName)
|
||||
{
|
||||
llassert_always(mInstanceName.empty());
|
||||
mInstanceName = name;
|
||||
if (!mInstanceName.empty())
|
||||
{
|
||||
std::string ctrl_name = getControlName(mInstanceName, mKey);
|
||||
|
||||
// save_rect and save_visibility only apply to registered floaters
|
||||
if (mSaveRect)
|
||||
{
|
||||
mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
|
||||
mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
|
||||
mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
|
||||
}
|
||||
initRectControl();
|
||||
if (!mVisibilityControl.empty())
|
||||
{
|
||||
mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name);
|
||||
|
|
@ -2948,6 +3011,7 @@ void LLFloater::setInstanceName(const std::string& name)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloater::setKey(const LLSD& newkey)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -217,13 +217,17 @@ public:
|
|||
/*virtual*/ void setFocus( BOOL b );
|
||||
/*virtual*/ void setIsChrome(BOOL is_chrome);
|
||||
/*virtual*/ void setRect(const LLRect &rect);
|
||||
void setIsSingleInstance(BOOL is_single_instance);
|
||||
|
||||
void initFloater(const Params& p);
|
||||
|
||||
void openFloater(const LLSD& key = LLSD());
|
||||
|
||||
// If allowed, close the floater cleanly, releasing focus.
|
||||
void closeFloater(bool app_quitting = false);
|
||||
virtual void closeFloater(bool app_quitting = false);
|
||||
|
||||
// Close the floater or its host. Use when hidding or toggling a floater instance.
|
||||
virtual void closeHostedFloater();
|
||||
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
|
||||
|
|
@ -301,6 +305,7 @@ public:
|
|||
/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
|
||||
|
||||
void setFrontmost(BOOL take_focus = TRUE);
|
||||
virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE);
|
||||
|
||||
// Defaults to false.
|
||||
virtual BOOL canSaveAs() const { return FALSE; }
|
||||
|
|
@ -324,6 +329,8 @@ public:
|
|||
virtual void setDocked(bool docked, bool pop_on_undock = true);
|
||||
|
||||
virtual void setTornOff(bool torn_off) { mTornOff = torn_off; }
|
||||
bool isTornOff() {return mTornOff;}
|
||||
void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;}
|
||||
|
||||
|
||||
// Close the floater returned by getFrontmostClosableFloater() and
|
||||
|
|
@ -354,6 +361,7 @@ protected:
|
|||
|
||||
void stackWith(LLFloater& other);
|
||||
|
||||
virtual void initRectControl();
|
||||
virtual bool applyRectControl();
|
||||
bool applyDockState();
|
||||
void applyPositioning(LLFloater* other, bool on_open);
|
||||
|
|
@ -367,7 +375,6 @@ protected:
|
|||
void setInstanceName(const std::string& name);
|
||||
|
||||
virtual void bringToFront(S32 x, S32 y);
|
||||
virtual void setVisibleAndFrontmost(BOOL take_focus=TRUE);
|
||||
|
||||
void setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
|
||||
const LLRect& getExpandedRect() const { return mExpandedRect; }
|
||||
|
|
@ -441,9 +448,10 @@ private:
|
|||
LLUIString mTitle;
|
||||
LLUIString mShortTitle;
|
||||
|
||||
BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
|
||||
bool mReuseInstance; // true if we want to hide the floater when we close it instead of destroying it
|
||||
std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
|
||||
BOOL mSingleInstance; // TRUE if there is only ever one instance of the floater
|
||||
bool mReuseInstance; // true if we want to hide the floater when we close it instead of destroying it
|
||||
bool mIsReuseInitialized; // true if mReuseInstance already set from parameters
|
||||
std::string mInstanceName; // Store the instance name so we can remove ourselves from the list
|
||||
|
||||
BOOL mCanTearOff;
|
||||
BOOL mCanMinimize;
|
||||
|
|
@ -570,6 +578,7 @@ private:
|
|||
S32 mMinimizePositionVOffset;
|
||||
typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
|
||||
hidden_floaters_t mHiddenFloaters;
|
||||
LLFloater * mFrontChild;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -264,17 +264,9 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
|
|||
LLFloater* instance = findInstance(name, key);
|
||||
if (instance)
|
||||
{
|
||||
// When toggling *visibility*, close the host instead of the floater when hosted
|
||||
if (instance->getHost())
|
||||
instance->getHost()->closeFloater();
|
||||
else
|
||||
instance->closeFloater();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
instance->closeHostedFloater();
|
||||
}
|
||||
return (instance != NULL);
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -284,11 +276,7 @@ bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
|
|||
LLFloater* instance = findInstance(name, key);
|
||||
if (LLFloater::isShown(instance))
|
||||
{
|
||||
// When toggling *visibility*, close the host instead of the floater when hosted
|
||||
if (instance->getHost())
|
||||
instance->getHost()->closeFloater();
|
||||
else
|
||||
instance->closeFloater();
|
||||
instance->closeHostedFloater();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
|
@ -481,31 +469,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
|
|||
// * Also, if it is not on top, bring it forward when focus is given.
|
||||
// * Else the target floater is open, close it.
|
||||
//
|
||||
|
||||
std::string name = sdname.asString();
|
||||
LLFloater* instance = getInstance(name, key);
|
||||
|
||||
|
||||
if (!instance)
|
||||
{
|
||||
lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
|
||||
return;
|
||||
}
|
||||
else if (instance->isMinimized())
|
||||
|
||||
// If hosted, we need to take that into account
|
||||
LLFloater* host = instance->getHost();
|
||||
|
||||
if (host)
|
||||
{
|
||||
instance->setMinimized(FALSE);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->isShown())
|
||||
{
|
||||
instance->openFloater(key);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->isFrontmost())
|
||||
{
|
||||
instance->setVisibleAndFrontmost();
|
||||
if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
|
||||
{
|
||||
host->setMinimized(FALSE);
|
||||
instance->openFloater(key);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->getVisible())
|
||||
{
|
||||
instance->openFloater(key);
|
||||
instance->setVisibleAndFrontmost();
|
||||
instance->setFocus(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->closeHostedFloater();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->closeFloater();
|
||||
if (instance->isMinimized())
|
||||
{
|
||||
instance->setMinimized(FALSE);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->isShown())
|
||||
{
|
||||
instance->openFloater(key);
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else if (!instance->isFrontmost())
|
||||
{
|
||||
instance->setVisibleAndFrontmost();
|
||||
}
|
||||
else
|
||||
{
|
||||
instance->closeHostedFloater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -39,19 +39,16 @@
|
|||
|
||||
#include "lluictrl.h"
|
||||
#include "v4color.h"
|
||||
#include "lldarray.h"
|
||||
#include "stdenums.h"
|
||||
#include "lldepthstack.h"
|
||||
#include "lleditmenuhandler.h"
|
||||
#include "llfontgl.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "lltooldraganddrop.h"
|
||||
#include "llviewertexture.h"
|
||||
|
||||
class LLFolderViewEventListener;
|
||||
class LLFolderViewModelInterface;
|
||||
class LLFolderViewFolder;
|
||||
class LLFolderViewItem;
|
||||
class LLInventoryModel;
|
||||
class LLFolderViewFilter;
|
||||
class LLPanel;
|
||||
class LLLineEditor;
|
||||
class LLMenuGL;
|
||||
|
|
@ -90,136 +87,104 @@ public:
|
|||
struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
|
||||
{
|
||||
Mandatory<LLPanel*> parent_panel;
|
||||
Optional<LLUUID> task_id;
|
||||
Optional<std::string> title;
|
||||
Optional<bool> use_label_suffix,
|
||||
allow_multiselect,
|
||||
show_empty_message,
|
||||
show_load_status,
|
||||
use_ellipses;
|
||||
use_ellipses,
|
||||
show_item_link_overlays;
|
||||
Mandatory<LLFolderViewModelInterface*> view_model;
|
||||
Mandatory<std::string> options_menu;
|
||||
|
||||
|
||||
Params();
|
||||
};
|
||||
|
||||
friend class LLFolderViewScrollContainer;
|
||||
typedef std::deque<LLFolderViewItem*> selected_items_t;
|
||||
|
||||
LLFolderView(const Params&);
|
||||
virtual ~LLFolderView( void );
|
||||
|
||||
virtual BOOL canFocusChildren() const;
|
||||
|
||||
virtual const LLFolderView* getRoot() const { return this; }
|
||||
virtual LLFolderView* getRoot() { return this; }
|
||||
|
||||
// FolderViews default to sort by name. This will change that,
|
||||
// and resort the items if necessary.
|
||||
void setSortOrder(U32 order);
|
||||
void setFilterPermMask(PermissionMask filter_perm_mask);
|
||||
|
||||
LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
|
||||
const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; }
|
||||
|
||||
typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
|
||||
void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
|
||||
void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
|
||||
|
||||
// filter is never null
|
||||
LLInventoryFilter* getFilter();
|
||||
const std::string getFilterSubString(BOOL trim = FALSE);
|
||||
U32 getFilterObjectTypes() const;
|
||||
PermissionMask getFilterPermissions() const;
|
||||
// *NOTE: use getFilter()->getShowFolderState();
|
||||
//LLInventoryFilter::EFolderShow getShowFolderState();
|
||||
U32 getSortOrder() const;
|
||||
BOOL isFilterModified();
|
||||
|
||||
bool getAllowMultiSelect() { return mAllowMultiSelect; }
|
||||
|
||||
// Close all folders in the view
|
||||
void closeAllFolders();
|
||||
void openTopLevelFolders();
|
||||
|
||||
virtual void toggleOpen() {};
|
||||
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
|
||||
virtual BOOL addFolder( LLFolderViewFolder* folder);
|
||||
virtual void addFolder( LLFolderViewFolder* folder);
|
||||
|
||||
// Find width and height of this object and its children. Also
|
||||
// makes sure that this view and its children are the right size.
|
||||
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
|
||||
virtual S32 arrange( S32* width, S32* height );
|
||||
virtual S32 getItemHeight();
|
||||
|
||||
void arrangeAll() { mArrangeGeneration++; }
|
||||
S32 getArrangeGeneration() { return mArrangeGeneration; }
|
||||
|
||||
// Apply filters to control visibility of inventory items
|
||||
virtual void filter( LLInventoryFilter& filter);
|
||||
// applies filters to control visibility of items
|
||||
virtual void filter( LLFolderViewFilter& filter);
|
||||
|
||||
// Get the last selected item
|
||||
virtual LLFolderViewItem* getCurSelectedItem( void );
|
||||
selected_items_t& getSelectedItems( void );
|
||||
|
||||
// Record the selected item and pass it down the hierarchy.
|
||||
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
|
||||
BOOL take_keyboard_focus);
|
||||
BOOL take_keyboard_focus = TRUE);
|
||||
|
||||
// Used by menu callbacks
|
||||
void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
|
||||
// Called once a frame to update the selection if mSelectThisID has been set
|
||||
void updateSelection();
|
||||
|
||||
// This method is used to toggle the selection of an item.
|
||||
// Walks children and keeps track of selected objects.
|
||||
// This method is used to toggle the selection of an item. Walks
|
||||
// children, and keeps track of selected objects.
|
||||
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
|
||||
|
||||
virtual std::set<LLUUID> getSelectionList() const;
|
||||
virtual std::set<LLFolderViewItem*> getSelectionList() const;
|
||||
|
||||
// Make sure if ancestor is selected, descendents are not
|
||||
// Make sure if ancestor is selected, descendants are not
|
||||
void sanitizeSelection();
|
||||
void clearSelection();
|
||||
virtual void clearSelection();
|
||||
void addToSelectionList(LLFolderViewItem* item);
|
||||
void removeFromSelectionList(LLFolderViewItem* item);
|
||||
|
||||
BOOL startDrag(LLToolDragAndDrop::ESource source);
|
||||
bool startDrag();
|
||||
void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
|
||||
void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
|
||||
LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
|
||||
|
||||
// Deletion functionality
|
||||
void removeSelectedItems();
|
||||
static void removeCutItems();
|
||||
|
||||
// Open the selected item
|
||||
void openSelectedItems( void );
|
||||
void propertiesSelectedItems( void );
|
||||
|
||||
// Change the folder type
|
||||
void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
|
||||
|
||||
void autoOpenItem(LLFolderViewFolder* item);
|
||||
void closeAutoOpenedFolders();
|
||||
BOOL autoOpenTest(LLFolderViewFolder* item);
|
||||
BOOL isOpen() const { return TRUE; } // root folder always open
|
||||
|
||||
// Copy & paste
|
||||
virtual void copy();
|
||||
virtual BOOL canCopy() const;
|
||||
virtual void copy();
|
||||
|
||||
virtual void cut();
|
||||
virtual BOOL canCut() const;
|
||||
virtual void cut();
|
||||
|
||||
virtual void paste();
|
||||
virtual BOOL canPaste() const;
|
||||
|
||||
virtual void doDelete();
|
||||
virtual BOOL canDoDelete() const;
|
||||
virtual void paste();
|
||||
|
||||
LLFolderViewItem* getNextUnselectedItem();
|
||||
|
||||
|
||||
// Public rename functionality - can only start the process
|
||||
void startRenamingSelectedItem( void );
|
||||
|
||||
// These functions were used when there was only one folderview,
|
||||
// and relied on that concept. This functionality is now handled
|
||||
// by the listeners and the lldraganddroptool.
|
||||
//LLFolderViewItem* getMovingItem() { return mMovingItem; }
|
||||
//void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; }
|
||||
//void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
|
||||
//void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
|
||||
|
||||
// LLView functionality
|
||||
///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
|
||||
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
|
||||
|
|
@ -250,16 +215,9 @@ public:
|
|||
BOOL getShowSingleSelection() { return mShowSingleSelection; }
|
||||
F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
|
||||
bool getUseEllipses() { return mUseEllipses; }
|
||||
S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
|
||||
|
||||
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
|
||||
void removeItemID(const LLUUID& id);
|
||||
LLFolderViewItem* getItemByID(const LLUUID& id);
|
||||
LLFolderViewFolder* getFolderByID(const LLUUID& id);
|
||||
|
||||
bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
|
||||
|
||||
void doIdle(); // Real idle routine
|
||||
static void idle(void* user_data); // static glue to doIdle()
|
||||
void update(); // needs to be called periodically (e.g. once per frame)
|
||||
|
||||
BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
|
||||
BOOL needsAutoRename() { return mNeedsAutoRename; }
|
||||
|
|
@ -267,9 +225,9 @@ public:
|
|||
void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
|
||||
void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
|
||||
|
||||
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
|
||||
bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
|
||||
|
||||
BOOL getDebugFilters() { return mDebugFilters; }
|
||||
void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
|
||||
|
||||
LLPanel* getParentPanel() { return mParentPanel; }
|
||||
// DEBUG only
|
||||
|
|
@ -298,18 +256,15 @@ protected:
|
|||
|
||||
BOOL addNoOptions(LLMenuGL* menu) const;
|
||||
|
||||
void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
|
||||
|
||||
protected:
|
||||
LLHandle<LLView> mPopupMenuHandle;
|
||||
|
||||
typedef std::deque<LLFolderViewItem*> selected_items_t;
|
||||
selected_items_t mSelectedItems;
|
||||
BOOL mKeyboardSelection;
|
||||
BOOL mAllowMultiSelect;
|
||||
BOOL mShowEmptyMessage;
|
||||
BOOL mShowFolderHierarchy;
|
||||
LLUUID mSourceID;
|
||||
|
||||
// Renaming variables and methods
|
||||
LLFolderViewItem* mRenameItem; // The item currently being renamed
|
||||
|
|
@ -322,15 +277,13 @@ protected:
|
|||
BOOL mAutoSelectOverride;
|
||||
BOOL mNeedsAutoRename;
|
||||
bool mUseLabelSuffix;
|
||||
bool mShowItemLinkOverlays;
|
||||
|
||||
BOOL mDebugFilters;
|
||||
U32 mSortOrder;
|
||||
LLDepthStack<LLFolderViewFolder> mAutoOpenItems;
|
||||
LLFolderViewFolder* mAutoOpenCandidate;
|
||||
LLFrameTimer mAutoOpenTimer;
|
||||
LLFrameTimer mSearchTimer;
|
||||
std::string mSearchString;
|
||||
LLInventoryFilter* mFilter;
|
||||
BOOL mShowSelectionContext;
|
||||
BOOL mShowSingleSelection;
|
||||
LLFrameTimer mMultiSelectionFadeTimer;
|
||||
|
|
@ -340,13 +293,11 @@ protected:
|
|||
signal_t mReshapeSignal;
|
||||
S32 mSignalSelectCallback;
|
||||
S32 mMinWidth;
|
||||
S32 mRunningHeight;
|
||||
std::map<LLUUID, LLFolderViewItem*> mItemMap;
|
||||
BOOL mDragAndDropThisFrame;
|
||||
|
||||
LLUUID mSelectThisID; // if non null, select this item
|
||||
|
||||
LLPanel* mParentPanel;
|
||||
|
||||
LLFolderViewModelInterface* mViewModel;
|
||||
|
||||
/**
|
||||
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
|
||||
|
|
@ -367,11 +318,82 @@ public:
|
|||
|
||||
};
|
||||
|
||||
bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
|
||||
bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b);
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFolderViewFunctor
|
||||
//
|
||||
// Simple abstract base class for applying a functor to folders and
|
||||
// items in a folder view hierarchy. This is suboptimal for algorithms
|
||||
// that only work folders or only work on items, but I'll worry about
|
||||
// that later when it's determined to be too slow.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFolderViewFunctor
|
||||
{
|
||||
public:
|
||||
virtual ~LLFolderViewFunctor() {}
|
||||
virtual void doFolder(LLFolderViewFolder* folder) = 0;
|
||||
virtual void doItem(LLFolderViewItem* item) = 0;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLSelectFirstFilteredItem
|
||||
//
|
||||
// This will select the first *item* found in the hierarchy. If no item can be
|
||||
// selected, the first matching folder will.
|
||||
// Since doFolder() is done first but we prioritize item selection, we let the
|
||||
// first filtered folder set the selection and raise a folder flag.
|
||||
// The selection might be overridden by the first filtered item in doItem()
|
||||
// which checks an item flag. Since doFolder() checks the item flag too, the first
|
||||
// item will still be selected if items were to be done first and folders second.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLSelectFirstFilteredItem : public LLFolderViewFunctor
|
||||
{
|
||||
public:
|
||||
LLSelectFirstFilteredItem() : mItemSelected(FALSE), mFolderSelected(FALSE) {}
|
||||
virtual ~LLSelectFirstFilteredItem() {}
|
||||
virtual void doFolder(LLFolderViewFolder* folder);
|
||||
virtual void doItem(LLFolderViewItem* item);
|
||||
BOOL wasItemSelected() { return mItemSelected || mFolderSelected; }
|
||||
protected:
|
||||
BOOL mItemSelected;
|
||||
BOOL mFolderSelected;
|
||||
};
|
||||
|
||||
class LLOpenFilteredFolders : public LLFolderViewFunctor
|
||||
{
|
||||
public:
|
||||
LLOpenFilteredFolders() {}
|
||||
virtual ~LLOpenFilteredFolders() {}
|
||||
virtual void doFolder(LLFolderViewFolder* folder);
|
||||
virtual void doItem(LLFolderViewItem* item);
|
||||
};
|
||||
|
||||
class LLSaveFolderState : public LLFolderViewFunctor
|
||||
{
|
||||
public:
|
||||
LLSaveFolderState() : mApply(FALSE) {}
|
||||
virtual ~LLSaveFolderState() {}
|
||||
virtual void doFolder(LLFolderViewFolder* folder);
|
||||
virtual void doItem(LLFolderViewItem* item) {}
|
||||
void setApply(BOOL apply);
|
||||
void clearOpenFolders() { mOpenFolders.clear(); }
|
||||
protected:
|
||||
std::set<LLUUID> mOpenFolders;
|
||||
BOOL mApply;
|
||||
};
|
||||
|
||||
class LLOpenFoldersWithSelection : public LLFolderViewFunctor
|
||||
{
|
||||
public:
|
||||
LLOpenFoldersWithSelection() {}
|
||||
virtual ~LLOpenFoldersWithSelection() {}
|
||||
virtual void doFolder(LLFolderViewFolder* folder);
|
||||
virtual void doItem(LLFolderViewItem* item);
|
||||
};
|
||||
|
||||
// Flags for buildContextMenu()
|
||||
const U32 SUPPRESS_OPEN_ITEM = 0x1;
|
||||
const U32 FIRST_SELECTED_ITEM = 0x2;
|
||||
const U32 ITEM_IN_MULTI_SELECTION = 0x4;
|
||||
|
||||
#endif // LL_LLFOLDERVIEW_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -26,55 +26,16 @@
|
|||
#ifndef LLFOLDERVIEWITEM_H
|
||||
#define LLFOLDERVIEWITEM_H
|
||||
|
||||
#include "llflashtimer.h"
|
||||
#include "llview.h"
|
||||
#include "lldarray.h" // *TODO: Eliminate, forward declare
|
||||
#include "lluiimage.h"
|
||||
|
||||
class LLFontGL;
|
||||
class LLFolderView;
|
||||
class LLFolderViewEventListener;
|
||||
class LLFolderViewModelItem;
|
||||
class LLFolderViewFolder;
|
||||
class LLFolderViewFunctor;
|
||||
class LLFolderViewItem;
|
||||
class LLFolderViewListenerFunctor;
|
||||
class LLInventoryFilter;
|
||||
class LLMenuGL;
|
||||
class LLUIImage;
|
||||
class LLViewerInventoryItem;
|
||||
|
||||
// These are grouping of inventory types.
|
||||
// Order matters when sorting system folders to the top.
|
||||
enum EInventorySortGroup
|
||||
{
|
||||
SG_SYSTEM_FOLDER,
|
||||
SG_TRASH_FOLDER,
|
||||
SG_NORMAL_FOLDER,
|
||||
SG_ITEM
|
||||
};
|
||||
|
||||
// *TODO: do we really need one sort object per folder?
|
||||
// can we just have one of these per LLFolderView ?
|
||||
class LLInventorySort
|
||||
{
|
||||
public:
|
||||
LLInventorySort()
|
||||
: mSortOrder(0),
|
||||
mByDate(false),
|
||||
mSystemToTop(false),
|
||||
mFoldersByName(false) { }
|
||||
|
||||
// Returns true if order has changed
|
||||
bool updateSort(U32 order);
|
||||
U32 getSort() { return mSortOrder; }
|
||||
bool isByDate() { return mByDate; }
|
||||
|
||||
bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
|
||||
private:
|
||||
U32 mSortOrder;
|
||||
bool mByDate;
|
||||
bool mSystemToTop;
|
||||
bool mFoldersByName;
|
||||
};
|
||||
class LLFolderViewFilter;
|
||||
class LLFolderViewModelInterface;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFolderViewItem
|
||||
|
|
@ -86,134 +47,130 @@ private:
|
|||
class LLFolderViewItem : public LLView
|
||||
{
|
||||
public:
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<LLUIImage*> icon;
|
||||
Optional<LLUIImage*> icon_open; // used for folders
|
||||
Optional<LLUIImage*> icon_overlay; // for links
|
||||
Optional<LLFolderView*> root;
|
||||
Mandatory<LLFolderViewEventListener*> listener;
|
||||
Optional<LLUIImage*> folder_arrow_image,
|
||||
selection_image;
|
||||
Mandatory<LLFolderView*> root;
|
||||
Mandatory<LLFolderViewModelItem*> listener;
|
||||
|
||||
Optional<LLUIImage*> folder_arrow_image;
|
||||
Optional<S32> folder_indentation; // pixels
|
||||
Optional<LLUIImage*> selection_image;
|
||||
Optional<S32> item_height; // pixels
|
||||
Optional<S32> item_top_pad; // pixels
|
||||
Optional<S32> folder_indentation, // pixels
|
||||
item_height,
|
||||
item_top_pad;
|
||||
|
||||
Optional<S32> creation_date; //UTC seconds
|
||||
Optional<time_t> creation_date;
|
||||
Optional<bool> allow_open;
|
||||
|
||||
Optional<LLUIColor> font_color;
|
||||
Optional<LLUIColor> font_highlight_color;
|
||||
|
||||
Optional<S32> left_pad,
|
||||
icon_pad,
|
||||
icon_width,
|
||||
text_pad,
|
||||
text_pad_right,
|
||||
arrow_size,
|
||||
max_folder_item_overlap;
|
||||
Params();
|
||||
};
|
||||
|
||||
// layout constants
|
||||
static const S32 LEFT_PAD = 5;
|
||||
// LEFT_INDENTATION is set via folder_indentation above
|
||||
static const S32 ICON_PAD = 2;
|
||||
static const S32 ICON_WIDTH = 16;
|
||||
static const S32 TEXT_PAD = 1;
|
||||
static const S32 TEXT_PAD_RIGHT = 4;
|
||||
static const S32 ARROW_SIZE = 12;
|
||||
static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
|
||||
|
||||
static const S32 DEFAULT_LABEL_PADDING_RIGHT = 4;
|
||||
// animation parameters
|
||||
static const F32 FOLDER_CLOSE_TIME_CONSTANT;
|
||||
static const F32 FOLDER_OPEN_TIME_CONSTANT;
|
||||
|
||||
// Mostly for debugging printout purposes.
|
||||
const std::string& getSearchableLabel() { return mSearchableLabel; }
|
||||
|
||||
BOOL isLoading() const { return mIsLoading; }
|
||||
|
||||
private:
|
||||
BOOL mIsSelected;
|
||||
static const F32 FOLDER_CLOSE_TIME_CONSTANT,
|
||||
FOLDER_OPEN_TIME_CONSTANT;
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
friend class LLFolderViewEventListener;
|
||||
friend class LLFolderViewModelItem;
|
||||
|
||||
LLFolderViewItem(const Params& p);
|
||||
|
||||
std::string mLabel;
|
||||
std::string mSearchableLabel;
|
||||
S32 mLabelWidth;
|
||||
bool mLabelWidthDirty;
|
||||
time_t mCreationDate;
|
||||
S32 mLabelPaddingRight;
|
||||
LLFolderViewFolder* mParentFolder;
|
||||
LLFolderViewEventListener* mListener;
|
||||
BOOL mIsCurSelection;
|
||||
BOOL mSelectPending;
|
||||
LLPointer<LLFolderViewModelItem> mViewModelItem;
|
||||
LLFontGL::StyleFlags mLabelStyle;
|
||||
std::string mLabelSuffix;
|
||||
LLUIImagePtr mIcon;
|
||||
std::string mStatusText;
|
||||
LLUIImagePtr mIconOpen;
|
||||
LLUIImagePtr mIconOverlay;
|
||||
BOOL mHasVisibleChildren;
|
||||
LLUIImagePtr mIcon,
|
||||
mIconOpen,
|
||||
mIconOverlay;
|
||||
S32 mLocalIndentation;
|
||||
S32 mIndentation;
|
||||
S32 mItemHeight;
|
||||
BOOL mPassedFilter;
|
||||
S32 mLastFilterGeneration;
|
||||
std::string::size_type mStringMatchOffset;
|
||||
S32 mDragStartX,
|
||||
mDragStartY;
|
||||
|
||||
S32 mLeftPad,
|
||||
mIconPad,
|
||||
mIconWidth,
|
||||
mTextPad,
|
||||
mTextPadRight,
|
||||
mArrowSize,
|
||||
mMaxFolderItemOverlap;
|
||||
|
||||
F32 mControlLabelRotation;
|
||||
LLFolderView* mRoot;
|
||||
BOOL mDragAndDropTarget;
|
||||
BOOL mIsLoading;
|
||||
LLTimer mTimeSinceRequestStart;
|
||||
bool mShowLoadStatus;
|
||||
bool mIsMouseOverTitle;
|
||||
bool mHasVisibleChildren,
|
||||
mIsCurSelection,
|
||||
mDragAndDropTarget,
|
||||
mIsMouseOverTitle,
|
||||
mAllowOpen,
|
||||
mSelectPending;
|
||||
|
||||
LLUIColor mFontColor;
|
||||
LLUIColor mFontHighlightColor;
|
||||
|
||||
// helper function to change the selection from the root.
|
||||
void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
|
||||
// For now assuming all colors are the same in derived classes.
|
||||
static bool sColorSetInitialized;
|
||||
static LLUIColor sFgColor;
|
||||
static LLUIColor sFgDisabledColor;
|
||||
static LLUIColor sHighlightBgColor;
|
||||
static LLUIColor sFlashBgColor;
|
||||
static LLUIColor sFocusOutlineColor;
|
||||
static LLUIColor sMouseOverColor;
|
||||
static LLUIColor sFilterBGColor;
|
||||
static LLUIColor sFilterTextColor;
|
||||
static LLUIColor sSuffixColor;
|
||||
static LLUIColor sSearchStatusColor;
|
||||
|
||||
// this is an internal method used for adding items to folders. A
|
||||
// no-op at this level, but reimplemented in derived classes.
|
||||
virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
|
||||
virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
|
||||
virtual void addItem(LLFolderViewItem*) { }
|
||||
virtual void addFolder(LLFolderViewFolder*) { }
|
||||
virtual bool isHighlightAllowed();
|
||||
virtual bool isHighlightActive();
|
||||
virtual bool isFlashing() { return false; }
|
||||
virtual void setFlashState(bool) { }
|
||||
|
||||
static LLFontGL* getLabelFontForStyle(U8 style);
|
||||
|
||||
virtual void setCreationDate(time_t creation_date_utc) { mCreationDate = creation_date_utc; }
|
||||
BOOL mIsSelected;
|
||||
|
||||
public:
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
|
||||
BOOL postBuild();
|
||||
|
||||
// This function clears the currently selected item, and records
|
||||
// the specified selected item appropriately for display and use
|
||||
// in the UI. If open is TRUE, then folders are opened up along
|
||||
// the way to the selection.
|
||||
void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
|
||||
BOOL take_keyboard_focus = TRUE);
|
||||
virtual void openItem( void );
|
||||
|
||||
// This function is called when the folder view is dirty. It's
|
||||
// implemented here but called by derived classes when folding the
|
||||
// views.
|
||||
void arrangeFromRoot();
|
||||
void filterFromRoot( void );
|
||||
|
||||
void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
|
||||
|
||||
virtual ~LLFolderViewItem( void );
|
||||
|
||||
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
|
||||
enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
|
||||
virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
|
||||
|
||||
virtual EInventorySortGroup getSortGroup() const;
|
||||
virtual void addToFolder(LLFolderViewFolder* folder);
|
||||
|
||||
// Finds width and height of this object and it's children. Also
|
||||
// makes sure that this view and it's children are the right size.
|
||||
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
|
||||
virtual S32 arrange( S32* width, S32* height );
|
||||
virtual S32 getItemHeight();
|
||||
|
||||
// applies filters to control visibility of inventory items
|
||||
virtual void filter( LLInventoryFilter& filter);
|
||||
|
||||
// updates filter serial number and optionally propagated value up to root
|
||||
S32 getLastFilterGeneration() { return mLastFilterGeneration; }
|
||||
|
||||
virtual void dirtyFilter();
|
||||
virtual S32 getLabelXPos();
|
||||
S32 getIconPad();
|
||||
S32 getTextPad();
|
||||
|
||||
// If 'selection' is 'this' then note that otherwise ignore.
|
||||
// Returns TRUE if this item ends up being selected.
|
||||
|
|
@ -231,7 +188,7 @@ public:
|
|||
virtual void selectItem();
|
||||
|
||||
// gets multiple-element selection
|
||||
virtual std::set<LLUUID> getSelectionList() const;
|
||||
virtual std::set<LLFolderViewItem*> getSelectionList() const;
|
||||
|
||||
// Returns true is this object and all of its children can be removed (deleted by user)
|
||||
virtual BOOL isRemovable();
|
||||
|
|
@ -253,74 +210,54 @@ public:
|
|||
|
||||
BOOL hasVisibleChildren() { return mHasVisibleChildren; }
|
||||
|
||||
void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
|
||||
|
||||
// Call through to the viewed object and return true if it can be
|
||||
// removed. Returns true if it's removed.
|
||||
//virtual BOOL removeRecursively(BOOL single_item);
|
||||
BOOL remove();
|
||||
|
||||
// Build an appropriate context menu for the item. Flags unused.
|
||||
void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
void buildContextMenu(class LLMenuGL& menu, U32 flags);
|
||||
|
||||
// This method returns the actual name of the thing being
|
||||
// viewed. This method will ask the viewed object itself.
|
||||
const std::string& getName( void ) const;
|
||||
|
||||
const std::string& getSearchableLabel( void ) const;
|
||||
|
||||
// This method returns the label displayed on the view. This
|
||||
// method was primarily added to allow sorting on the folder
|
||||
// contents possible before the entire view has been constructed.
|
||||
const std::string& getLabel() const { return mLabel; }
|
||||
|
||||
// Used for sorting, like getLabel() above.
|
||||
virtual time_t getCreationDate() const { return mCreationDate; }
|
||||
|
||||
LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
|
||||
const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
|
||||
|
||||
void setParentFolder(LLFolderViewFolder* parent) { mParentFolder = parent; }
|
||||
|
||||
LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
|
||||
LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
|
||||
|
||||
const LLFolderViewEventListener* getListener( void ) const { return mListener; }
|
||||
LLFolderViewEventListener* getListener( void ) { return mListener; }
|
||||
|
||||
// Gets the inventory item if it exists (null otherwise)
|
||||
LLViewerInventoryItem * getInventoryItem(void);
|
||||
const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; }
|
||||
LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; }
|
||||
|
||||
const LLFolderViewModelInterface* getFolderViewModel( void ) const;
|
||||
LLFolderViewModelInterface* getFolderViewModel( void );
|
||||
|
||||
// just rename the object.
|
||||
void rename(const std::string& new_name);
|
||||
|
||||
// open
|
||||
virtual void openItem( void );
|
||||
virtual void preview(void);
|
||||
|
||||
// Show children (unfortunate that this is called "open")
|
||||
// Show children
|
||||
virtual void setOpen(BOOL open = TRUE) {};
|
||||
|
||||
virtual BOOL isOpen() const { return FALSE; }
|
||||
|
||||
virtual LLFolderView* getRoot();
|
||||
virtual const LLFolderView* getRoot() const;
|
||||
BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
|
||||
S32 getIndentation() { return mIndentation; }
|
||||
|
||||
virtual BOOL potentiallyVisible(); // do we know for a fact that this item won't be displayed?
|
||||
virtual BOOL potentiallyFiltered(); // do we know for a fact that this item has been filtered out?
|
||||
|
||||
virtual BOOL getFiltered();
|
||||
virtual BOOL getFiltered(S32 filter_generation);
|
||||
virtual void setFiltered(BOOL filtered, S32 filter_generation);
|
||||
|
||||
// change the icon
|
||||
void setIcon(LLUIImagePtr icon);
|
||||
virtual BOOL passedFilter(S32 filter_generation = -1);
|
||||
|
||||
// refresh information from the object being viewed.
|
||||
void refreshFromListener();
|
||||
virtual void refresh();
|
||||
|
||||
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
|
||||
|
||||
// LLView functionality
|
||||
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
|
||||
|
|
@ -330,25 +267,23 @@ public:
|
|||
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
||||
virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
|
||||
//virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return LLView::findChildView(name, recurse); }
|
||||
|
||||
// virtual void handleDropped();
|
||||
virtual void draw();
|
||||
void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
|
||||
void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
|
||||
void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
|
||||
private:
|
||||
static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
|
||||
};
|
||||
|
||||
|
||||
// function used for sorting.
|
||||
typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFolderViewFolder
|
||||
//
|
||||
|
|
@ -363,33 +298,26 @@ protected:
|
|||
LLFolderViewFolder( const LLFolderViewItem::Params& );
|
||||
friend class LLUICtrlFactory;
|
||||
|
||||
public:
|
||||
typedef enum e_trash
|
||||
{
|
||||
UNKNOWN, TRASH, NOT_TRASH
|
||||
} ETrash;
|
||||
void updateLabelRotation();
|
||||
virtual bool isCollapsed() { return FALSE; }
|
||||
|
||||
public:
|
||||
typedef std::list<LLFolderViewItem*> items_t;
|
||||
typedef std::list<LLFolderViewFolder*> folders_t;
|
||||
|
||||
protected:
|
||||
items_t mItems;
|
||||
folders_t mFolders;
|
||||
LLInventorySort mSortFunction;
|
||||
|
||||
BOOL mIsOpen;
|
||||
BOOL mExpanderHighlighted;
|
||||
F32 mCurHeight;
|
||||
F32 mTargetHeight;
|
||||
F32 mAutoOpenCountdown;
|
||||
time_t mSubtreeCreationDate;
|
||||
mutable ETrash mAmTrash;
|
||||
S32 mLastArrangeGeneration;
|
||||
S32 mLastCalculatedWidth;
|
||||
S32 mCompletedFilterGeneration;
|
||||
S32 mMostFilteredDescendantGeneration;
|
||||
bool mNeedsSort;
|
||||
bool mPassedFolderFilter;
|
||||
|
||||
public:
|
||||
typedef enum e_recurse_type
|
||||
|
|
@ -403,48 +331,25 @@ public:
|
|||
|
||||
virtual ~LLFolderViewFolder( void );
|
||||
|
||||
virtual BOOL potentiallyVisible();
|
||||
|
||||
LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
|
||||
LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
|
||||
|
||||
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
|
||||
virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
|
||||
virtual void addToFolder(LLFolderViewFolder* folder);
|
||||
|
||||
// Finds width and height of this object and it's children. Also
|
||||
// makes sure that this view and it's children are the right size.
|
||||
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
|
||||
virtual S32 arrange( S32* width, S32* height );
|
||||
|
||||
BOOL needsArrange();
|
||||
void requestSort();
|
||||
|
||||
// Returns the sort group (system, trash, folder) for this folder.
|
||||
virtual EInventorySortGroup getSortGroup() const;
|
||||
|
||||
virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
|
||||
virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
|
||||
|
||||
BOOL hasFilteredDescendants(S32 filter_generation);
|
||||
BOOL hasFilteredDescendants();
|
||||
|
||||
// applies filters to control visibility of inventory items
|
||||
virtual void filter( LLInventoryFilter& filter);
|
||||
virtual void setFiltered(BOOL filtered, S32 filter_generation);
|
||||
virtual BOOL getFiltered();
|
||||
virtual BOOL getFiltered(S32 filter_generation);
|
||||
|
||||
virtual void dirtyFilter();
|
||||
|
||||
// folder-specific filtering (filter status propagates top down instead of bottom up)
|
||||
void filterFolder(LLInventoryFilter& filter);
|
||||
void setFilteredFolder(bool filtered, S32 filter_generation);
|
||||
bool getFilteredFolder(S32 filter_generation);
|
||||
bool descendantsPassedFilter(S32 filter_generation = -1);
|
||||
|
||||
// Passes selection information on to children and record
|
||||
// selection information if necessary.
|
||||
// Returns TRUE if this object (or a child) ends up being selected.
|
||||
// If 'openitem' is TRUE then folders are opened up along the way to the selection.
|
||||
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
|
||||
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus = TRUE);
|
||||
|
||||
// This method is used to change the selection of an item.
|
||||
// Recursively traverse all children; if 'selection' is 'this' then change
|
||||
|
|
@ -464,31 +369,13 @@ public:
|
|||
// destroys this folder, and all children
|
||||
virtual void destroyView();
|
||||
|
||||
// If this folder can be removed, remove all children that can be
|
||||
// removed, return TRUE if this is empty after the operation and
|
||||
// it's viewed folder object can be removed.
|
||||
//virtual BOOL removeRecursively(BOOL single_item);
|
||||
//virtual BOOL remove();
|
||||
|
||||
// remove the specified item (and any children) if
|
||||
// possible. Return TRUE if the item was deleted.
|
||||
BOOL removeItem(LLFolderViewItem* item);
|
||||
|
||||
// simply remove the view (and any children) Don't bother telling
|
||||
// the listeners.
|
||||
void removeView(LLFolderViewItem* item);
|
||||
|
||||
// extractItem() removes the specified item from the folder, but
|
||||
// doesn't delete it.
|
||||
void extractItem( LLFolderViewItem* item );
|
||||
virtual void extractItem( LLFolderViewItem* item );
|
||||
|
||||
// This function is called by a child that needs to be resorted.
|
||||
void resort(LLFolderViewItem* item);
|
||||
|
||||
void setItemSortOrder(U32 ordering);
|
||||
void sortBy(U32);
|
||||
//BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
|
||||
|
||||
void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
|
||||
|
||||
// folders can be opened. This will usually be called by internal
|
||||
|
|
@ -499,8 +386,7 @@ public:
|
|||
virtual void setOpen(BOOL openitem = TRUE);
|
||||
|
||||
// Called when a child is refreshed.
|
||||
// don't rearrange child folder contents unless explicitly requested
|
||||
virtual void requestArrange(BOOL include_descendants = FALSE);
|
||||
virtual void requestArrange();
|
||||
|
||||
// internal method which doesn't update the entire view. This
|
||||
// method was written because the list iterators destroy the state
|
||||
|
|
@ -513,65 +399,60 @@ public:
|
|||
|
||||
// special case if an object is dropped on the child.
|
||||
BOOL handleDragAndDropFromChild(MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
|
||||
void applyFunctorRecursively(LLFolderViewFunctor& functor);
|
||||
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
|
||||
|
||||
// Just apply this functor to the folder's immediate children.
|
||||
void applyFunctorToChildren(LLFolderViewFunctor& functor);
|
||||
// apply this functor to the folder's descendants.
|
||||
void applyFunctorRecursively(LLFolderViewFunctor& functor);
|
||||
|
||||
virtual void openItem( void );
|
||||
virtual BOOL addItem(LLFolderViewItem* item);
|
||||
virtual BOOL addFolder( LLFolderViewFolder* folder);
|
||||
|
||||
// LLView functionality
|
||||
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
BOOL handleDragAndDropToThisFolder(MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
virtual void draw();
|
||||
|
||||
time_t getCreationDate() const;
|
||||
bool isTrash() const;
|
||||
|
||||
folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
|
||||
folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
|
||||
folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
|
||||
folders_t::iterator getFoldersEnd() { return mFolders.end(); }
|
||||
folders_t::size_type getFoldersCount() const { return mFolders.size(); }
|
||||
|
||||
items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
|
||||
items_t::const_iterator getItemsEnd() const { return mItems.end(); }
|
||||
items_t::size_type getItemsCount() const { return mItems.size(); }
|
||||
|
||||
LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
|
||||
void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
|
||||
|
||||
// internal functions for tracking folders and items separately
|
||||
// use addToFolder() virtual method to ensure folders are always added to mFolders
|
||||
// and not mItems
|
||||
void addItem(LLFolderViewItem* item);
|
||||
void addFolder( LLFolderViewFolder* folder);
|
||||
|
||||
//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
|
||||
template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
|
||||
template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFolderViewListenerFunctor
|
||||
//
|
||||
// This simple abstract base class can be used to applied to all
|
||||
// listeners in a hierarchy.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLFolderViewListenerFunctor
|
||||
{
|
||||
public:
|
||||
virtual ~LLFolderViewListenerFunctor() {}
|
||||
virtual void operator()(LLFolderViewEventListener* listener) = 0;
|
||||
};
|
||||
|
||||
#endif // LLFOLDERVIEWITEM_H
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* @file llfolderviewmodel.cpp
|
||||
* @brief Implementation of the view model collection of classes.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llfolderviewmodel.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
|
||||
{
|
||||
return item->getSortVersion() < mTargetSortVersion;
|
||||
}
|
||||
|
||||
std::string LLFolderViewModelCommon::getStatusText()
|
||||
{
|
||||
if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())
|
||||
{
|
||||
return LLTrans::getString("Searching");
|
||||
}
|
||||
else
|
||||
{
|
||||
return getFilter().getEmptyLookupMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderViewModelCommon::filter()
|
||||
{
|
||||
getFilter().setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
|
||||
mFolderView->getViewModelItem()->filter(getFilter());
|
||||
}
|
||||
|
||||
bool LLFolderViewModelItemCommon::hasFilterStringMatch()
|
||||
{
|
||||
return mStringMatchOffsetFilter != std::string::npos;
|
||||
}
|
||||
|
||||
std::string::size_type LLFolderViewModelItemCommon::getFilterStringOffset()
|
||||
{
|
||||
return mStringMatchOffsetFilter;
|
||||
}
|
||||
|
||||
std::string::size_type LLFolderViewModelItemCommon::getFilterStringSize()
|
||||
{
|
||||
return mRootViewModel.getFilter().getFilterStringSize();
|
||||
}
|
||||
|
|
@ -0,0 +1,444 @@
|
|||
/**
|
||||
* @file llfolderviewmodel.h
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
#ifndef LLFOLDERVIEWMODEL_H
|
||||
#define LLFOLDERVIEWMODEL_H
|
||||
|
||||
#include "llfontgl.h" // just for StyleFlags enum
|
||||
#include "llfolderview.h"
|
||||
|
||||
// These are grouping of inventory types.
|
||||
// Order matters when sorting system folders to the top.
|
||||
enum EInventorySortGroup
|
||||
{
|
||||
SG_SYSTEM_FOLDER,
|
||||
SG_TRASH_FOLDER,
|
||||
SG_NORMAL_FOLDER,
|
||||
SG_ITEM
|
||||
};
|
||||
|
||||
class LLFontGL;
|
||||
class LLInventoryModel;
|
||||
class LLMenuGL;
|
||||
class LLUIImage;
|
||||
class LLUUID;
|
||||
class LLFolderViewItem;
|
||||
class LLFolderViewFolder;
|
||||
|
||||
class LLFolderViewFilter
|
||||
{
|
||||
public:
|
||||
enum EFilterModified
|
||||
{
|
||||
FILTER_NONE, // nothing to do, already filtered
|
||||
FILTER_RESTART, // restart filtering from scratch
|
||||
FILTER_LESS_RESTRICTIVE, // existing filtered items will certainly pass this filter
|
||||
FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
LLFolderViewFilter() {}
|
||||
virtual ~LLFolderViewFilter() {}
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Execution And Results
|
||||
// +-------------------------------------------------------------------+
|
||||
virtual bool check(const LLFolderViewModelItem* item) = 0;
|
||||
virtual bool checkFolder(const LLFolderViewModelItem* folder) const = 0;
|
||||
|
||||
virtual void setEmptyLookupMessage(const std::string& message) = 0;
|
||||
virtual std::string getEmptyLookupMessage() const = 0;
|
||||
|
||||
virtual bool showAllResults() const = 0;
|
||||
|
||||
virtual std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const = 0;
|
||||
virtual std::string::size_type getFilterStringSize() const = 0;
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Status
|
||||
// +-------------------------------------------------------------------+
|
||||
virtual bool isActive() const = 0;
|
||||
virtual bool isModified() const = 0;
|
||||
virtual void clearModified() = 0;
|
||||
virtual const std::string& getName() const = 0;
|
||||
virtual const std::string& getFilterText() = 0;
|
||||
//RN: this is public to allow system to externally force a global refilter
|
||||
virtual void setModified(EFilterModified behavior = FILTER_RESTART) = 0;
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Count
|
||||
// +-------------------------------------------------------------------+
|
||||
virtual void setFilterCount(S32 count) = 0;
|
||||
virtual S32 getFilterCount() const = 0;
|
||||
virtual void decrementFilterCount() = 0;
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Default
|
||||
// +-------------------------------------------------------------------+
|
||||
virtual bool isDefault() const = 0;
|
||||
virtual bool isNotDefault() const = 0;
|
||||
virtual void markDefault() = 0;
|
||||
virtual void resetDefault() = 0;
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Generation
|
||||
// +-------------------------------------------------------------------+
|
||||
virtual S32 getCurrentGeneration() const = 0;
|
||||
virtual S32 getFirstSuccessGeneration() const = 0;
|
||||
virtual S32 getFirstRequiredGeneration() const = 0;
|
||||
};
|
||||
|
||||
class LLFolderViewModelInterface
|
||||
{
|
||||
public:
|
||||
virtual ~LLFolderViewModelInterface() {}
|
||||
virtual void requestSortAll() = 0;
|
||||
|
||||
virtual void sort(class LLFolderViewFolder*) = 0;
|
||||
virtual void filter() = 0;
|
||||
|
||||
virtual bool contentsReady() = 0;
|
||||
virtual void setFolderView(LLFolderView* folder_view) = 0;
|
||||
virtual LLFolderViewFilter& getFilter() = 0;
|
||||
virtual const LLFolderViewFilter& getFilter() const = 0;
|
||||
virtual std::string getStatusText() = 0;
|
||||
|
||||
virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
|
||||
};
|
||||
|
||||
// This is an abstract base class that users of the folderview classes
|
||||
// would use to bridge the folder view with the underlying data
|
||||
class LLFolderViewModelItem : public LLRefCount
|
||||
{
|
||||
public:
|
||||
LLFolderViewModelItem() { }
|
||||
virtual ~LLFolderViewModelItem() { }
|
||||
|
||||
virtual void update() {} //called when drawing
|
||||
virtual const std::string& getName() const = 0;
|
||||
virtual const std::string& getDisplayName() const = 0;
|
||||
virtual const std::string& getSearchableName() const = 0;
|
||||
|
||||
virtual LLPointer<LLUIImage> getIcon() const = 0;
|
||||
virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
|
||||
virtual LLPointer<LLUIImage> getIconOverlay() const { return NULL; }
|
||||
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
|
||||
virtual std::string getLabelSuffix() const = 0;
|
||||
|
||||
virtual void openItem( void ) = 0;
|
||||
virtual void closeItem( void ) = 0;
|
||||
virtual void selectItem(void) = 0;
|
||||
|
||||
virtual BOOL isItemRenameable() const = 0;
|
||||
virtual BOOL renameItem(const std::string& new_name) = 0;
|
||||
|
||||
virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
|
||||
virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
|
||||
|
||||
virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
|
||||
virtual BOOL removeItem() = 0;
|
||||
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
|
||||
|
||||
virtual BOOL isItemCopyable() const = 0;
|
||||
virtual BOOL copyToClipboard() const = 0;
|
||||
virtual BOOL cutToClipboard() const = 0;
|
||||
|
||||
virtual BOOL isClipboardPasteable() const = 0;
|
||||
virtual void pasteFromClipboard() = 0;
|
||||
virtual void pasteLinkFromClipboard() = 0;
|
||||
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
|
||||
|
||||
virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
|
||||
|
||||
virtual bool filter( LLFolderViewFilter& filter) = 0;
|
||||
virtual bool passedFilter(S32 filter_generation = -1) = 0;
|
||||
virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
|
||||
virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
|
||||
virtual void setPassedFolderFilter(bool passed, S32 filter_generation) = 0;
|
||||
virtual void dirtyFilter() = 0;
|
||||
virtual bool hasFilterStringMatch() = 0;
|
||||
virtual std::string::size_type getFilterStringOffset() = 0;
|
||||
virtual std::string::size_type getFilterStringSize() = 0;
|
||||
|
||||
virtual S32 getLastFilterGeneration() const = 0;
|
||||
|
||||
virtual bool hasChildren() const = 0;
|
||||
virtual void addChild(LLFolderViewModelItem* child) = 0;
|
||||
virtual void removeChild(LLFolderViewModelItem* child) = 0;
|
||||
|
||||
// This method will be called to determine if a drop can be
|
||||
// performed, and will set drop to TRUE if a drop is
|
||||
// requested. Returns TRUE if a drop is possible/happened,
|
||||
// otherwise FALSE.
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
std::string& tooltip_msg) = 0;
|
||||
|
||||
virtual void requestSort() = 0;
|
||||
virtual S32 getSortVersion() = 0;
|
||||
virtual void setSortVersion(S32 version) = 0;
|
||||
virtual void setParent(LLFolderViewModelItem* parent) = 0;
|
||||
virtual bool hasParent() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
friend class LLFolderViewItem;
|
||||
virtual void setFolderViewItem(LLFolderViewItem* folder_view_item) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLFolderViewModelItemCommon : public LLFolderViewModelItem
|
||||
{
|
||||
public:
|
||||
LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model)
|
||||
: mSortVersion(-1),
|
||||
mPassedFilter(true),
|
||||
mPassedFolderFilter(true),
|
||||
mStringMatchOffsetFilter(std::string::npos),
|
||||
mStringFilterSize(0),
|
||||
mFolderViewItem(NULL),
|
||||
mLastFilterGeneration(-1),
|
||||
mLastFolderFilterGeneration(-1),
|
||||
mMostFilteredDescendantGeneration(-1),
|
||||
mParent(NULL),
|
||||
mRootViewModel(root_view_model)
|
||||
{
|
||||
mChildren.clear();
|
||||
}
|
||||
|
||||
void requestSort() { mSortVersion = -1; }
|
||||
S32 getSortVersion() { return mSortVersion; }
|
||||
void setSortVersion(S32 version) { mSortVersion = version;}
|
||||
|
||||
S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
|
||||
S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
|
||||
void dirtyFilter()
|
||||
{
|
||||
mLastFilterGeneration = -1;
|
||||
mLastFolderFilterGeneration = -1;
|
||||
|
||||
// bubble up dirty flag all the way to root
|
||||
if (mParent)
|
||||
{
|
||||
mParent->dirtyFilter();
|
||||
}
|
||||
}
|
||||
bool hasFilterStringMatch();
|
||||
std::string::size_type getFilterStringOffset();
|
||||
std::string::size_type getFilterStringSize();
|
||||
|
||||
typedef std::list<LLFolderViewModelItem*> child_list_t;
|
||||
|
||||
virtual void addChild(LLFolderViewModelItem* child)
|
||||
{
|
||||
// Avoid duplicates: bail out if that child is already present in the list
|
||||
// Note: this happens when models are created before views
|
||||
child_list_t::const_iterator iter;
|
||||
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
if (child == *iter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
mChildren.push_back(child);
|
||||
child->setParent(this);
|
||||
dirtyFilter();
|
||||
requestSort();
|
||||
}
|
||||
virtual void removeChild(LLFolderViewModelItem* child)
|
||||
{
|
||||
mChildren.remove(child);
|
||||
child->setParent(NULL);
|
||||
dirtyFilter();
|
||||
}
|
||||
|
||||
virtual void clearChildren()
|
||||
{
|
||||
// As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects
|
||||
// This is different and not equivalent to calling removeChild() on each child
|
||||
std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
|
||||
mChildren.clear();
|
||||
dirtyFilter();
|
||||
}
|
||||
|
||||
child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); }
|
||||
child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
|
||||
child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
|
||||
|
||||
void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
|
||||
{
|
||||
mPassedFilter = passed;
|
||||
mLastFilterGeneration = filter_generation;
|
||||
mStringMatchOffsetFilter = string_offset;
|
||||
mStringFilterSize = string_size;
|
||||
}
|
||||
|
||||
void setPassedFolderFilter(bool passed, S32 filter_generation)
|
||||
{
|
||||
mPassedFolderFilter = passed;
|
||||
mLastFolderFilterGeneration = filter_generation;
|
||||
}
|
||||
|
||||
virtual bool potentiallyVisible()
|
||||
{
|
||||
return passedFilter() // we've passed the filter
|
||||
|| getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration() // or we don't know yet
|
||||
|| descendantsPassedFilter();
|
||||
}
|
||||
|
||||
virtual bool passedFilter(S32 filter_generation = -1)
|
||||
{
|
||||
if (filter_generation < 0)
|
||||
filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
|
||||
|
||||
bool passed_folder_filter = mPassedFolderFilter && mLastFolderFilterGeneration >= filter_generation;
|
||||
bool passed_filter = mPassedFilter && mLastFilterGeneration >= filter_generation;
|
||||
return passed_folder_filter
|
||||
&& (descendantsPassedFilter(filter_generation)
|
||||
|| passed_filter);
|
||||
}
|
||||
|
||||
virtual bool descendantsPassedFilter(S32 filter_generation = -1)
|
||||
{
|
||||
if (filter_generation < 0) filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
|
||||
return mMostFilteredDescendantGeneration >= filter_generation;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
|
||||
virtual bool hasParent() { return mParent != NULL; }
|
||||
|
||||
S32 mSortVersion;
|
||||
bool mPassedFilter;
|
||||
bool mPassedFolderFilter;
|
||||
std::string::size_type mStringMatchOffsetFilter;
|
||||
std::string::size_type mStringFilterSize;
|
||||
|
||||
S32 mLastFilterGeneration;
|
||||
S32 mLastFolderFilterGeneration;
|
||||
S32 mMostFilteredDescendantGeneration;
|
||||
|
||||
child_list_t mChildren;
|
||||
LLFolderViewModelItem* mParent;
|
||||
LLFolderViewModelInterface& mRootViewModel;
|
||||
|
||||
void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
|
||||
LLFolderViewItem* mFolderViewItem;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LLFolderViewModelCommon : public LLFolderViewModelInterface
|
||||
{
|
||||
public:
|
||||
LLFolderViewModelCommon()
|
||||
: mTargetSortVersion(0),
|
||||
mFolderView(NULL)
|
||||
{}
|
||||
|
||||
virtual void requestSortAll()
|
||||
{
|
||||
// sort everything
|
||||
mTargetSortVersion++;
|
||||
}
|
||||
virtual std::string getStatusText();
|
||||
virtual void filter();
|
||||
|
||||
void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
|
||||
|
||||
protected:
|
||||
bool needsSort(class LLFolderViewModelItem* item);
|
||||
|
||||
S32 mTargetSortVersion;
|
||||
LLFolderView* mFolderView;
|
||||
|
||||
};
|
||||
|
||||
template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
|
||||
class LLFolderViewModel : public LLFolderViewModelCommon
|
||||
{
|
||||
public:
|
||||
LLFolderViewModel(){}
|
||||
virtual ~LLFolderViewModel() {}
|
||||
|
||||
typedef SORT_TYPE SortType;
|
||||
typedef ITEM_TYPE ItemType;
|
||||
typedef FOLDER_TYPE FolderType;
|
||||
typedef FILTER_TYPE FilterType;
|
||||
|
||||
virtual SortType& getSorter() { return mSorter; }
|
||||
virtual const SortType& getSorter() const { return mSorter; }
|
||||
virtual void setSorter(const SortType& sorter) { mSorter = sorter; requestSortAll(); }
|
||||
|
||||
virtual FilterType& getFilter() { return mFilter; }
|
||||
virtual const FilterType& getFilter() const { return mFilter; }
|
||||
virtual void setFilter(const FilterType& filter) { mFilter = filter; }
|
||||
|
||||
// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
|
||||
// this method needs to be overloaded and return the relevant fetch status.
|
||||
virtual bool contentsReady() { return true; }
|
||||
|
||||
|
||||
struct ViewModelCompare
|
||||
{
|
||||
ViewModelCompare(const SortType& sorter)
|
||||
: mSorter(sorter)
|
||||
{}
|
||||
|
||||
bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
|
||||
{
|
||||
return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
|
||||
}
|
||||
|
||||
bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
|
||||
{
|
||||
return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
|
||||
}
|
||||
|
||||
const SortType& mSorter;
|
||||
};
|
||||
|
||||
void sort(LLFolderViewFolder* folder)
|
||||
{
|
||||
if (needsSort(folder->getViewModelItem()))
|
||||
{
|
||||
folder->sortFolders(ViewModelCompare(getSorter()));
|
||||
folder->sortItems(ViewModelCompare(getSorter()));
|
||||
folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
|
||||
folder->requestArrange();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
SortType mSorter;
|
||||
FilterType mFilter;
|
||||
};
|
||||
|
||||
#endif // LLFOLDERVIEWMODEL_H
|
||||
|
|
@ -32,11 +32,10 @@
|
|||
|
||||
#include "lllocalcliprect.h"
|
||||
#include "llpanel.h"
|
||||
#include "llresizebar.h"
|
||||
#include "llcriticaldamp.h"
|
||||
#include "boost/foreach.hpp"
|
||||
|
||||
static const F32 MIN_FRACTIONAL_SIZE = 0.0f;
|
||||
static const F32 MIN_FRACTIONAL_SIZE = 0.00001f;
|
||||
static const F32 MAX_FRACTIONAL_SIZE = 1.f;
|
||||
|
||||
static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
|
||||
|
|
@ -71,7 +70,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
|
|||
mCollapseAmt(0.f),
|
||||
mVisibleAmt(1.f), // default to fully visible
|
||||
mResizeBar(NULL),
|
||||
mFractionalSize(MIN_FRACTIONAL_SIZE),
|
||||
mFractionalSize(0.f),
|
||||
mTargetDim(0),
|
||||
mIgnoreReshape(false),
|
||||
mOrientation(LLLayoutStack::HORIZONTAL)
|
||||
|
|
@ -520,7 +519,7 @@ void LLLayoutStack::updateFractionalSizes()
|
|||
{
|
||||
if (panelp->mAutoResize)
|
||||
{
|
||||
total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim());
|
||||
total_resizable_dim += llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -671,12 +670,12 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
S32 new_dim = (mOrientation == HORIZONTAL)
|
||||
? new_rect.getWidth()
|
||||
: new_rect.getHeight();
|
||||
S32 delta_dim = new_dim - resized_panel->getVisibleDim();
|
||||
if (delta_dim == 0) return;
|
||||
S32 delta_panel_dim = new_dim - resized_panel->getVisibleDim();
|
||||
if (delta_panel_dim == 0) return;
|
||||
|
||||
F32 total_visible_fraction = 0.f;
|
||||
F32 delta_auto_resize_headroom = 0.f;
|
||||
F32 original_auto_resize_headroom = 0.f;
|
||||
F32 old_auto_resize_headroom = 0.f;
|
||||
|
||||
LLLayoutPanel* other_resize_panel = NULL;
|
||||
LLLayoutPanel* following_panel = NULL;
|
||||
|
|
@ -685,7 +684,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
{
|
||||
if (panelp->mAutoResize)
|
||||
{
|
||||
original_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
|
||||
old_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
|
||||
if (panelp->getVisible() && !panelp->mCollapsed)
|
||||
{
|
||||
total_visible_fraction += panelp->mFractionalSize;
|
||||
|
|
@ -703,25 +702,24 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (resized_panel->mAutoResize)
|
||||
{
|
||||
if (!other_resize_panel || !other_resize_panel->mAutoResize)
|
||||
{
|
||||
delta_auto_resize_headroom += delta_dim;
|
||||
delta_auto_resize_headroom += delta_panel_dim;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!other_resize_panel || other_resize_panel->mAutoResize)
|
||||
{
|
||||
delta_auto_resize_headroom -= delta_dim;
|
||||
delta_auto_resize_headroom -= delta_panel_dim;
|
||||
}
|
||||
}
|
||||
|
||||
F32 fraction_given_up = 0.f;
|
||||
F32 fraction_remaining = 1.f;
|
||||
F32 updated_auto_resize_headroom = original_auto_resize_headroom + delta_auto_resize_headroom;
|
||||
F32 new_auto_resize_headroom = old_auto_resize_headroom + delta_auto_resize_headroom;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -733,7 +731,14 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
|
||||
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
|
||||
{
|
||||
if (!panelp->getVisible() || panelp->mCollapsed) continue;
|
||||
if (!panelp->getVisible() || panelp->mCollapsed)
|
||||
{
|
||||
if (panelp->mAutoResize)
|
||||
{
|
||||
fraction_remaining -= panelp->mFractionalSize;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (panelp == resized_panel)
|
||||
{
|
||||
|
|
@ -745,9 +750,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
case BEFORE_RESIZED_PANEL:
|
||||
if (panelp->mAutoResize)
|
||||
{ // freeze current size as fraction of overall auto_resize space
|
||||
F32 fractional_adjustment_factor = updated_auto_resize_headroom == 0.f
|
||||
F32 fractional_adjustment_factor = new_auto_resize_headroom == 0.f
|
||||
? 1.f
|
||||
: original_auto_resize_headroom / updated_auto_resize_headroom;
|
||||
: old_auto_resize_headroom / new_auto_resize_headroom;
|
||||
F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor,
|
||||
MIN_FRACTIONAL_SIZE,
|
||||
MAX_FRACTIONAL_SIZE);
|
||||
|
|
@ -764,9 +769,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
case RESIZED_PANEL:
|
||||
if (panelp->mAutoResize)
|
||||
{ // freeze new size as fraction
|
||||
F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
|
||||
F32 new_fractional_size = (new_auto_resize_headroom == 0.f)
|
||||
? MAX_FRACTIONAL_SIZE
|
||||
: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
|
||||
: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / new_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
|
||||
fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
|
||||
fraction_remaining -= panelp->mFractionalSize;
|
||||
panelp->mFractionalSize = new_fractional_size;
|
||||
|
|
@ -789,8 +794,13 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
}
|
||||
else
|
||||
{
|
||||
if (new_auto_resize_headroom < 1.f)
|
||||
{
|
||||
new_auto_resize_headroom = 1.f;
|
||||
}
|
||||
|
||||
F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom)
|
||||
/ updated_auto_resize_headroom,
|
||||
/ new_auto_resize_headroom,
|
||||
MIN_FRACTIONAL_SIZE,
|
||||
MAX_FRACTIONAL_SIZE);
|
||||
fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
|
||||
|
|
@ -799,7 +809,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
}
|
||||
else
|
||||
{
|
||||
panelp->mTargetDim -= delta_dim;
|
||||
panelp->mTargetDim -= delta_panel_dim;
|
||||
}
|
||||
which_panel = AFTER_RESIZED_PANEL;
|
||||
break;
|
||||
|
|
@ -815,7 +825,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
|
|||
}
|
||||
}
|
||||
updateLayout();
|
||||
normalizeFractionalSizes();
|
||||
//normalizeFractionalSizes();
|
||||
}
|
||||
|
||||
void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#define LL_LLLAYOUTSTACK_H
|
||||
|
||||
#include "llpanel.h"
|
||||
#include "llresizebar.h"
|
||||
|
||||
|
||||
class LLLayoutPanel;
|
||||
|
|
@ -178,6 +179,9 @@ public:
|
|||
F32 getAutoResizeFactor() const;
|
||||
F32 getVisibleAmount() const;
|
||||
S32 getVisibleDim() const;
|
||||
LLResizeBar* getResizeBar() { return mResizeBar; }
|
||||
|
||||
bool isCollapsed() const { return mCollapsed;}
|
||||
|
||||
void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
|
||||
void storeOriginalDim();
|
||||
|
|
|
|||
|
|
@ -157,8 +157,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
|
|||
mHighlightColor(p.highlight_color()),
|
||||
mPreeditBgColor(p.preedit_bg_color()),
|
||||
mGLFont(p.font),
|
||||
mContextMenuHandle(),
|
||||
mAutoreplaceCallback()
|
||||
mContextMenuHandle()
|
||||
{
|
||||
llassert( mMaxLengthBytes > 0 );
|
||||
|
||||
|
|
@ -971,12 +970,6 @@ void LLLineEditor::addChar(const llwchar uni_char)
|
|||
LLUI::reportBadKeystroke();
|
||||
}
|
||||
|
||||
if (!mReadOnly && mAutoreplaceCallback != NULL)
|
||||
{
|
||||
// call callback
|
||||
mAutoreplaceCallback(mText, mCursorPos);
|
||||
}
|
||||
|
||||
getWindow()->hideCursorUntilMouseMove();
|
||||
}
|
||||
|
||||
|
|
@ -2022,8 +2015,8 @@ void LLLineEditor::draw()
|
|||
LLRect screen_pos = calcScreenRect();
|
||||
LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
|
||||
|
||||
ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
|
||||
ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
|
||||
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
|
||||
ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
|
||||
getWindow()->setLanguageTextInput( ime_pos );
|
||||
}
|
||||
}
|
||||
|
|
@ -2570,7 +2563,7 @@ void LLLineEditor::markAsPreedit(S32 position, S32 length)
|
|||
|
||||
S32 LLLineEditor::getPreeditFontSize() const
|
||||
{
|
||||
return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
|
||||
return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
|
||||
}
|
||||
|
||||
void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace)
|
||||
|
|
|
|||
|
|
@ -189,9 +189,6 @@ public:
|
|||
virtual BOOL setTextArg( const std::string& key, const LLStringExplicit& text );
|
||||
virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text );
|
||||
|
||||
typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
|
||||
autoreplace_callback_t mAutoreplaceCallback;
|
||||
void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
|
||||
void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
|
||||
const std::string& getLabel() { return mLabel.getString(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
|
|||
|
||||
void LLLoadingIndicator::initFromParams(const Params& p)
|
||||
{
|
||||
BOOST_FOREACH(LLUIImage* image, p.images.image)
|
||||
BOOST_FOREACH(LLUIImage* image, p.images().image)
|
||||
{
|
||||
mImages.push_back(image);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class LLLoadingIndicator
|
|||
LOG_CLASS(LLLoadingIndicator);
|
||||
public:
|
||||
|
||||
struct Images : public LLInitParam::BatchBlock<Images>
|
||||
struct Images : public LLInitParam::Block<Images>
|
||||
{
|
||||
Multiple<LLUIImage*> image;
|
||||
|
||||
|
|
@ -62,8 +62,8 @@ public:
|
|||
|
||||
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
|
||||
{
|
||||
Optional<F32> images_per_sec;
|
||||
Optional<Images> images;
|
||||
Optional<F32> images_per_sec;
|
||||
Optional<Atomic<Images> > images;
|
||||
|
||||
Params()
|
||||
: images_per_sec("images_per_sec", 1.0f),
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
|
||||
LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
|
||||
: mScissorState(GL_SCISSOR_TEST),
|
||||
: mScissorState(GL_SCISSOR_TEST),
|
||||
mEnabled(enabled)
|
||||
{
|
||||
if (mEnabled)
|
||||
|
|
@ -88,10 +88,10 @@ void LLScreenClipRect::updateScissorRegion()
|
|||
LLRect rect = sClipRectStack.top();
|
||||
stop_glerror();
|
||||
S32 x,y,w,h;
|
||||
x = llfloor(rect.mLeft * LLUI::getScaleFactor().mV[VX]);
|
||||
y = llfloor(rect.mBottom * LLUI::getScaleFactor().mV[VY]);
|
||||
w = llmax(0, llceil(rect.getWidth() * LLUI::getScaleFactor().mV[VX])) + 1;
|
||||
h = llmax(0, llceil(rect.getHeight() * LLUI::getScaleFactor().mV[VY])) + 1;
|
||||
x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
|
||||
y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
|
||||
w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
|
||||
h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
|
||||
glScissor( x,y,w,h );
|
||||
stop_glerror();
|
||||
}
|
||||
|
|
@ -100,10 +100,10 @@ void LLScreenClipRect::updateScissorRegion()
|
|||
// LLLocalClipRect
|
||||
//---------------------------------------------------------------------------
|
||||
LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
|
||||
: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,
|
||||
rect.mTop + LLFontGL::sCurOrigin.mY,
|
||||
rect.mRight + LLFontGL::sCurOrigin.mX,
|
||||
rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
|
||||
: LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX,
|
||||
rect.mTop + LLFontGL::sCurOrigin.mY,
|
||||
rect.mRight + LLFontGL::sCurOrigin.mX,
|
||||
rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
|
||||
{}
|
||||
|
||||
LLLocalClipRect::~LLLocalClipRect()
|
||||
|
|
|
|||
|
|
@ -44,33 +44,27 @@ void LLMenuButton::MenuPositions::declareValues()
|
|||
|
||||
LLMenuButton::Params::Params()
|
||||
: menu_filename("menu_filename"),
|
||||
position("position", MP_BOTTOM_LEFT)
|
||||
position("menu_position", MP_BOTTOM_LEFT)
|
||||
{
|
||||
addSynonym(position, "position");
|
||||
}
|
||||
|
||||
|
||||
LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
|
||||
: LLButton(p),
|
||||
mIsMenuShown(false),
|
||||
mMenuPosition(p.position)
|
||||
mMenuPosition(p.position),
|
||||
mOwnMenu(false)
|
||||
{
|
||||
std::string menu_filename = p.menu_filename;
|
||||
|
||||
if (!menu_filename.empty())
|
||||
{
|
||||
LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
|
||||
if (!menu)
|
||||
{
|
||||
llwarns << "Error loading menu_button menu" << llendl;
|
||||
return;
|
||||
}
|
||||
setMenu(menu_filename, mMenuPosition);
|
||||
updateMenuOrigin();
|
||||
}
|
||||
|
||||
menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
|
||||
|
||||
mMenuHandle = menu->getHandle();
|
||||
|
||||
updateMenuOrigin();
|
||||
}
|
||||
LLMenuButton::~LLMenuButton()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
|
||||
|
|
@ -80,9 +74,7 @@ boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_sign
|
|||
|
||||
void LLMenuButton::hideMenu()
|
||||
{
|
||||
if(mMenuHandle.isDead()) return;
|
||||
|
||||
LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
|
||||
LLToggleableMenu* menu = getMenu();
|
||||
if (menu)
|
||||
{
|
||||
menu->setVisible(FALSE);
|
||||
|
|
@ -94,19 +86,39 @@ LLToggleableMenu* LLMenuButton::getMenu()
|
|||
return dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
|
||||
}
|
||||
|
||||
void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/)
|
||||
void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition position /*MP_TOP_LEFT*/)
|
||||
{
|
||||
if (menu_filename.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
|
||||
if (!menu)
|
||||
{
|
||||
llwarns << "Error loading menu_button menu" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
setMenu(menu, position, true);
|
||||
}
|
||||
|
||||
void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/, bool take_ownership /*false*/)
|
||||
{
|
||||
if (!menu) return;
|
||||
|
||||
cleanup(); // destroy the previous memnu if we own it
|
||||
|
||||
mMenuHandle = menu->getHandle();
|
||||
mMenuPosition = position;
|
||||
mOwnMenu = take_ownership;
|
||||
|
||||
menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
|
||||
}
|
||||
|
||||
BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
|
||||
{
|
||||
if (mMenuHandle.isDead()) return FALSE;
|
||||
if (!getMenu()) return FALSE;
|
||||
|
||||
if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
|
||||
{
|
||||
|
|
@ -118,7 +130,7 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
|
||||
LLToggleableMenu* menu = getMenu();
|
||||
if (menu && menu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
|
||||
{
|
||||
menu->setVisible(FALSE);
|
||||
|
|
@ -139,9 +151,12 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
|
||||
void LLMenuButton::toggleMenu()
|
||||
{
|
||||
if(mMenuHandle.isDead()) return;
|
||||
if (mValidateSignal && !(*mValidateSignal)(this, LLSD()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
|
||||
LLToggleableMenu* menu = getMenu();
|
||||
if (!menu) return;
|
||||
|
||||
// Store the button rectangle to toggle menu visibility if a mouse event
|
||||
|
|
@ -170,7 +185,8 @@ void LLMenuButton::toggleMenu()
|
|||
|
||||
void LLMenuButton::updateMenuOrigin()
|
||||
{
|
||||
if (mMenuHandle.isDead()) return;
|
||||
LLToggleableMenu* menu = getMenu();
|
||||
if (!menu) return;
|
||||
|
||||
LLRect rect = getRect();
|
||||
|
||||
|
|
@ -179,12 +195,12 @@ void LLMenuButton::updateMenuOrigin()
|
|||
case MP_TOP_LEFT:
|
||||
{
|
||||
mX = rect.mLeft;
|
||||
mY = rect.mTop + mMenuHandle.get()->getRect().getHeight();
|
||||
mY = rect.mTop + menu->getRect().getHeight();
|
||||
break;
|
||||
}
|
||||
case MP_TOP_RIGHT:
|
||||
{
|
||||
const LLRect& menu_rect = mMenuHandle.get()->getRect();
|
||||
const LLRect& menu_rect = menu->getRect();
|
||||
mX = rect.mRight - menu_rect.getWidth();
|
||||
mY = rect.mTop + menu_rect.getHeight();
|
||||
break;
|
||||
|
|
@ -211,3 +227,11 @@ void LLMenuButton::onMenuVisibilityChange(const LLSD& param)
|
|||
mIsMenuShown = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLMenuButton::cleanup()
|
||||
{
|
||||
if (mMenuHandle.get() && mOwnMenu)
|
||||
{
|
||||
mMenuHandle.get()->die();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ class LLToggleableMenu;
|
|||
class LLMenuButton
|
||||
: public LLButton
|
||||
{
|
||||
LOG_CLASS(LLMenuButton);
|
||||
|
||||
public:
|
||||
typedef enum e_menu_position
|
||||
{
|
||||
|
|
@ -53,7 +55,7 @@ public:
|
|||
{
|
||||
// filename for it's toggleable menu
|
||||
Optional<std::string> menu_filename;
|
||||
Optional<EMenuPosition> position;
|
||||
Optional<EMenuPosition, MenuPositions> position;
|
||||
|
||||
Params();
|
||||
};
|
||||
|
|
@ -68,13 +70,15 @@ public:
|
|||
void hideMenu();
|
||||
|
||||
LLToggleableMenu* getMenu();
|
||||
void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT);
|
||||
void setMenu(const std::string& menu_filename, EMenuPosition position = MP_TOP_LEFT);
|
||||
void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT, bool take_ownership = false);
|
||||
|
||||
void setMenuPosition(EMenuPosition position) { mMenuPosition = position; }
|
||||
|
||||
protected:
|
||||
friend class LLUICtrlFactory;
|
||||
LLMenuButton(const Params&);
|
||||
~LLMenuButton();
|
||||
|
||||
void toggleMenu();
|
||||
void updateMenuOrigin();
|
||||
|
|
@ -82,11 +86,14 @@ protected:
|
|||
void onMenuVisibilityChange(const LLSD& param);
|
||||
|
||||
private:
|
||||
void cleanup();
|
||||
|
||||
LLHandle<LLView> mMenuHandle;
|
||||
bool mIsMenuShown;
|
||||
EMenuPosition mMenuPosition;
|
||||
S32 mX;
|
||||
S32 mY;
|
||||
bool mOwnMenu; // true if we manage the menu lifetime
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -593,12 +593,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
{
|
||||
// the menu items are in the child list in bottom up order
|
||||
LLView* prev_menu_item = parent_menu->findNextSibling(this);
|
||||
return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
|
||||
return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLView* next_menu_item = parent_menu->findPrevSibling(this);
|
||||
return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
|
||||
return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -608,12 +608,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask)
|
|||
if (y > getRect().getHeight() / 2)
|
||||
{
|
||||
LLView* prev_menu_item = parent_menu->findNextSibling(this);
|
||||
return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
|
||||
return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLView* next_menu_item = parent_menu->findPrevSibling(this);
|
||||
return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
|
||||
return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1751,35 +1751,50 @@ void LLMenuGL::setCanTearOff(BOOL tear_off)
|
|||
|
||||
bool LLMenuGL::addChild(LLView* view, S32 tab_group)
|
||||
{
|
||||
if (LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view))
|
||||
LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
|
||||
if (menup)
|
||||
{
|
||||
appendMenu(menup);
|
||||
return true;
|
||||
return appendMenu(menup);
|
||||
}
|
||||
else if (LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view))
|
||||
|
||||
LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view);
|
||||
if (itemp)
|
||||
{
|
||||
append(itemp);
|
||||
return true;
|
||||
return append(itemp);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used in LLContextMenu and in LLTogleableMenu
|
||||
// to add an item of context menu branch
|
||||
|
||||
// Add an item to the context menu branch
|
||||
bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
|
||||
{
|
||||
LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
|
||||
if (context)
|
||||
{
|
||||
return appendContextSubMenu(context);
|
||||
}
|
||||
|
||||
LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
|
||||
if (separator)
|
||||
{
|
||||
return append(separator);
|
||||
}
|
||||
|
||||
LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
|
||||
if (item)
|
||||
{
|
||||
return append(item);
|
||||
|
||||
}
|
||||
|
||||
LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
|
||||
if (menup)
|
||||
{
|
||||
return appendMenu(menup);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2446,6 +2461,56 @@ void LLMenuGL::empty( void )
|
|||
deleteAllChildren();
|
||||
}
|
||||
|
||||
// erase group of items from menu
|
||||
void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/)
|
||||
{
|
||||
S32 items = mItems.size();
|
||||
|
||||
if ( items == 0 || begin >= end || begin < 0 || end > items )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
item_list_t::iterator start_position = mItems.begin();
|
||||
std::advance(start_position, begin);
|
||||
|
||||
item_list_t::iterator end_position = mItems.begin();
|
||||
std::advance(end_position, end);
|
||||
|
||||
for (item_list_t::iterator position_iter = start_position; position_iter != end_position; position_iter++)
|
||||
{
|
||||
LLUICtrl::removeChild(*position_iter);
|
||||
}
|
||||
|
||||
mItems.erase(start_position, end_position);
|
||||
|
||||
if (arrange)
|
||||
{
|
||||
needsArrange();
|
||||
}
|
||||
}
|
||||
|
||||
// add new item at position
|
||||
void LLMenuGL::insert( S32 position, LLView * ctrl, bool arrange /*= true*/ )
|
||||
{
|
||||
LLMenuItemGL * item = dynamic_cast<LLMenuItemGL *>(ctrl);
|
||||
|
||||
if (NULL == item || position < 0 || position >= mItems.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
item_list_t::iterator position_iter = mItems.begin();
|
||||
std::advance(position_iter, position);
|
||||
mItems.insert(position_iter, item);
|
||||
LLUICtrl::addChild(item);
|
||||
|
||||
if (arrange)
|
||||
{
|
||||
needsArrange();
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust rectangle of the menu
|
||||
void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom)
|
||||
{
|
||||
|
|
@ -2487,7 +2552,8 @@ BOOL LLMenuGL::append( LLMenuItemGL* item )
|
|||
// add a separator to this menu
|
||||
BOOL LLMenuGL::addSeparator()
|
||||
{
|
||||
LLMenuItemGL* separator = new LLMenuItemSeparatorGL();
|
||||
LLMenuItemSeparatorGL::Params p;
|
||||
LLMenuItemGL* separator = LLUICtrlFactory::create<LLMenuItemSeparatorGL>(p);
|
||||
return addChild(separator);
|
||||
}
|
||||
|
||||
|
|
@ -3080,7 +3146,17 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
|
|||
const S32 CURSOR_HEIGHT = 22; // Approximate "normal" cursor size
|
||||
const S32 CURSOR_WIDTH = 12;
|
||||
|
||||
if(menu->getChildList()->empty())
|
||||
//Do not show menu if all menu items are disabled
|
||||
BOOL item_enabled = false;
|
||||
for (LLView::child_list_t::const_iterator itor = menu->getChildList()->begin();
|
||||
itor != menu->getChildList()->end();
|
||||
++itor)
|
||||
{
|
||||
LLView *menu_item = (*itor);
|
||||
item_enabled = item_enabled || menu_item->getEnabled();
|
||||
}
|
||||
|
||||
if(menu->getChildList()->empty() || !item_enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -4039,11 +4115,6 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
|
|||
return result;
|
||||
}
|
||||
|
||||
void LLContextMenu::draw()
|
||||
{
|
||||
LLMenuGL::draw();
|
||||
}
|
||||
|
||||
bool LLContextMenu::addChild(LLView* view, S32 tab_group)
|
||||
{
|
||||
return addContextChild(view, tab_group);
|
||||
|
|
|
|||
|
|
@ -478,6 +478,12 @@ public:
|
|||
// remove all items on the menu
|
||||
void empty( void );
|
||||
|
||||
// erase group of items from menu
|
||||
void erase( S32 begin, S32 end, bool arrange = true );
|
||||
|
||||
// add new item at position
|
||||
void insert( S32 begin, LLView * ctrl, bool arrange = true );
|
||||
|
||||
void setItemLastSelected(LLMenuItemGL* item); // must be in menu
|
||||
U32 getItemCount(); // number of menu items
|
||||
LLMenuItemGL* getItem(S32 number); // 0 = first item
|
||||
|
|
@ -675,8 +681,6 @@ public:
|
|||
// can't set visibility directly, must call show or hide
|
||||
virtual void setVisible (BOOL visible);
|
||||
|
||||
virtual void draw ();
|
||||
|
||||
virtual void show (S32 x, S32 y, LLView* spawning_view = NULL);
|
||||
virtual void hide ();
|
||||
|
||||
|
|
@ -698,7 +702,6 @@ protected:
|
|||
LLHandle<LLView> mSpawningViewHandle;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// class LLContextMenuBranch
|
||||
// A branch to another context menu
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
|
|||
mTabContainer(NULL),
|
||||
mTabPos(LLTabContainer::TOP),
|
||||
mAutoResize(TRUE),
|
||||
mOrigMinWidth(0),
|
||||
mOrigMinHeight(0)
|
||||
mOrigMinWidth(params.min_width),
|
||||
mOrigMinHeight(params.min_height)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
|
|||
else if (floaterp->getHost())
|
||||
{
|
||||
// floaterp is hosted by somebody else and
|
||||
// this is adding it, so remove it from it's old host
|
||||
// this is adding it, so remove it from its old host
|
||||
floaterp->getHost()->removeFloater(floaterp);
|
||||
}
|
||||
else if (floaterp->getParent() == gFloaterView)
|
||||
|
|
@ -188,11 +188,13 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
|
|||
floater_data.mHeight = floaterp->getRect().getHeight();
|
||||
floater_data.mCanMinimize = floaterp->isMinimizeable();
|
||||
floater_data.mCanResize = floaterp->isResizable();
|
||||
floater_data.mSaveRect = floaterp->mSaveRect;
|
||||
|
||||
// remove minimize and close buttons
|
||||
floaterp->setCanMinimize(FALSE);
|
||||
floaterp->setCanResize(FALSE);
|
||||
floaterp->setCanDrag(FALSE);
|
||||
floaterp->mSaveRect = FALSE;
|
||||
floaterp->storeRectControl();
|
||||
// avoid double rendering of floater background (makes it more opaque)
|
||||
floaterp->setBackgroundVisible(FALSE);
|
||||
|
|
@ -291,6 +293,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
|
|||
{
|
||||
LLFloaterData& floater_data = found_data_it->second;
|
||||
floaterp->setCanMinimize(floater_data.mCanMinimize);
|
||||
floaterp->mSaveRect = floater_data.mSaveRect;
|
||||
if (!floater_data.mCanResize)
|
||||
{
|
||||
// restore original size
|
||||
|
|
@ -468,23 +471,12 @@ BOOL LLMultiFloater::postBuild()
|
|||
|
||||
void LLMultiFloater::updateResizeLimits()
|
||||
{
|
||||
static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
|
||||
const LLFloater::Params& default_params = LLFloater::getDefaultParams();
|
||||
S32 floater_header_size = default_params.header_height;
|
||||
S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
|
||||
// initialize minimum size constraint to the original xml values.
|
||||
S32 new_min_width = mOrigMinWidth;
|
||||
S32 new_min_height = mOrigMinHeight;
|
||||
// possibly increase minimum size constraint due to children's minimums.
|
||||
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
|
||||
{
|
||||
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
|
||||
if (floaterp)
|
||||
{
|
||||
new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
|
||||
new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
|
||||
}
|
||||
}
|
||||
|
||||
computeResizeLimits(new_min_width, new_min_height);
|
||||
|
||||
setResizeLimits(new_min_width, new_min_height);
|
||||
|
||||
S32 cur_height = getRect().getHeight();
|
||||
|
|
@ -510,3 +502,22 @@ void LLMultiFloater::updateResizeLimits()
|
|||
gFloaterView->adjustToFitScreen(this, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLMultiFloater::computeResizeLimits(S32& new_min_width, S32& new_min_height)
|
||||
{
|
||||
static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
|
||||
const LLFloater::Params& default_params = LLFloater::getDefaultParams();
|
||||
S32 floater_header_size = default_params.header_height;
|
||||
S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
|
||||
|
||||
// possibly increase minimum size constraint due to children's minimums.
|
||||
for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
|
||||
{
|
||||
LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
|
||||
if (floaterp)
|
||||
{
|
||||
new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
|
||||
new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ public:
|
|||
|
||||
virtual BOOL postBuild();
|
||||
/*virtual*/ void onOpen(const LLSD& key);
|
||||
/*virtual*/ void draw();
|
||||
/*virtual*/ void setVisible(BOOL visible);
|
||||
virtual void draw();
|
||||
virtual void setVisible(BOOL visible);
|
||||
/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
|
||||
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
|
||||
|
||||
|
|
@ -79,10 +79,11 @@ public:
|
|||
protected:
|
||||
struct LLFloaterData
|
||||
{
|
||||
S32 mWidth;
|
||||
S32 mHeight;
|
||||
BOOL mCanMinimize;
|
||||
BOOL mCanResize;
|
||||
S32 mWidth;
|
||||
S32 mHeight;
|
||||
BOOL mCanMinimize;
|
||||
BOOL mCanResize;
|
||||
BOOL mSaveRect;
|
||||
};
|
||||
|
||||
LLTabContainer* mTabContainer;
|
||||
|
|
@ -93,6 +94,9 @@ protected:
|
|||
LLTabContainer::TabPosition mTabPos;
|
||||
BOOL mAutoResize;
|
||||
S32 mOrigMinWidth, mOrigMinHeight; // logically const but initialized late
|
||||
|
||||
private:
|
||||
virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height);
|
||||
};
|
||||
|
||||
#endif // LL_MULTI_FLOATER_H
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include "lldir.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "lltrans.h"
|
||||
#include "llnotificationslistener.h"
|
||||
#include "llstring.h"
|
||||
#include "llsdparam.h"
|
||||
#include "llsdutil.h"
|
||||
|
|
@ -60,7 +59,8 @@ void NotificationPriorityValues::declareValues()
|
|||
}
|
||||
|
||||
LLNotificationForm::FormElementBase::FormElementBase()
|
||||
: name("name")
|
||||
: name("name"),
|
||||
enabled("enabled", true)
|
||||
{}
|
||||
|
||||
LLNotificationForm::FormIgnore::FormIgnore()
|
||||
|
|
@ -104,39 +104,7 @@ LLNotificationForm::Params::Params()
|
|||
form_elements("")
|
||||
{}
|
||||
|
||||
// Local channel for persistent notifications
|
||||
// Stores only persistent notifications.
|
||||
// Class users can use connectChanged() to process persistent notifications
|
||||
// (see LLNotificationStorage for example).
|
||||
class LLPersistentNotificationChannel : public LLNotificationChannel
|
||||
{
|
||||
LOG_CLASS(LLPersistentNotificationChannel);
|
||||
public:
|
||||
LLPersistentNotificationChannel() :
|
||||
LLNotificationChannel("Persistent", "Visible", ¬ificationFilter, LLNotificationComparators::orderByUUID())
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// The channel gets all persistent notifications except those that have been canceled
|
||||
static bool notificationFilter(LLNotificationPtr pNotification)
|
||||
{
|
||||
bool handle_notification = false;
|
||||
|
||||
handle_notification = pNotification->isPersistent()
|
||||
&& !pNotification->isCancelled();
|
||||
|
||||
return handle_notification;
|
||||
}
|
||||
|
||||
void onDelete(LLNotificationPtr pNotification)
|
||||
{
|
||||
// we want to keep deleted notifications in our log, otherwise some
|
||||
// notifications will be lost on exit.
|
||||
mItems.insert(pNotification);
|
||||
}
|
||||
};
|
||||
|
||||
bool filterIgnoredNotifications(LLNotificationPtr notification)
|
||||
{
|
||||
|
|
@ -210,6 +178,14 @@ LLNotificationForm::LLNotificationForm()
|
|||
{
|
||||
}
|
||||
|
||||
LLNotificationForm::LLNotificationForm( const LLNotificationForm& other )
|
||||
{
|
||||
mFormData = other.mFormData;
|
||||
mIgnore = other.mIgnore;
|
||||
mIgnoreMsg = other.mIgnoreMsg;
|
||||
mIgnoreSetting = other.mIgnoreSetting;
|
||||
mInvertSetting = other.mInvertSetting;
|
||||
}
|
||||
|
||||
LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p)
|
||||
: mIgnore(IGNORE_NO),
|
||||
|
|
@ -246,14 +222,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
|
|||
LLParamSDParser parser;
|
||||
parser.writeSD(mFormData, p.form_elements);
|
||||
|
||||
if (!mFormData.isArray())
|
||||
{
|
||||
// change existing contents to a one element array
|
||||
LLSD new_llsd_array = LLSD::emptyArray();
|
||||
new_llsd_array.append(mFormData);
|
||||
mFormData = new_llsd_array;
|
||||
}
|
||||
|
||||
for (LLSD::array_iterator it = mFormData.beginArray(), end_it = mFormData.endArray();
|
||||
it != end_it;
|
||||
++it)
|
||||
|
|
@ -300,7 +268,7 @@ LLSD LLNotificationForm::getElement(const std::string& element_name)
|
|||
}
|
||||
|
||||
|
||||
bool LLNotificationForm::hasElement(const std::string& element_name)
|
||||
bool LLNotificationForm::hasElement(const std::string& element_name) const
|
||||
{
|
||||
for (LLSD::array_const_iterator it = mFormData.beginArray();
|
||||
it != mFormData.endArray();
|
||||
|
|
@ -311,7 +279,48 @@ bool LLNotificationForm::hasElement(const std::string& element_name)
|
|||
return false;
|
||||
}
|
||||
|
||||
void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
|
||||
void LLNotificationForm::getElements(LLSD& elements, S32 offset)
|
||||
{
|
||||
//Finds elements that the template did not add
|
||||
LLSD::array_const_iterator it = mFormData.beginArray() + offset;
|
||||
|
||||
//Keeps track of only the dynamic elements
|
||||
for(; it != mFormData.endArray(); ++it)
|
||||
{
|
||||
elements.append(*it);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLNotificationForm::getElementEnabled(const std::string& element_name) const
|
||||
{
|
||||
for (LLSD::array_const_iterator it = mFormData.beginArray();
|
||||
it != mFormData.endArray();
|
||||
++it)
|
||||
{
|
||||
if ((*it)["name"].asString() == element_name)
|
||||
{
|
||||
return (*it)["enabled"].asBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLNotificationForm::setElementEnabled(const std::string& element_name, bool enabled)
|
||||
{
|
||||
for (LLSD::array_iterator it = mFormData.beginArray();
|
||||
it != mFormData.endArray();
|
||||
++it)
|
||||
{
|
||||
if ((*it)["name"].asString() == element_name)
|
||||
{
|
||||
(*it)["enabled"] = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value, bool enabled)
|
||||
{
|
||||
LLSD element;
|
||||
element["type"] = type;
|
||||
|
|
@ -319,6 +328,7 @@ void LLNotificationForm::addElement(const std::string& type, const std::string&
|
|||
element["text"] = name;
|
||||
element["value"] = value;
|
||||
element["index"] = mFormData.size();
|
||||
element["enabled"] = enabled;
|
||||
mFormData.append(element);
|
||||
}
|
||||
|
||||
|
|
@ -408,14 +418,19 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
|
|||
mURLOption(p.url.option),
|
||||
mURLTarget(p.url.target),
|
||||
mUnique(p.unique.isProvided()),
|
||||
mCombineBehavior(p.unique.combine),
|
||||
mPriority(p.priority),
|
||||
mPersist(p.persist),
|
||||
mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name())
|
||||
mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
|
||||
mLogToChat(p.log_to_chat),
|
||||
mLogToIM(p.log_to_im),
|
||||
mShowToast(p.show_toast),
|
||||
mSoundName("")
|
||||
{
|
||||
if (p.sound.isProvided()
|
||||
&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
|
||||
{
|
||||
mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
|
||||
mSoundName = p.sound;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
|
||||
|
|
@ -460,18 +475,20 @@ LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationV
|
|||
}
|
||||
}
|
||||
|
||||
LLNotification::LLNotification(const LLNotification::Params& p) :
|
||||
LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) :
|
||||
mTimestamp(p.time_stamp),
|
||||
mSubstitutions(p.substitutions),
|
||||
mPayload(p.payload),
|
||||
mExpiresAt(0),
|
||||
mExpiresAt(p.expiry),
|
||||
mTemporaryResponder(false),
|
||||
mRespondedTo(false),
|
||||
mPriority(p.priority),
|
||||
mCancelled(false),
|
||||
mIgnored(false),
|
||||
mResponderObj(NULL),
|
||||
mIsReusable(false)
|
||||
mId(p.id.isProvided() ? p.id : LLUUID::generateNewID()),
|
||||
mOfferFromAgent(p.offer_from_agent),
|
||||
mIsDND(p.is_dnd)
|
||||
{
|
||||
if (p.functor.name.isChosen())
|
||||
{
|
||||
|
|
@ -494,52 +511,52 @@ LLNotification::LLNotification(const LLNotification::Params& p) :
|
|||
mResponderObj = p.responder;
|
||||
}
|
||||
|
||||
mId.generate();
|
||||
init(p.name, p.form_elements);
|
||||
}
|
||||
|
||||
|
||||
LLNotification::LLNotification(const LLSD& sd) :
|
||||
mTemporaryResponder(false),
|
||||
mRespondedTo(false),
|
||||
mCancelled(false),
|
||||
mIgnored(false),
|
||||
mResponderObj(NULL),
|
||||
mIsReusable(false)
|
||||
{
|
||||
mId.generate();
|
||||
mSubstitutions = sd["substitutions"];
|
||||
mPayload = sd["payload"];
|
||||
mTimestamp = sd["time"];
|
||||
mExpiresAt = sd["expiry"];
|
||||
mPriority = (ENotificationPriority)sd["priority"].asInteger();
|
||||
mResponseFunctorName = sd["responseFunctor"].asString();
|
||||
std::string templatename = sd["name"].asString();
|
||||
init(templatename, LLSD());
|
||||
// replace form with serialized version
|
||||
mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
|
||||
}
|
||||
|
||||
|
||||
LLSD LLNotification::asLLSD()
|
||||
LLSD LLNotification::asLLSD(bool excludeTemplateElements)
|
||||
{
|
||||
LLSD output;
|
||||
output["id"] = mId;
|
||||
output["name"] = mTemplatep->mName;
|
||||
output["form"] = getForm()->asLLSD();
|
||||
output["substitutions"] = mSubstitutions;
|
||||
output["payload"] = mPayload;
|
||||
output["time"] = mTimestamp;
|
||||
output["expiry"] = mExpiresAt;
|
||||
output["priority"] = (S32)mPriority;
|
||||
output["responseFunctor"] = mResponseFunctorName;
|
||||
output["reusable"] = mIsReusable;
|
||||
LLParamSDParser parser;
|
||||
|
||||
if(mResponder)
|
||||
Params p;
|
||||
p.id = mId;
|
||||
p.name = mTemplatep->mName;
|
||||
p.substitutions = mSubstitutions;
|
||||
p.payload = mPayload;
|
||||
p.time_stamp = mTimestamp;
|
||||
p.expiry = mExpiresAt;
|
||||
p.priority = mPriority;
|
||||
|
||||
LLNotificationFormPtr templateForm = mTemplatep->mForm;
|
||||
LLSD formElements = mForm->asLLSD();
|
||||
|
||||
//All form elements (dynamic or not)
|
||||
if(!excludeTemplateElements)
|
||||
{
|
||||
p.form_elements = formElements;
|
||||
}
|
||||
//Only dynamic form elements (exclude template elements)
|
||||
else if(templateForm->getNumElements() < formElements.size())
|
||||
{
|
||||
LLSD dynamicElements;
|
||||
//Offset to dynamic elements and store them
|
||||
mForm->getElements(dynamicElements, templateForm->getNumElements());
|
||||
p.form_elements = dynamicElements;
|
||||
}
|
||||
|
||||
if(mResponder)
|
||||
{
|
||||
p.functor.responder_sd = mResponder->asLLSD();
|
||||
}
|
||||
|
||||
if(!mResponseFunctorName.empty())
|
||||
{
|
||||
output["responder"] = mResponder->asLLSD();
|
||||
p.functor.name = mResponseFunctorName;
|
||||
}
|
||||
|
||||
LLSD output;
|
||||
parser.writeSD(output, p);
|
||||
return output;
|
||||
}
|
||||
|
||||
|
|
@ -569,7 +586,6 @@ void LLNotification::updateFrom(LLNotificationPtr other)
|
|||
mRespondedTo = other->mRespondedTo;
|
||||
mResponse = other->mResponse;
|
||||
mTemporaryResponder = other->mTemporaryResponder;
|
||||
mIsReusable = other->isReusable();
|
||||
|
||||
update();
|
||||
}
|
||||
|
|
@ -668,7 +684,7 @@ void LLNotification::respond(const LLSD& response)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mTemporaryResponder && !isReusable())
|
||||
if (mTemporaryResponder)
|
||||
{
|
||||
LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
|
||||
mResponseFunctorName = "";
|
||||
|
|
@ -829,7 +845,7 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
|
|||
//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
|
||||
|
||||
mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
|
||||
mForm->append(form_elements);
|
||||
mForm->append(form_elements);
|
||||
|
||||
// apply substitution to form labels
|
||||
mForm->formatElements(mSubstitutions);
|
||||
|
|
@ -897,6 +913,49 @@ std::string LLNotification::getURL() const
|
|||
return (mTemplatep ? url : "");
|
||||
}
|
||||
|
||||
bool LLNotification::canLogToChat() const
|
||||
{
|
||||
return mTemplatep->mLogToChat;
|
||||
}
|
||||
|
||||
bool LLNotification::canLogToIM() const
|
||||
{
|
||||
return mTemplatep->mLogToIM;
|
||||
}
|
||||
|
||||
bool LLNotification::canShowToast() const
|
||||
{
|
||||
return mTemplatep->mShowToast;
|
||||
}
|
||||
|
||||
bool LLNotification::hasFormElements() const
|
||||
{
|
||||
return mTemplatep->mForm->getNumElements() != 0;
|
||||
}
|
||||
|
||||
void LLNotification::playSound()
|
||||
{
|
||||
make_ui_sound(mTemplatep->mSoundName.c_str());
|
||||
}
|
||||
|
||||
LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
|
||||
{
|
||||
return mTemplatep->mCombineBehavior;
|
||||
}
|
||||
|
||||
void LLNotification::updateForm( const LLNotificationFormPtr& form )
|
||||
{
|
||||
mForm = form;
|
||||
}
|
||||
|
||||
void LLNotification::repost()
|
||||
{
|
||||
mRespondedTo = false;
|
||||
LLNotifications::instance().update(shared_from_this());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// =========================================================
|
||||
// LLNotificationChannel implementation
|
||||
// ---
|
||||
|
|
@ -957,7 +1016,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
std::string cmd = payload["sigtype"];
|
||||
LLNotificationSet::iterator foundItem = mItems.find(pNotification);
|
||||
bool wasFound = (foundItem != mItems.end());
|
||||
bool passesFilter = mFilter(pNotification);
|
||||
bool passesFilter = mFilter ? mFilter(pNotification) : true;
|
||||
|
||||
// first, we offer the result of the filter test to the simple
|
||||
// signals for pass/fail. One of these is guaranteed to be called.
|
||||
|
|
@ -966,10 +1025,12 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
bool abortProcessing = false;
|
||||
if (passesFilter)
|
||||
{
|
||||
onFilterPass(pNotification);
|
||||
abortProcessing = mPassedFilter(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
onFilterFail(pNotification);
|
||||
abortProcessing = mFailedFilter(payload);
|
||||
}
|
||||
|
||||
|
|
@ -987,8 +1048,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
{
|
||||
// not in our list, add it and say so
|
||||
mItems.insert(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
onLoad(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
}
|
||||
}
|
||||
else if (cmd == "change")
|
||||
|
|
@ -1003,18 +1064,18 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
{
|
||||
// it already existed, so this is a change
|
||||
// since it changed in place, all we have to do is resend the signal
|
||||
abortProcessing = mChanged(payload);
|
||||
onChange(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
// not in our list, add it and say so
|
||||
mItems.insert(pNotification);
|
||||
onChange(pNotification);
|
||||
// our payload is const, so make a copy before changing it
|
||||
LLSD newpayload = payload;
|
||||
newpayload["sigtype"] = "add";
|
||||
abortProcessing = mChanged(newpayload);
|
||||
onChange(pNotification);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1023,11 +1084,11 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
{
|
||||
// it already existed, so this is a delete
|
||||
mItems.erase(pNotification);
|
||||
onChange(pNotification);
|
||||
// our payload is const, so make a copy before changing it
|
||||
LLSD newpayload = payload;
|
||||
newpayload["sigtype"] = "delete";
|
||||
abortProcessing = mChanged(newpayload);
|
||||
onChange(pNotification);
|
||||
}
|
||||
// didn't pass, not on our list, do nothing
|
||||
}
|
||||
|
|
@ -1041,8 +1102,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
{
|
||||
// not in our list, add it and say so
|
||||
mItems.insert(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
onAdd(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
}
|
||||
}
|
||||
else if (cmd == "delete")
|
||||
|
|
@ -1050,65 +1111,35 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
|
|||
// if we have it in our list, pass on the delete, then delete it, else do nothing
|
||||
if (wasFound)
|
||||
{
|
||||
onDelete(pNotification);
|
||||
abortProcessing = mChanged(payload);
|
||||
// do not delete the notification to make LLChatHistory::appendMessage add notification panel to IM window
|
||||
if( ! pNotification->isReusable() )
|
||||
{
|
||||
mItems.erase(pNotification);
|
||||
onDelete(pNotification);
|
||||
}
|
||||
mItems.erase(pNotification);
|
||||
}
|
||||
}
|
||||
return abortProcessing;
|
||||
}
|
||||
|
||||
/* static */
|
||||
LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name,
|
||||
const std::string& parent,
|
||||
LLNotificationFilter filter,
|
||||
LLNotificationComparator comparator)
|
||||
LLNotificationChannel::LLNotificationChannel(const Params& p)
|
||||
: LLNotificationChannelBase(p.filter()),
|
||||
LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()),
|
||||
mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
|
||||
{
|
||||
// note: this is not a leak; notifications are self-registering.
|
||||
// This factory helps to prevent excess deletions by making sure all smart
|
||||
// pointers to notification channels come from the same source
|
||||
new LLNotificationChannel(name, parent, filter, comparator);
|
||||
return LLNotifications::instance().getChannel(name);
|
||||
BOOST_FOREACH(const std::string& source, p.sources)
|
||||
{
|
||||
connectToChannel(source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LLNotificationChannel::LLNotificationChannel(const std::string& name,
|
||||
const std::string& parent,
|
||||
LLNotificationFilter filter,
|
||||
LLNotificationComparator comparator) :
|
||||
LLNotificationChannelBase(filter, comparator),
|
||||
mName(name),
|
||||
mParent(parent)
|
||||
LLNotificationFilter filter)
|
||||
: LLNotificationChannelBase(filter),
|
||||
LLInstanceTracker<LLNotificationChannel, std::string>(name),
|
||||
mName(name)
|
||||
{
|
||||
// store myself in the channel map
|
||||
LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
|
||||
// bind to notification broadcast
|
||||
if (parent.empty())
|
||||
{
|
||||
LLNotifications::instance().connectChanged(
|
||||
boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
|
||||
p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLNotificationChannel::setComparator(LLNotificationComparator comparator)
|
||||
{
|
||||
mComparator = comparator;
|
||||
LLNotificationSet s2(mComparator);
|
||||
s2.insert(mItems.begin(), mItems.end());
|
||||
mItems.swap(s2);
|
||||
|
||||
// notify clients that we've been resorted
|
||||
mChanged(LLSD().with("sigtype", "sort"));
|
||||
connectToChannel(parent);
|
||||
}
|
||||
|
||||
bool LLNotificationChannel::isEmpty() const
|
||||
|
|
@ -1131,6 +1162,11 @@ LLNotificationChannel::Iterator LLNotificationChannel::end()
|
|||
return mItems.end();
|
||||
}
|
||||
|
||||
size_t LLNotificationChannel::size()
|
||||
{
|
||||
return mItems.size();
|
||||
}
|
||||
|
||||
std::string LLNotificationChannel::summarize()
|
||||
{
|
||||
std::string s("Channel '");
|
||||
|
|
@ -1144,22 +1180,33 @@ std::string LLNotificationChannel::summarize()
|
|||
return s;
|
||||
}
|
||||
|
||||
void LLNotificationChannel::connectToChannel( const std::string& channel_name )
|
||||
{
|
||||
if (channel_name.empty())
|
||||
{
|
||||
LLNotifications::instance().connectChanged(
|
||||
boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name);
|
||||
p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
// END OF LLNotificationChannel implementation
|
||||
// =========================================================
|
||||
|
||||
|
||||
// =========================================================
|
||||
// ============================================== ===========
|
||||
// LLNotifications implementation
|
||||
// ---
|
||||
LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
|
||||
LLNotificationComparators::orderByUUID()),
|
||||
mIgnoreAllNotifications(false)
|
||||
LLNotifications::LLNotifications()
|
||||
: LLNotificationChannelBase(LLNotificationFilters::includeEverything),
|
||||
mIgnoreAllNotifications(false)
|
||||
{
|
||||
LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
|
||||
|
||||
mListener.reset(new LLNotificationsListener(*this));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1196,7 +1243,15 @@ bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
|
|||
if (pNotif != existing_notification
|
||||
&& pNotif->isEquivalentTo(existing_notification))
|
||||
{
|
||||
return false;
|
||||
if (pNotif->getCombineBehavior() == LLNotification::CANCEL_OLD)
|
||||
{
|
||||
cancel(existing_notification);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1236,43 +1291,43 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Update the existing unique notification with the data from this particular instance...
|
||||
// This guarantees that duplicate notifications will be collapsed to the one
|
||||
// most recently triggered
|
||||
for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
|
||||
existing_it != mUniqueNotifications.end();
|
||||
++existing_it)
|
||||
switch(pNotif->getCombineBehavior())
|
||||
{
|
||||
LLNotificationPtr existing_notification = existing_it->second;
|
||||
if (pNotif != existing_notification
|
||||
&& pNotif->isEquivalentTo(existing_notification))
|
||||
case LLNotification::REPLACE_WITH_NEW:
|
||||
// Update the existing unique notification with the data from this particular instance...
|
||||
// This guarantees that duplicate notifications will be collapsed to the one
|
||||
// most recently triggered
|
||||
for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
|
||||
existing_it != mUniqueNotifications.end();
|
||||
++existing_it)
|
||||
{
|
||||
// copy notification instance data over to oldest instance
|
||||
// of this unique notification and update it
|
||||
existing_notification->updateFrom(pNotif);
|
||||
// then delete the new one
|
||||
cancel(pNotif);
|
||||
LLNotificationPtr existing_notification = existing_it->second;
|
||||
if (pNotif != existing_notification
|
||||
&& pNotif->isEquivalentTo(existing_notification))
|
||||
{
|
||||
// copy notification instance data over to oldest instance
|
||||
// of this unique notification and update it
|
||||
existing_notification->updateFrom(pNotif);
|
||||
// then delete the new one
|
||||
cancel(pNotif);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LLNotification::KEEP_OLD:
|
||||
break;
|
||||
case LLNotification::CANCEL_OLD:
|
||||
// already handled by filter logic
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
|
||||
{
|
||||
mChannels[pChan->getName()] = pChan;
|
||||
}
|
||||
|
||||
LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
|
||||
{
|
||||
ChannelMap::iterator p = mChannels.find(channelName);
|
||||
if(p == mChannels.end())
|
||||
{
|
||||
llerrs << "Did not find channel named " << channelName << llendl;
|
||||
return LLNotificationChannelPtr();
|
||||
}
|
||||
return p->second;
|
||||
return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1288,24 +1343,21 @@ void LLNotifications::createDefaultChannels()
|
|||
{
|
||||
// now construct the various channels AFTER loading the notifications,
|
||||
// because the history channel is going to rewrite the stored notifications file
|
||||
LLNotificationChannel::buildChannel("Enabled", "",
|
||||
!boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
|
||||
LLNotificationChannel::buildChannel("Expiration", "Enabled",
|
||||
boost::bind(&LLNotifications::expirationFilter, this, _1));
|
||||
LLNotificationChannel::buildChannel("Unexpired", "Enabled",
|
||||
!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
|
||||
LLNotificationChannel::buildChannel("Unique", "Unexpired",
|
||||
boost::bind(&LLNotifications::uniqueFilter, this, _1));
|
||||
LLNotificationChannel::buildChannel("Ignore", "Unique",
|
||||
filterIgnoredNotifications);
|
||||
LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
|
||||
boost::bind(&LLNotifications::isVisibleByRules, this, _1));
|
||||
LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
|
||||
&LLNotificationFilters::includeEverything);
|
||||
|
||||
// create special persistent notification channel
|
||||
// this isn't a leak, don't worry about the empty "new"
|
||||
new LLPersistentNotificationChannel();
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "",
|
||||
!boost::bind(&LLNotifications::getIgnoreAllNotifications, this)));
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled",
|
||||
boost::bind(&LLNotifications::expirationFilter, this, _1)));
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled",
|
||||
!boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired",
|
||||
boost::bind(&LLNotifications::uniqueFilter, this, _1)));
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique",
|
||||
filterIgnoredNotifications));
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore",
|
||||
boost::bind(&LLNotifications::isVisibleByRules, this, _1)));
|
||||
mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules",
|
||||
&LLNotificationFilters::includeEverything));
|
||||
mDefaultChannels.push_back(new LLPersistentNotificationChannel());
|
||||
|
||||
// connect action methods to these channels
|
||||
LLNotifications::instance().getChannel("Enabled")->
|
||||
|
|
@ -1537,34 +1589,32 @@ void LLNotifications::addFromCallback(const LLSD& name)
|
|||
add(name.asString(), LLSD(), LLSD());
|
||||
}
|
||||
|
||||
LLNotificationPtr LLNotifications::add(const std::string& name,
|
||||
const LLSD& substitutions,
|
||||
const LLSD& payload)
|
||||
LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload)
|
||||
{
|
||||
LLNotification::Params::Functor functor_p;
|
||||
functor_p.name = name;
|
||||
return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
|
||||
}
|
||||
|
||||
LLNotificationPtr LLNotifications::add(const std::string& name,
|
||||
const LLSD& substitutions,
|
||||
const LLSD& payload,
|
||||
const std::string& functor_name)
|
||||
LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, const std::string& functor_name)
|
||||
{
|
||||
LLNotification::Params::Functor functor_p;
|
||||
functor_p.name = functor_name;
|
||||
return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
|
||||
return add(LLNotification::Params().name(name)
|
||||
.substitutions(substitutions)
|
||||
.payload(payload)
|
||||
.functor(functor_p));
|
||||
}
|
||||
|
||||
//virtual
|
||||
LLNotificationPtr LLNotifications::add(const std::string& name,
|
||||
const LLSD& substitutions,
|
||||
const LLSD& payload,
|
||||
LLNotificationFunctorRegistry::ResponseFunctor functor)
|
||||
LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, LLNotificationFunctorRegistry::ResponseFunctor functor)
|
||||
{
|
||||
LLNotification::Params::Functor functor_p;
|
||||
functor_p.function = functor;
|
||||
return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));
|
||||
return add(LLNotification::Params().name(name)
|
||||
.substitutions(substitutions)
|
||||
.payload(payload)
|
||||
.functor(functor_p));
|
||||
}
|
||||
|
||||
// generalized add function that takes a parameter block object for more complex instantiations
|
||||
|
|
@ -1595,12 +1645,11 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
|
|||
if (pNotif == NULL || pNotif->isCancelled()) return;
|
||||
|
||||
LLNotificationSet::iterator it=mItems.find(pNotif);
|
||||
if (it == mItems.end())
|
||||
if (it != mItems.end())
|
||||
{
|
||||
llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
|
||||
pNotif->cancel();
|
||||
updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
|
||||
}
|
||||
pNotif->cancel();
|
||||
updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
|
||||
}
|
||||
|
||||
void LLNotifications::cancelByName(const std::string& name)
|
||||
|
|
@ -1639,7 +1688,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif)
|
|||
|
||||
LLNotificationPtr LLNotifications::find(LLUUID uuid)
|
||||
{
|
||||
LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
|
||||
LLNotificationPtr target = LLNotificationPtr(new LLNotification(LLNotification::Params().id(uuid)));
|
||||
LLNotificationSet::iterator it=mItems.find(target);
|
||||
if (it == mItems.end())
|
||||
{
|
||||
|
|
@ -1778,22 +1827,18 @@ std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
|
|||
return s;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLPostponedNotification::lookupName(LLPostponedNotification* thiz,
|
||||
const LLUUID& id,
|
||||
void LLPostponedNotification::lookupName(const LLUUID& id,
|
||||
bool is_group)
|
||||
{
|
||||
if (is_group)
|
||||
{
|
||||
gCacheName->getGroup(id,
|
||||
boost::bind(&LLPostponedNotification::onGroupNameCache,
|
||||
thiz, _1, _2, _3));
|
||||
this, _1, _2, _3));
|
||||
}
|
||||
else
|
||||
{
|
||||
LLAvatarNameCache::get(id,
|
||||
boost::bind(&LLPostponedNotification::onAvatarNameCache,
|
||||
thiz, _1, _2));
|
||||
fetchAvatarName(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1804,9 +1849,24 @@ void LLPostponedNotification::onGroupNameCache(const LLUUID& id,
|
|||
finalizeName(full_name);
|
||||
}
|
||||
|
||||
void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
|
||||
{
|
||||
if (id.notNull())
|
||||
{
|
||||
if (mAvatarNameCacheConnection.connected())
|
||||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
|
||||
mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
|
||||
const LLAvatarName& av_name)
|
||||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
|
||||
std::string name = av_name.getCompleteName();
|
||||
|
||||
// from PE merge - we should figure out if this is the right thing to do
|
||||
|
|
|
|||
|
|
@ -87,17 +87,16 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
// we want to minimize external dependencies, but this one is important
|
||||
#include "llsd.h"
|
||||
|
||||
// and we need this to manage the notification callbacks
|
||||
#include "llevents.h"
|
||||
#include "llfunctorregistry.h"
|
||||
#include "llpointer.h"
|
||||
#include "llinitparam.h"
|
||||
#include "llnotificationslistener.h"
|
||||
#include "llmortician.h"
|
||||
#include "llnotificationptr.h"
|
||||
#include "llpointer.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llsdparam.h"
|
||||
|
||||
class LLAvatarName;
|
||||
typedef enum e_notification_priority
|
||||
|
|
@ -164,6 +163,7 @@ public:
|
|||
struct FormElementBase : public LLInitParam::Block<FormElementBase>
|
||||
{
|
||||
Optional<std::string> name;
|
||||
Optional<bool> enabled;
|
||||
|
||||
FormElementBase();
|
||||
};
|
||||
|
|
@ -233,16 +233,21 @@ public:
|
|||
} EIgnoreType;
|
||||
|
||||
LLNotificationForm();
|
||||
LLNotificationForm(const LLNotificationForm&);
|
||||
LLNotificationForm(const LLSD& sd);
|
||||
LLNotificationForm(const std::string& name, const Params& p);
|
||||
|
||||
void fromLLSD(const LLSD& sd);
|
||||
LLSD asLLSD() const;
|
||||
|
||||
S32 getNumElements() { return mFormData.size(); }
|
||||
LLSD getElement(S32 index) { return mFormData.get(index); }
|
||||
LLSD getElement(const std::string& element_name);
|
||||
bool hasElement(const std::string& element_name);
|
||||
void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD());
|
||||
void getElements(LLSD& elements, S32 offset = 0);
|
||||
bool hasElement(const std::string& element_name) const;
|
||||
bool getElementEnabled(const std::string& element_name) const;
|
||||
void setElementEnabled(const std::string& element_name, bool enabled);
|
||||
void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true);
|
||||
void formatElements(const LLSD& substitutions);
|
||||
// appends form elements from another form serialized as LLSD
|
||||
void append(const LLSD& sub_form);
|
||||
|
|
@ -296,42 +301,52 @@ LOG_CLASS(LLNotification);
|
|||
friend class LLNotifications;
|
||||
|
||||
public:
|
||||
|
||||
// parameter object used to instantiate a new notification
|
||||
struct Params : public LLInitParam::Block<Params>
|
||||
{
|
||||
friend class LLNotification;
|
||||
|
||||
Mandatory<std::string> name;
|
||||
|
||||
// optional
|
||||
Optional<LLSD> substitutions;
|
||||
Optional<LLSD> payload;
|
||||
Optional<LLUUID> id;
|
||||
Optional<LLSD> substitutions,
|
||||
form_elements,
|
||||
payload;
|
||||
Optional<ENotificationPriority, NotificationPriorityValues> priority;
|
||||
Optional<LLSD> form_elements;
|
||||
Optional<LLDate> time_stamp;
|
||||
Optional<LLDate> time_stamp,
|
||||
expiry;
|
||||
Optional<LLNotificationContext*> context;
|
||||
Optional<void*> responder;
|
||||
Optional<bool> offer_from_agent;
|
||||
Optional<bool> is_dnd;
|
||||
|
||||
struct Functor : public LLInitParam::ChoiceBlock<Functor>
|
||||
{
|
||||
Alternative<std::string> name;
|
||||
Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;
|
||||
Alternative<LLNotificationResponderPtr> responder;
|
||||
Alternative<LLSD> responder_sd;
|
||||
|
||||
Functor()
|
||||
: name("functor_name"),
|
||||
: name("responseFunctor"),
|
||||
function("functor"),
|
||||
responder("responder")
|
||||
responder("responder"),
|
||||
responder_sd("responder_sd")
|
||||
{}
|
||||
};
|
||||
Optional<Functor> functor;
|
||||
|
||||
Params()
|
||||
: name("name"),
|
||||
id("id"),
|
||||
priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
|
||||
time_stamp("time_stamp"),
|
||||
time_stamp("time"),
|
||||
payload("payload"),
|
||||
form_elements("form_elements")
|
||||
form_elements("form"),
|
||||
substitutions("substitutions"),
|
||||
expiry("expiry"),
|
||||
offer_from_agent("offer_from_agent", false),
|
||||
is_dnd("is_dnd", false)
|
||||
{
|
||||
time_stamp = LLDate::now();
|
||||
responder = NULL;
|
||||
|
|
@ -340,9 +355,13 @@ public:
|
|||
Params(const std::string& _name)
|
||||
: name("name"),
|
||||
priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
|
||||
time_stamp("time_stamp"),
|
||||
time_stamp("time"),
|
||||
payload("payload"),
|
||||
form_elements("form_elements")
|
||||
form_elements("form"),
|
||||
substitutions("substitutions"),
|
||||
expiry("expiry"),
|
||||
offer_from_agent("offer_from_agent", false),
|
||||
is_dnd("is_dnd", false)
|
||||
{
|
||||
functor.name = _name;
|
||||
name = _name;
|
||||
|
|
@ -355,7 +374,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
LLUUID mId;
|
||||
const LLUUID mId;
|
||||
LLSD mPayload;
|
||||
LLSD mSubstitutions;
|
||||
LLDate mTimestamp;
|
||||
|
|
@ -367,8 +386,9 @@ private:
|
|||
ENotificationPriority mPriority;
|
||||
LLNotificationFormPtr mForm;
|
||||
void* mResponderObj; // TODO - refactor/remove this field
|
||||
bool mIsReusable;
|
||||
LLNotificationResponderPtr mResponder;
|
||||
bool mOfferFromAgent;
|
||||
bool mIsDND;
|
||||
|
||||
// a reference to the template
|
||||
LLNotificationTemplatePtr mTemplatep;
|
||||
|
|
@ -392,18 +412,10 @@ private:
|
|||
|
||||
void init(const std::string& template_name, const LLSD& form_elements);
|
||||
|
||||
LLNotification(const Params& p);
|
||||
|
||||
// this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
|
||||
// for anything real!
|
||||
LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {}
|
||||
|
||||
void cancel();
|
||||
|
||||
public:
|
||||
|
||||
// constructor from a saved notification
|
||||
LLNotification(const LLSD& sd);
|
||||
LLNotification(const LLSDParamAdapter<Params>& p);
|
||||
|
||||
void setResponseFunctor(std::string const &responseFunctorName);
|
||||
|
||||
|
|
@ -446,7 +458,12 @@ public:
|
|||
// ["time"] = time at which notification was generated;
|
||||
// ["expiry"] = time at which notification expires;
|
||||
// ["responseFunctor"] = name of registered functor that handles responses to notification;
|
||||
LLSD asLLSD();
|
||||
LLSD asLLSD(bool excludeTemplateElements = false);
|
||||
|
||||
const LLNotificationFormPtr getForm();
|
||||
void updateForm(const LLNotificationFormPtr& form);
|
||||
|
||||
void repost();
|
||||
|
||||
void respond(const LLSD& sd);
|
||||
void respondWithDefault();
|
||||
|
|
@ -507,6 +524,21 @@ public:
|
|||
return mTimestamp;
|
||||
}
|
||||
|
||||
bool getOfferFromAgent() const
|
||||
{
|
||||
return mOfferFromAgent;
|
||||
}
|
||||
|
||||
bool isDND() const
|
||||
{
|
||||
return mIsDND;
|
||||
}
|
||||
|
||||
void setDND(const bool flag)
|
||||
{
|
||||
mIsDND = flag;
|
||||
}
|
||||
|
||||
std::string getType() const;
|
||||
std::string getMessage() const;
|
||||
std::string getFooter() const;
|
||||
|
|
@ -514,8 +546,21 @@ public:
|
|||
std::string getURL() const;
|
||||
S32 getURLOption() const;
|
||||
S32 getURLOpenExternally() const;
|
||||
bool canLogToChat() const;
|
||||
bool canLogToIM() const;
|
||||
bool canShowToast() const;
|
||||
bool hasFormElements() const;
|
||||
void playSound();
|
||||
|
||||
typedef enum e_combine_behavior
|
||||
{
|
||||
REPLACE_WITH_NEW,
|
||||
KEEP_OLD,
|
||||
CANCEL_OLD
|
||||
|
||||
} ECombineBehavior;
|
||||
|
||||
const LLNotificationFormPtr getForm();
|
||||
ECombineBehavior getCombineBehavior() const;
|
||||
|
||||
const LLDate getExpiration() const
|
||||
{
|
||||
|
|
@ -532,10 +577,6 @@ public:
|
|||
return mId;
|
||||
}
|
||||
|
||||
bool isReusable() { return mIsReusable; }
|
||||
|
||||
void setReusable(bool reusable) { mIsReusable = reusable; }
|
||||
|
||||
// comparing two notifications normally means comparing them by UUID (so we can look them
|
||||
// up quickly this way)
|
||||
bool operator<(const LLNotification& rhs) const
|
||||
|
|
@ -647,44 +688,17 @@ namespace LLNotificationFilters
|
|||
|
||||
namespace LLNotificationComparators
|
||||
{
|
||||
typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection;
|
||||
|
||||
// generic order functor that takes method or member variable reference
|
||||
template<typename T>
|
||||
struct orderBy
|
||||
struct orderByUUID
|
||||
{
|
||||
typedef boost::function<T (LLNotificationPtr)> field_t;
|
||||
orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {}
|
||||
bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
|
||||
{
|
||||
if (mDirection == ORDER_DECREASING)
|
||||
{
|
||||
return mField(lhs) > mField(rhs);
|
||||
}
|
||||
else
|
||||
{
|
||||
return mField(lhs) < mField(rhs);
|
||||
}
|
||||
return lhs->id() < rhs->id();
|
||||
}
|
||||
|
||||
field_t mField;
|
||||
EDirection mDirection;
|
||||
};
|
||||
|
||||
struct orderByUUID : public orderBy<const LLUUID&>
|
||||
{
|
||||
orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {}
|
||||
};
|
||||
|
||||
struct orderByDate : public orderBy<const LLDate&>
|
||||
{
|
||||
orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {}
|
||||
};
|
||||
};
|
||||
|
||||
typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
|
||||
typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
|
||||
typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet;
|
||||
typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
|
||||
typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
|
||||
|
||||
// ========================================================
|
||||
|
|
@ -705,12 +719,14 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
|
|||
// all of the built-in tests should attach to the "Visible" channel
|
||||
//
|
||||
class LLNotificationChannelBase :
|
||||
public LLEventTrackable
|
||||
public LLEventTrackable,
|
||||
public LLRefCount
|
||||
{
|
||||
LOG_CLASS(LLNotificationChannelBase);
|
||||
public:
|
||||
LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) :
|
||||
mFilter(filter), mItems(comp)
|
||||
LLNotificationChannelBase(LLNotificationFilter filter)
|
||||
: mFilter(filter),
|
||||
mItems()
|
||||
{}
|
||||
virtual ~LLNotificationChannelBase() {}
|
||||
// you can also connect to a Channel, so you can be notified of
|
||||
|
|
@ -776,6 +792,9 @@ protected:
|
|||
virtual void onDelete(LLNotificationPtr p) {}
|
||||
virtual void onChange(LLNotificationPtr p) {}
|
||||
|
||||
virtual void onFilterPass(LLNotificationPtr p) {}
|
||||
virtual void onFilterFail(LLNotificationPtr p) {}
|
||||
|
||||
bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
|
||||
LLNotificationFilter mFilter;
|
||||
};
|
||||
|
|
@ -785,64 +804,53 @@ protected:
|
|||
// destroy it, but if it becomes necessary to do so, the shared_ptr model
|
||||
// will ensure that we don't leak resources.
|
||||
class LLNotificationChannel;
|
||||
typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
|
||||
typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;
|
||||
|
||||
// manages a list of notifications
|
||||
// Note that if this is ever copied around, we might find ourselves with multiple copies
|
||||
// of a queue with notifications being added to different nonequivalent copies. So we
|
||||
// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
|
||||
//
|
||||
// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to
|
||||
// do something like:
|
||||
// LLNotificationChannel::buildChannel("name", "parent"...);
|
||||
// This returns an LLNotificationChannelPtr, which you can store, or
|
||||
// you can then retrieve the channel by using the registry:
|
||||
// LLNotifications::instance().getChannel("name")...
|
||||
// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.
|
||||
//
|
||||
class LLNotificationChannel :
|
||||
boost::noncopyable,
|
||||
public LLNotificationChannelBase
|
||||
public LLNotificationChannelBase,
|
||||
public LLInstanceTracker<LLNotificationChannel, std::string>
|
||||
{
|
||||
LOG_CLASS(LLNotificationChannel);
|
||||
|
||||
public:
|
||||
// Notification Channels have a filter, which determines which notifications
|
||||
// will be added to this channel.
|
||||
// Channel filters cannot change.
|
||||
struct Params : public LLInitParam::Block<Params>
|
||||
{
|
||||
Mandatory<std::string> name;
|
||||
Optional<LLNotificationFilter> filter;
|
||||
Multiple<std::string> sources;
|
||||
};
|
||||
|
||||
LLNotificationChannel(const Params& p = Params());
|
||||
LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter);
|
||||
|
||||
virtual ~LLNotificationChannel() {}
|
||||
typedef LLNotificationSet::iterator Iterator;
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
std::string getParentChannelName() { return mParent; }
|
||||
|
||||
void connectToChannel(const std::string& channel_name);
|
||||
|
||||
bool isEmpty() const;
|
||||
S32 size() const;
|
||||
|
||||
Iterator begin();
|
||||
Iterator end();
|
||||
size_t size();
|
||||
|
||||
// Channels have a comparator to control sort order;
|
||||
// the default sorts by arrival date
|
||||
void setComparator(LLNotificationComparator comparator);
|
||||
|
||||
std::string summarize();
|
||||
|
||||
// factory method for constructing these channels; since they're self-registering,
|
||||
// we want to make sure that you can't use new to make them
|
||||
static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent,
|
||||
LLNotificationFilter filter=LLNotificationFilters::includeEverything,
|
||||
LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
|
||||
|
||||
protected:
|
||||
// Notification Channels have a filter, which determines which notifications
|
||||
// will be added to this channel.
|
||||
// Channel filters cannot change.
|
||||
// Channels have a protected constructor so you can't make smart pointers that don't
|
||||
// come from our internal reference; call NotificationChannel::build(args)
|
||||
LLNotificationChannel(const std::string& name, const std::string& parent,
|
||||
LLNotificationFilter filter, LLNotificationComparator comparator);
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mParent;
|
||||
LLNotificationComparator mComparator;
|
||||
};
|
||||
|
||||
// An interface class to provide a clean linker seam to the LLNotifications class.
|
||||
|
|
@ -925,10 +933,6 @@ public:
|
|||
|
||||
void createDefaultChannels();
|
||||
|
||||
typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
|
||||
ChannelMap mChannels;
|
||||
|
||||
void addChannel(LLNotificationChannelPtr pChan);
|
||||
LLNotificationChannelPtr getChannel(const std::string& channelName);
|
||||
|
||||
std::string getGlobalString(const std::string& key) const;
|
||||
|
|
@ -966,7 +970,7 @@ private:
|
|||
|
||||
bool mIgnoreAllNotifications;
|
||||
|
||||
boost::scoped_ptr<LLNotificationsListener> mListener;
|
||||
std::vector<LLNotificationChannelPtr> mDefaultChannels;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -979,7 +983,7 @@ private:
|
|||
* 1 create class derived from LLPostponedNotification;
|
||||
* 2 call LLPostponedNotification::add method;
|
||||
*/
|
||||
class LLPostponedNotification
|
||||
class LLPostponedNotification : public LLMortician
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
|
@ -997,26 +1001,38 @@ public:
|
|||
thiz->mParams = params;
|
||||
|
||||
// Avoid header file dependency on llcachename.h
|
||||
lookupName(thiz, id, is_group);
|
||||
thiz->lookupName(id, is_group);
|
||||
}
|
||||
|
||||
private:
|
||||
static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group);
|
||||
void lookupName(const LLUUID& id, bool is_group);
|
||||
// only used for groups
|
||||
void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
|
||||
// only used for avatars
|
||||
void fetchAvatarName(const LLUUID& id);
|
||||
void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
|
||||
// used for both group and avatar names
|
||||
void finalizeName(const std::string& name);
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
delete this;
|
||||
die();
|
||||
}
|
||||
|
||||
protected:
|
||||
LLPostponedNotification() {}
|
||||
virtual ~LLPostponedNotification() {}
|
||||
LLPostponedNotification()
|
||||
: mParams(),
|
||||
mName(),
|
||||
mAvatarNameCacheConnection()
|
||||
{}
|
||||
|
||||
virtual ~LLPostponedNotification()
|
||||
{
|
||||
if (mAvatarNameCacheConnection.connected())
|
||||
{
|
||||
mAvatarNameCacheConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method provides possibility to modify notification parameters and
|
||||
|
|
@ -1027,6 +1043,58 @@ protected:
|
|||
|
||||
LLNotification::Params mParams;
|
||||
std::string mName;
|
||||
boost::signals2::connection mAvatarNameCacheConnection;
|
||||
};
|
||||
|
||||
// Stores only persistent notifications.
|
||||
// Class users can use connectChanged() to process persistent notifications
|
||||
// (see LLPersistentNotificationStorage for example).
|
||||
class LLPersistentNotificationChannel : public LLNotificationChannel
|
||||
{
|
||||
LOG_CLASS(LLPersistentNotificationChannel);
|
||||
public:
|
||||
LLPersistentNotificationChannel()
|
||||
: LLNotificationChannel("Persistent", "Visible", ¬ificationFilter)
|
||||
{
|
||||
}
|
||||
|
||||
typedef std::vector<LLNotificationPtr> history_list_t;
|
||||
history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
|
||||
history_list_t::iterator endHistory() { return mHistory.end(); }
|
||||
|
||||
private:
|
||||
|
||||
struct sortByTime
|
||||
{
|
||||
S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b)
|
||||
{
|
||||
return a->getDate() < b->getDate();
|
||||
}
|
||||
};
|
||||
|
||||
void sortHistory()
|
||||
{
|
||||
std::sort(mHistory.begin(), mHistory.end(), sortByTime());
|
||||
}
|
||||
|
||||
|
||||
// The channel gets all persistent notifications except those that have been canceled
|
||||
static bool notificationFilter(LLNotificationPtr pNotification)
|
||||
{
|
||||
bool handle_notification = false;
|
||||
|
||||
handle_notification = pNotification->isPersistent()
|
||||
&& !pNotification->isCancelled();
|
||||
|
||||
return handle_notification;
|
||||
}
|
||||
|
||||
void onAdd(LLNotificationPtr p)
|
||||
{
|
||||
mHistory.push_back(p);
|
||||
}
|
||||
|
||||
std::vector<LLNotificationPtr> mHistory;
|
||||
};
|
||||
|
||||
#endif//LL_LLNOTIFICATIONS_H
|
||||
|
|
|
|||
|
|
@ -1,354 +0,0 @@
|
|||
/**
|
||||
* @file llnotificationslistener.cpp
|
||||
* @author Brad Kittenbrink
|
||||
* @date 2009-07-08
|
||||
* @brief Implementation for llnotificationslistener.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llnotificationslistener.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llnotificationtemplate.h"
|
||||
#include "llsd.h"
|
||||
#include "llui.h"
|
||||
|
||||
LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
|
||||
LLEventAPI("LLNotifications",
|
||||
"LLNotifications listener to (e.g.) pop up a notification"),
|
||||
mNotifications(notifications)
|
||||
{
|
||||
add("requestAdd",
|
||||
"Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
|
||||
"If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
|
||||
&LLNotificationsListener::requestAdd);
|
||||
add("listChannels",
|
||||
"Post to [\"reply\"] a map of info on existing channels",
|
||||
&LLNotificationsListener::listChannels,
|
||||
LLSD().with("reply", LLSD()));
|
||||
add("listChannelNotifications",
|
||||
"Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
|
||||
&LLNotificationsListener::listChannelNotifications,
|
||||
LLSD().with("reply", LLSD()).with("channel", LLSD()));
|
||||
add("respond",
|
||||
"Respond to notification [\"uuid\"] with data in [\"response\"]",
|
||||
&LLNotificationsListener::respond,
|
||||
LLSD().with("uuid", LLSD()));
|
||||
add("cancel",
|
||||
"Cancel notification [\"uuid\"]",
|
||||
&LLNotificationsListener::cancel,
|
||||
LLSD().with("uuid", LLSD()));
|
||||
add("ignore",
|
||||
"Ignore future notification [\"name\"]\n"
|
||||
"(from <notification name= > in notifications.xml)\n"
|
||||
"according to boolean [\"ignore\"].\n"
|
||||
"If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
|
||||
"Note that ignored notifications are not forwarded unless intercepted before\n"
|
||||
"the \"Ignore\" channel.",
|
||||
&LLNotificationsListener::ignore);
|
||||
add("forward",
|
||||
"Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
|
||||
"according to boolean [\"forward\"]. When enabled, only types matching\n"
|
||||
"[\"types\"] are forwarded, as follows:\n"
|
||||
"omitted or undefined: forward all notifications\n"
|
||||
"string: forward only the specific named [sig]type\n"
|
||||
"array of string: forward any notification matching any named [sig]type.\n"
|
||||
"When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
|
||||
"notification.",
|
||||
&LLNotificationsListener::forward,
|
||||
LLSD().with("channel", LLSD()));
|
||||
}
|
||||
|
||||
// This is here in the .cpp file so we don't need the definition of class
|
||||
// Forwarder in the header file.
|
||||
LLNotificationsListener::~LLNotificationsListener()
|
||||
{
|
||||
}
|
||||
|
||||
void LLNotificationsListener::requestAdd(const LLSD& event_data) const
|
||||
{
|
||||
if(event_data.has("reply"))
|
||||
{
|
||||
mNotifications.add(event_data["name"],
|
||||
event_data["substitutions"],
|
||||
event_data["payload"],
|
||||
boost::bind(&LLNotificationsListener::NotificationResponder,
|
||||
this,
|
||||
event_data["reply"].asString(),
|
||||
_1, _2
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
mNotifications.add(event_data["name"],
|
||||
event_data["substitutions"],
|
||||
event_data["payload"]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNotificationsListener::NotificationResponder(const std::string& reply_pump,
|
||||
const LLSD& notification,
|
||||
const LLSD& response) const
|
||||
{
|
||||
LLSD reponse_event;
|
||||
reponse_event["notification"] = notification;
|
||||
reponse_event["response"] = response;
|
||||
LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
|
||||
}
|
||||
|
||||
void LLNotificationsListener::listChannels(const LLSD& params) const
|
||||
{
|
||||
LLReqID reqID(params);
|
||||
LLSD response(reqID.makeResponse());
|
||||
for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
|
||||
cmend(mNotifications.mChannels.end());
|
||||
cmi != cmend; ++cmi)
|
||||
{
|
||||
LLSD channelInfo;
|
||||
channelInfo["parent"] = cmi->second->getParentChannelName();
|
||||
response[cmi->first] = channelInfo;
|
||||
}
|
||||
LLEventPumps::instance().obtain(params["reply"]).post(response);
|
||||
}
|
||||
|
||||
void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
|
||||
{
|
||||
LLReqID reqID(params);
|
||||
LLSD response(reqID.makeResponse());
|
||||
LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
|
||||
if (channel)
|
||||
{
|
||||
LLSD notifications(LLSD::emptyArray());
|
||||
for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
|
||||
ni != nend; ++ni)
|
||||
{
|
||||
notifications.append(asLLSD(*ni));
|
||||
}
|
||||
response["notifications"] = notifications;
|
||||
}
|
||||
LLEventPumps::instance().obtain(params["reply"]).post(response);
|
||||
}
|
||||
|
||||
void LLNotificationsListener::respond(const LLSD& params) const
|
||||
{
|
||||
LLNotificationPtr notification(mNotifications.find(params["uuid"]));
|
||||
if (notification)
|
||||
{
|
||||
notification->respond(params["response"]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNotificationsListener::cancel(const LLSD& params) const
|
||||
{
|
||||
LLNotificationPtr notification(mNotifications.find(params["uuid"]));
|
||||
if (notification)
|
||||
{
|
||||
mNotifications.cancel(notification);
|
||||
}
|
||||
}
|
||||
|
||||
void LLNotificationsListener::ignore(const LLSD& params) const
|
||||
{
|
||||
// Calling a method named "ignore", but omitting its "ignore" Boolean
|
||||
// argument, should by default cause something to be ignored. Explicitly
|
||||
// pass ["ignore"] = false to cancel ignore.
|
||||
bool ignore = true;
|
||||
if (params.has("ignore"))
|
||||
{
|
||||
ignore = params["ignore"].asBoolean();
|
||||
}
|
||||
// This method can be used to affect either a single notification name or
|
||||
// all future notifications. The two use substantially different mechanisms.
|
||||
if (params["name"].isDefined())
|
||||
{
|
||||
// ["name"] was passed: ignore just that notification
|
||||
LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
|
||||
if (templatep)
|
||||
{
|
||||
templatep->mForm->setIgnored(ignore);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no ["name"]: ignore all future notifications
|
||||
mNotifications.setIgnoreAllNotifications(ignore);
|
||||
}
|
||||
}
|
||||
|
||||
class LLNotificationsListener::Forwarder: public LLEventTrackable
|
||||
{
|
||||
LOG_CLASS(LLNotificationsListener::Forwarder);
|
||||
public:
|
||||
Forwarder(LLNotifications& llnotifications, const std::string& channel):
|
||||
mNotifications(llnotifications),
|
||||
mRespond(false)
|
||||
{
|
||||
// Connect to the specified channel on construction. Because
|
||||
// LLEventTrackable is a base, we should automatically disconnect when
|
||||
// destroyed.
|
||||
LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
|
||||
if (channelptr)
|
||||
{
|
||||
// Insert our processing as a "passed filter" listener. This way
|
||||
// we get to run before all the "changed" listeners, and we get to
|
||||
// swipe it (hide it from the other listeners) if desired.
|
||||
channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
|
||||
}
|
||||
}
|
||||
|
||||
void setPumpName(const std::string& name) { mPumpName = name; }
|
||||
void setTypes(const LLSD& types) { mTypes = types; }
|
||||
void setRespond(bool respond) { mRespond = respond; }
|
||||
|
||||
private:
|
||||
bool handle(const LLSD& notification) const;
|
||||
bool matchType(const LLSD& filter, const std::string& type) const;
|
||||
|
||||
LLNotifications& mNotifications;
|
||||
std::string mPumpName;
|
||||
LLSD mTypes;
|
||||
bool mRespond;
|
||||
};
|
||||
|
||||
void LLNotificationsListener::forward(const LLSD& params)
|
||||
{
|
||||
std::string channel(params["channel"]);
|
||||
// First decide whether we're supposed to start forwarding or stop it.
|
||||
// Default to true.
|
||||
bool forward = true;
|
||||
if (params.has("forward"))
|
||||
{
|
||||
forward = params["forward"].asBoolean();
|
||||
}
|
||||
if (! forward)
|
||||
{
|
||||
// This is a request to stop forwarding notifications on the specified
|
||||
// channel. The rest of the params don't matter.
|
||||
// Because mForwarders contains scoped_ptrs, erasing the map entry
|
||||
// DOES delete the heap Forwarder object. Because Forwarder derives
|
||||
// from LLEventTrackable, destroying it disconnects it from the
|
||||
// channel.
|
||||
mForwarders.erase(channel);
|
||||
return;
|
||||
}
|
||||
// From here on, we know we're being asked to start (or modify) forwarding
|
||||
// on the specified channel. Find or create an appropriate Forwarder.
|
||||
ForwarderMap::iterator
|
||||
entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
|
||||
if (! entry->second)
|
||||
{
|
||||
entry->second.reset(new Forwarder(mNotifications, channel));
|
||||
}
|
||||
// Now, whether this Forwarder is brand-new or not, update it with the new
|
||||
// request info.
|
||||
Forwarder& fwd(*entry->second);
|
||||
fwd.setPumpName(params["pump"]);
|
||||
fwd.setTypes(params["types"]);
|
||||
fwd.setRespond(params["respond"]);
|
||||
}
|
||||
|
||||
bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
|
||||
if (notification["sigtype"].asString() == "delete")
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
|
||||
// let other listeners see the "delete" operation
|
||||
return false;
|
||||
}
|
||||
LLNotificationPtr note(mNotifications.find(notification["id"]));
|
||||
if (! note)
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
if (! matchType(mTypes, note->getType()))
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
|
||||
// We're not supposed to intercept this particular notification. Let
|
||||
// other listeners process it.
|
||||
return false;
|
||||
}
|
||||
LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
|
||||
// This is a notification we care about. Forward it through specified
|
||||
// LLEventPump.
|
||||
LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
|
||||
// Are we also being asked to auto-respond?
|
||||
if (mRespond)
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
|
||||
note->respond(LLSD::emptyMap());
|
||||
// Did that succeed in removing the notification? Only cancel() if
|
||||
// it's still around -- otherwise we get an LL_ERRS crash!
|
||||
note = mNotifications.find(notification["id"]);
|
||||
if (note)
|
||||
{
|
||||
LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
|
||||
mNotifications.cancel(note);
|
||||
}
|
||||
}
|
||||
// If we've auto-responded to this notification, then it's going to be
|
||||
// deleted. Other listeners would get the change operation, try to look it
|
||||
// up and be baffled by lookup failure. So when we auto-respond, suppress
|
||||
// this notification: don't pass it to other listeners.
|
||||
return mRespond;
|
||||
}
|
||||
|
||||
bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
|
||||
{
|
||||
// Decide whether this notification matches filter:
|
||||
// undefined: forward all notifications
|
||||
if (filter.isUndefined())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// array of string: forward any notification matching any named type
|
||||
if (filter.isArray())
|
||||
{
|
||||
for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
|
||||
ti != tend; ++ti)
|
||||
{
|
||||
if (ti->asString() == type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Didn't match any entry in the array
|
||||
return false;
|
||||
}
|
||||
// string: forward only the specific named type
|
||||
return (filter.asString() == type);
|
||||
}
|
||||
|
||||
LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
|
||||
{
|
||||
LLSD notificationInfo(note->asLLSD());
|
||||
// For some reason the following aren't included in LLNotification::asLLSD().
|
||||
notificationInfo["summary"] = note->summarize();
|
||||
notificationInfo["id"] = note->id();
|
||||
notificationInfo["type"] = note->getType();
|
||||
notificationInfo["message"] = note->getMessage();
|
||||
notificationInfo["label"] = note->getLabel();
|
||||
return notificationInfo;
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/**
|
||||
* @file llnotificationslistener.h
|
||||
* @author Brad Kittenbrink
|
||||
* @date 2009-07-08
|
||||
* @brief Wrap subset of LLNotifications API in event API for test scripts.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* 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;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLNOTIFICATIONSLISTENER_H
|
||||
#define LL_LLNOTIFICATIONSLISTENER_H
|
||||
|
||||
#include "lleventapi.h"
|
||||
#include "llnotificationptr.h"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class LLNotifications;
|
||||
class LLSD;
|
||||
|
||||
class LLNotificationsListener : public LLEventAPI
|
||||
{
|
||||
public:
|
||||
LLNotificationsListener(LLNotifications & notifications);
|
||||
~LLNotificationsListener();
|
||||
|
||||
private:
|
||||
void requestAdd(LLSD const & event_data) const;
|
||||
|
||||
void NotificationResponder(const std::string& replypump,
|
||||
const LLSD& notification,
|
||||
const LLSD& response) const;
|
||||
|
||||
void listChannels(const LLSD& params) const;
|
||||
void listChannelNotifications(const LLSD& params) const;
|
||||
void respond(const LLSD& params) const;
|
||||
void cancel(const LLSD& params) const;
|
||||
void ignore(const LLSD& params) const;
|
||||
void forward(const LLSD& params);
|
||||
|
||||
static LLSD asLLSD(LLNotificationPtr);
|
||||
|
||||
class Forwarder;
|
||||
typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
|
||||
ForwarderMap mForwarders;
|
||||
LLNotifications & mNotifications;
|
||||
};
|
||||
|
||||
#endif // LL_LLNOTIFICATIONSLISTENER_H
|
||||
|
|
@ -49,7 +49,6 @@
|
|||
//#include "llfunctorregistry.h"
|
||||
//#include "llpointer.h"
|
||||
#include "llinitparam.h"
|
||||
//#include "llnotificationslistener.h"
|
||||
//#include "llnotificationptr.h"
|
||||
//#include "llcachename.h"
|
||||
#include "llnotifications.h"
|
||||
|
|
@ -61,6 +60,18 @@ typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
|
|||
// from the appropriate local language directory).
|
||||
struct LLNotificationTemplate
|
||||
{
|
||||
struct CombineBehaviorNames
|
||||
: public LLInitParam::TypeValuesHelper<LLNotification::ECombineBehavior, CombineBehaviorNames>
|
||||
{
|
||||
static void declareValues()
|
||||
{
|
||||
declare("replace_with_new", LLNotification::REPLACE_WITH_NEW);
|
||||
declare("keep_old", LLNotification::KEEP_OLD);
|
||||
declare("cancel_old", LLNotification::CANCEL_OLD);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct GlobalString : public LLInitParam::Block<GlobalString>
|
||||
{
|
||||
Mandatory<std::string> name,
|
||||
|
|
@ -94,9 +105,11 @@ struct LLNotificationTemplate
|
|||
Optional<LLInitParam::Flag> dummy_val;
|
||||
public:
|
||||
Multiple<UniquenessContext> contexts;
|
||||
Optional<LLNotification::ECombineBehavior, CombineBehaviorNames> combine;
|
||||
|
||||
UniquenessConstraint()
|
||||
: contexts("context"),
|
||||
combine("combine", LLNotification::REPLACE_WITH_NEW),
|
||||
dummy_val("")
|
||||
{}
|
||||
};
|
||||
|
|
@ -183,7 +196,10 @@ struct LLNotificationTemplate
|
|||
struct Params : public LLInitParam::Block<Params>
|
||||
{
|
||||
Mandatory<std::string> name;
|
||||
Optional<bool> persist;
|
||||
Optional<bool> persist,
|
||||
log_to_im,
|
||||
show_toast,
|
||||
log_to_chat;
|
||||
Optional<std::string> functor,
|
||||
icon,
|
||||
label,
|
||||
|
|
@ -204,6 +220,9 @@ struct LLNotificationTemplate
|
|||
Params()
|
||||
: name("name"),
|
||||
persist("persist", false),
|
||||
log_to_im("log_to_im", false),
|
||||
show_toast("show_toast", true),
|
||||
log_to_chat("log_to_chat", true),
|
||||
functor("functor"),
|
||||
icon("icon"),
|
||||
label("label"),
|
||||
|
|
@ -262,6 +281,7 @@ struct LLNotificationTemplate
|
|||
// (used for things like progress indications, or repeating warnings
|
||||
// like "the grid is going down in N minutes")
|
||||
bool mUnique;
|
||||
LLNotification::ECombineBehavior mCombineBehavior;
|
||||
// if we want to be unique only if a certain part of the payload or substitutions args
|
||||
// are constant specify the field names for the payload. The notification will only be
|
||||
// combined if all of the fields named in the context are identical in the
|
||||
|
|
@ -302,12 +322,15 @@ struct LLNotificationTemplate
|
|||
LLNotificationFormPtr mForm;
|
||||
// default priority for notifications of this type
|
||||
ENotificationPriority mPriority;
|
||||
// UUID of the audio file to be played when this notification arrives
|
||||
// this is loaded as a name, but looked up to get the UUID upon template load.
|
||||
// If null, it wasn't specified.
|
||||
LLUUID mSoundEffect;
|
||||
// Stores the sound name which can then be used to play the sound using make_ui_sound
|
||||
std::string mSoundName;
|
||||
// List of tags that rules can match against.
|
||||
std::list<std::string> mTags;
|
||||
|
||||
// inject these notifications into chat/IM streams
|
||||
bool mLogToChat;
|
||||
bool mLogToIM;
|
||||
bool mShowToast;
|
||||
};
|
||||
|
||||
#endif //LL_LLNOTIFICATION_TEMPLATE_H
|
||||
|
|
|
|||
|
|
@ -45,7 +45,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
|
|||
mSide( p.side ),
|
||||
mSnappingEnabled(p.snapping_enabled),
|
||||
mAllowDoubleClickSnapping(p.allow_double_click_snapping),
|
||||
mResizingView(p.resizing_view)
|
||||
mResizingView(p.resizing_view),
|
||||
mResizeListener(NULL)
|
||||
{
|
||||
setFollowsNone();
|
||||
// set up some generically good follow code.
|
||||
|
|
@ -300,6 +301,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
}
|
||||
|
||||
if (mResizeListener)
|
||||
{
|
||||
mResizeListener(NULL);
|
||||
}
|
||||
|
||||
return handled;
|
||||
} // end LLResizeBar::handleHover
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
|
||||
void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
|
||||
bool canResize() { return getEnabled() && mMaxSize > mMinSize; }
|
||||
void setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
|
||||
|
||||
private:
|
||||
S32 mDragLastScreenX;
|
||||
|
|
@ -84,6 +85,7 @@ private:
|
|||
BOOL mSnappingEnabled;
|
||||
BOOL mAllowDoubleClickSnapping;
|
||||
LLView* mResizingView;
|
||||
boost::function<void(void*)> mResizeListener;
|
||||
};
|
||||
|
||||
#endif // LL_RESIZEBAR_H
|
||||
|
|
|
|||
|
|
@ -1841,7 +1841,7 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
|
|||
{
|
||||
LLAvatarName av_name;
|
||||
LLAvatarNameCache::get(LLUUID(id), &av_name);
|
||||
name = av_name.getLegacyName();
|
||||
name = av_name.getAccountName();
|
||||
}
|
||||
LLUrlAction::copyURLToClipboard(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()
|
|||
: label_width("label_width"),
|
||||
decimal_digits("decimal_digits"),
|
||||
allow_text_entry("allow_text_entry", true),
|
||||
allow_digits_only("allow_digits_only", false),
|
||||
label_wrap("label_wrap", false),
|
||||
text_enabled_color("text_enabled_color"),
|
||||
text_disabled_color("text_disabled_color"),
|
||||
|
|
@ -129,6 +130,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
|
|||
params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
|
||||
mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
|
||||
mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
|
||||
if (p.allow_digits_only)
|
||||
{
|
||||
mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace);
|
||||
}
|
||||
//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
|
||||
// than when it doesn't. Instead, if you always have to double click to select all the text,
|
||||
// it's easier to understand
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public:
|
|||
Optional<S32> label_width;
|
||||
Optional<U32> decimal_digits;
|
||||
Optional<bool> allow_text_entry;
|
||||
Optional<bool> allow_digits_only;
|
||||
Optional<bool> label_wrap;
|
||||
|
||||
Optional<LLUIColor> text_enabled_color;
|
||||
|
|
|
|||
|
|
@ -506,8 +506,8 @@ void LLTabContainer::draw()
|
|||
}
|
||||
}
|
||||
|
||||
mPrevArrowBtn->setFlashing(FALSE);
|
||||
mNextArrowBtn->setFlashing(FALSE);
|
||||
mPrevArrowBtn->setFlashing(false);
|
||||
mNextArrowBtn->setFlashing(false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1209,7 +1209,11 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
|
|||
update_images(mTabList[mTabList.size()-2], mLastTabParams, getTabPosition());
|
||||
}
|
||||
|
||||
removeChild( tuple->mButton );
|
||||
if (!getTabsHidden())
|
||||
{
|
||||
// We need to remove tab buttons only if the tabs are not hidden.
|
||||
removeChild( tuple->mButton );
|
||||
}
|
||||
delete tuple->mButton;
|
||||
|
||||
removeChild( tuple->mTabPanel );
|
||||
|
|
@ -1479,6 +1483,8 @@ BOOL LLTabContainer::setTab(S32 which)
|
|||
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
|
||||
{
|
||||
LLTabTuple* tuple = *iter;
|
||||
if (!tuple)
|
||||
continue;
|
||||
BOOL is_selected = ( tuple == selected_tuple );
|
||||
tuple->mButton->setUseEllipses(mUseTabEllipses);
|
||||
tuple->mButton->setHAlign(mFontHalign);
|
||||
|
|
|
|||
|
|
@ -188,10 +188,11 @@ public:
|
|||
void selectFirstTab();
|
||||
void selectLastTab();
|
||||
void selectNextTab();
|
||||
void selectPrevTab();
|
||||
void selectPrevTab();
|
||||
BOOL selectTabPanel( LLPanel* child );
|
||||
BOOL selectTab(S32 which);
|
||||
BOOL selectTabByName(const std::string& title);
|
||||
void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
|
||||
|
||||
BOOL getTabPanelFlashing(LLPanel* child);
|
||||
void setTabPanelFlashing(LLPanel* child, BOOL state);
|
||||
|
|
@ -242,8 +243,6 @@ private:
|
|||
|
||||
void setTabsHidden(BOOL hidden) { mTabsHidden = hidden; }
|
||||
BOOL getTabsHidden() const { return mTabsHidden; }
|
||||
|
||||
void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
|
||||
|
||||
void scrollPrev() { mScrollPos = llmax(0, mScrollPos-1); } // No wrap
|
||||
void scrollNext() { mScrollPos = llmin(mScrollPos+1, mMaxScrollPos); } // No wrap
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
const F32 CURSOR_FLASH_DELAY = 1.0f; // in seconds
|
||||
const S32 CURSOR_THICKNESS = 2;
|
||||
const F32 TRIPLE_CLICK_INTERVAL = 0.3f; // delay between double and triple click.
|
||||
|
||||
LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num)
|
||||
: mDocIndexStart(index_start),
|
||||
|
|
@ -145,6 +146,7 @@ LLTextBase::Params::Params()
|
|||
: cursor_color("cursor_color"),
|
||||
text_color("text_color"),
|
||||
text_readonly_color("text_readonly_color"),
|
||||
text_tentative_color("text_tentative_color"),
|
||||
bg_visible("bg_visible", false),
|
||||
border_visible("border_visible", false),
|
||||
bg_readonly_color("bg_readonly_color"),
|
||||
|
|
@ -179,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
|
|||
: LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
|
||||
mURLClickSignal(NULL),
|
||||
mMaxTextByteLength( p.max_text_length ),
|
||||
mDefaultFont(p.font),
|
||||
mFont(p.font),
|
||||
mFontShadow(p.font_shadow),
|
||||
mPopupMenu(NULL),
|
||||
mReadOnly(p.read_only),
|
||||
|
|
@ -190,6 +192,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
|
|||
mFgColor(p.text_color),
|
||||
mBorderVisible( p.border_visible ),
|
||||
mReadOnlyFgColor(p.text_readonly_color),
|
||||
mTentativeFgColor(p.text_tentative_color()),
|
||||
mWriteableBgColor(p.bg_writeable_color),
|
||||
mReadOnlyBgColor(p.bg_readonly_color),
|
||||
mFocusBgColor(p.bg_focus_color),
|
||||
|
|
@ -319,21 +322,26 @@ bool LLTextBase::truncate()
|
|||
return did_truncate;
|
||||
}
|
||||
|
||||
const LLStyle::Params& LLTextBase::getDefaultStyleParams()
|
||||
const LLStyle::Params& LLTextBase::getStyleParams()
|
||||
{
|
||||
//FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html
|
||||
//and eliminate color member values
|
||||
if (mStyleDirty)
|
||||
{
|
||||
mDefaultStyle
|
||||
mStyle
|
||||
.color(LLUIColor(&mFgColor)) // pass linked color instead of copy of mFGColor
|
||||
.readonly_color(LLUIColor(&mReadOnlyFgColor))
|
||||
.selected_color(LLUIColor(&mTextSelectedColor))
|
||||
.font(mDefaultFont)
|
||||
.font(mFont)
|
||||
.drop_shadow(mFontShadow);
|
||||
mStyleDirty = false;
|
||||
}
|
||||
return mDefaultStyle;
|
||||
return mStyle;
|
||||
}
|
||||
|
||||
void LLTextBase::beforeValueChange()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLTextBase::onValueChange(S32 start, S32 end)
|
||||
|
|
@ -351,6 +359,7 @@ void LLTextBase::drawSelectionBackground()
|
|||
|
||||
S32 selection_left = llmin( mSelectionStart, mSelectionEnd );
|
||||
S32 selection_right = llmax( mSelectionStart, mSelectionEnd );
|
||||
LLRect selection_rect = mVisibleTextRect;
|
||||
|
||||
// Skip through the lines we aren't drawing.
|
||||
LLRect content_display_rect = getVisibleDocumentRect();
|
||||
|
|
@ -512,8 +521,8 @@ void LLTextBase::drawCursor()
|
|||
LLRect screen_pos = calcScreenRect();
|
||||
LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) );
|
||||
|
||||
ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
|
||||
ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
|
||||
ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
|
||||
ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
|
||||
getWindow()->setLanguageTextInput( ime_pos );
|
||||
}
|
||||
}
|
||||
|
|
@ -521,11 +530,17 @@ void LLTextBase::drawCursor()
|
|||
|
||||
void LLTextBase::drawText()
|
||||
{
|
||||
const S32 text_len = getLength();
|
||||
if( text_len <= 0 )
|
||||
S32 text_len = getLength();
|
||||
|
||||
if (text_len <= 0 && mLabel.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (useLabel())
|
||||
{
|
||||
text_len = mLabel.getWString().length();
|
||||
}
|
||||
|
||||
S32 selection_left = -1;
|
||||
S32 selection_right = -1;
|
||||
// Draw selection even if we don't have keyboard focus for search/replace
|
||||
|
|
@ -591,7 +606,8 @@ void LLTextBase::drawText()
|
|||
|
||||
// Find the start of the first word
|
||||
U32 word_start = seg_start, word_end = -1;
|
||||
while ( (word_start < wstrText.length()) && (!LLStringOps::isAlpha(wstrText[word_start])) )
|
||||
U32 text_length = wstrText.length();
|
||||
while ( (word_start < text_length) && (!LLStringOps::isAlpha(wstrText[word_start])) )
|
||||
{
|
||||
word_start++;
|
||||
}
|
||||
|
|
@ -613,11 +629,15 @@ void LLTextBase::drawText()
|
|||
break;
|
||||
}
|
||||
|
||||
// Don't process words shorter than 3 characters
|
||||
std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
|
||||
if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
|
||||
if (word_start < text_length && word_end <= text_length && word_end > word_start)
|
||||
{
|
||||
mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
|
||||
std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
|
||||
|
||||
// Don't process words shorter than 3 characters
|
||||
if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
|
||||
{
|
||||
mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
|
||||
}
|
||||
}
|
||||
|
||||
// Find the start of the next word
|
||||
|
|
@ -738,6 +758,8 @@ void LLTextBase::drawText()
|
|||
|
||||
S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::segment_vec_t* segments )
|
||||
{
|
||||
beforeValueChange();
|
||||
|
||||
S32 old_len = getLength(); // length() returns character length
|
||||
S32 insert_len = wstr.length();
|
||||
|
||||
|
|
@ -769,7 +791,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
|
|||
else
|
||||
{
|
||||
// create default editable segment to hold new text
|
||||
LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
|
||||
LLStyleConstSP sp(new LLStyle(getStyleParams()));
|
||||
default_segment = new LLNormalTextSegment( sp, pos, pos + insert_len, *this);
|
||||
}
|
||||
|
||||
|
|
@ -813,6 +835,8 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
|
|||
|
||||
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
|
||||
{
|
||||
|
||||
beforeValueChange();
|
||||
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
|
||||
while(seg_iter != mSegments.end())
|
||||
{
|
||||
|
|
@ -871,6 +895,8 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
|
|||
|
||||
S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
|
||||
{
|
||||
beforeValueChange();
|
||||
|
||||
if (pos > (S32)getLength())
|
||||
{
|
||||
return 0;
|
||||
|
|
@ -889,7 +915,7 @@ void LLTextBase::createDefaultSegment()
|
|||
// ensures that there is always at least one segment
|
||||
if (mSegments.empty())
|
||||
{
|
||||
LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
|
||||
LLStyleConstSP sp(new LLStyle(getStyleParams()));
|
||||
LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
|
||||
mSegments.insert(default_segment);
|
||||
default_segment->linkToDocument(this);
|
||||
|
|
@ -979,6 +1005,13 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
|
|||
|
||||
BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
// handle triple click
|
||||
if (!mTripleClickTimer.hasExpired())
|
||||
{
|
||||
selectAll();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
|
||||
if (cur_segment && cur_segment->handleMouseDown(x, y, mask))
|
||||
{
|
||||
|
|
@ -1053,6 +1086,7 @@ BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask)
|
|||
|
||||
BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
|
||||
LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
|
||||
if (cur_segment && cur_segment->handleDoubleClick(x, y, mask))
|
||||
{
|
||||
|
|
@ -1337,6 +1371,25 @@ void LLTextBase::onSpellCheckSettingsChange()
|
|||
mSpellCheckStart = mSpellCheckEnd = -1;
|
||||
}
|
||||
|
||||
void LLTextBase::onFocusReceived()
|
||||
{
|
||||
LLUICtrl::onFocusReceived();
|
||||
if (!getLength() && !mLabel.empty())
|
||||
{
|
||||
// delete label which is LLLabelTextSegment
|
||||
clearSegments();
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextBase::onFocusLost()
|
||||
{
|
||||
LLUICtrl::onFocusLost();
|
||||
if (!getLength() && !mLabel.empty())
|
||||
{
|
||||
resetLabel();
|
||||
}
|
||||
}
|
||||
|
||||
// Sets the scrollbar from the cursor position
|
||||
void LLTextBase::updateScrollFromCursor()
|
||||
{
|
||||
|
|
@ -1923,7 +1976,7 @@ static LLFastTimer::DeclareTimer FTM_PARSE_HTML("Parse HTML");
|
|||
void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
|
||||
{
|
||||
LLStyle::Params style_params(input_params);
|
||||
style_params.fillFrom(getDefaultStyleParams());
|
||||
style_params.fillFrom(getStyleParams());
|
||||
|
||||
S32 part = (S32)LLTextParser::WHOLE;
|
||||
if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
|
||||
|
|
@ -2008,6 +2061,44 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
|
|||
appendTextImpl(new_text,input_params);
|
||||
}
|
||||
|
||||
void LLTextBase::setLabel(const LLStringExplicit& label)
|
||||
{
|
||||
mLabel = label;
|
||||
resetLabel();
|
||||
}
|
||||
|
||||
BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& text )
|
||||
{
|
||||
mLabel.setArg(key, text);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLTextBase::resetLabel()
|
||||
{
|
||||
if (useLabel())
|
||||
{
|
||||
clearSegments();
|
||||
|
||||
LLStyle* style = new LLStyle(getStyleParams());
|
||||
style->setColor(mTentativeFgColor);
|
||||
LLStyleConstSP sp(style);
|
||||
|
||||
LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, mLabel.getWString().length() + 1, *this);
|
||||
insertSegment(label);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLTextBase::useLabel()
|
||||
{
|
||||
return !getLength() && !mLabel.empty() && !hasFocus();
|
||||
}
|
||||
|
||||
void LLTextBase::setFont(const LLFontGL* font)
|
||||
{
|
||||
mFont = font;
|
||||
mStyleDirty = true;
|
||||
}
|
||||
|
||||
void LLTextBase::needsReflow(S32 index)
|
||||
{
|
||||
lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl;
|
||||
|
|
@ -2238,6 +2329,7 @@ const LLWString& LLTextBase::getWText() const
|
|||
S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const
|
||||
{
|
||||
// Figure out which line we're nearest to.
|
||||
LLRect visible_region = getVisibleDocumentRect();
|
||||
LLRect doc_rect = mDocumentView->getRect();
|
||||
|
||||
S32 doc_y = local_y - doc_rect.mBottom;
|
||||
|
|
@ -2397,7 +2489,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
|
|||
{
|
||||
// return default height rect in upper left
|
||||
local_rect = content_window_rect;
|
||||
local_rect.mBottom = local_rect.mTop - mDefaultFont->getLineHeight();
|
||||
local_rect.mBottom = local_rect.mTop - mFont->getLineHeight();
|
||||
return local_rect;
|
||||
}
|
||||
|
||||
|
|
@ -2902,7 +2994,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
|
|||
{
|
||||
F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
|
||||
|
||||
const LLWString &text = mEditor.getWText();
|
||||
const LLWString &text = getWText();
|
||||
|
||||
F32 right_x = rect.mLeft;
|
||||
if (!mStyle->isVisible())
|
||||
|
|
@ -3065,7 +3157,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
|
|||
if (num_chars > 0)
|
||||
{
|
||||
height = mFontHeight;
|
||||
const LLWString &text = mEditor.getWText();
|
||||
const LLWString &text = getWText();
|
||||
// if last character is a newline, then return true, forcing line break
|
||||
width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
|
||||
}
|
||||
|
|
@ -3074,7 +3166,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
|
|||
|
||||
S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
|
||||
{
|
||||
const LLWString &text = mEditor.getWText();
|
||||
const LLWString &text = getWText();
|
||||
return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
|
||||
(F32)segment_local_x_coord,
|
||||
F32_MAX,
|
||||
|
|
@ -3084,7 +3176,7 @@ S32 LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
|
|||
|
||||
S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
|
||||
{
|
||||
const LLWString &text = mEditor.getWText();
|
||||
const LLWString &text = getWText();
|
||||
|
||||
LLUIImagePtr image = mStyle->getImage();
|
||||
if( image.notNull())
|
||||
|
|
@ -3120,7 +3212,7 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
|
|||
S32 last_char_in_run = mStart + segment_offset + num_chars;
|
||||
// check length first to avoid indexing off end of string
|
||||
if (last_char_in_run < mEnd
|
||||
&& (last_char_in_run >= mEditor.getLength() ))
|
||||
&& (last_char_in_run >= getLength()))
|
||||
{
|
||||
num_chars++;
|
||||
}
|
||||
|
|
@ -3138,6 +3230,39 @@ void LLNormalTextSegment::dump() const
|
|||
llendl;
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
const LLWString& LLNormalTextSegment::getWText() const
|
||||
{
|
||||
return mEditor.getWText();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
const S32 LLNormalTextSegment::getLength() const
|
||||
{
|
||||
return mEditor.getLength();
|
||||
}
|
||||
|
||||
LLLabelTextSegment::LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor )
|
||||
: LLNormalTextSegment(style, start, end, editor)
|
||||
{
|
||||
}
|
||||
|
||||
LLLabelTextSegment::LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible)
|
||||
: LLNormalTextSegment(color, start, end, editor, is_visible)
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
const LLWString& LLLabelTextSegment::getWText() const
|
||||
{
|
||||
return mEditor.getWlabel();
|
||||
}
|
||||
/*virtual*/
|
||||
const S32 LLLabelTextSegment::getLength() const
|
||||
{
|
||||
return mEditor.getWlabel().length();
|
||||
}
|
||||
|
||||
//
|
||||
// LLOnHoverChangeableTextSegment
|
||||
//
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ class LLNormalTextSegment : public LLTextSegment
|
|||
public:
|
||||
LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
|
||||
LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
|
||||
~LLNormalTextSegment();
|
||||
virtual ~LLNormalTextSegment();
|
||||
|
||||
/*virtual*/ bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
|
||||
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
|
||||
|
|
@ -131,6 +131,9 @@ public:
|
|||
protected:
|
||||
F32 drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
|
||||
|
||||
virtual const LLWString& getWText() const;
|
||||
virtual const S32 getLength() const;
|
||||
|
||||
protected:
|
||||
class LLTextBase& mEditor;
|
||||
LLStyleConstSP mStyle;
|
||||
|
|
@ -140,6 +143,21 @@ protected:
|
|||
boost::signals2::connection mImageLoadedConnection;
|
||||
};
|
||||
|
||||
// This text segment is the same as LLNormalTextSegment, the only difference
|
||||
// is that LLNormalTextSegment draws value of LLTextBase (LLTextBase::getWText()),
|
||||
// but LLLabelTextSegment draws label of the LLTextBase (LLTextBase::mLabel)
|
||||
class LLLabelTextSegment : public LLNormalTextSegment
|
||||
{
|
||||
public:
|
||||
LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
|
||||
LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
|
||||
|
||||
protected:
|
||||
|
||||
/*virtual*/ const LLWString& getWText() const;
|
||||
/*virtual*/ const S32 getLength() const;
|
||||
};
|
||||
|
||||
// Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment)
|
||||
class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
|
||||
{
|
||||
|
|
@ -251,6 +269,7 @@ public:
|
|||
Optional<LLUIColor> cursor_color,
|
||||
text_color,
|
||||
text_readonly_color,
|
||||
text_tentative_color,
|
||||
bg_readonly_color,
|
||||
bg_writeable_color,
|
||||
bg_focus_color,
|
||||
|
|
@ -314,6 +333,9 @@ public:
|
|||
/*virtual*/ BOOL canDeselect() const;
|
||||
/*virtual*/ void deselect();
|
||||
|
||||
virtual void onFocusReceived();
|
||||
virtual void onFocusLost();
|
||||
|
||||
// LLSpellCheckMenuHandler overrides
|
||||
/*virtual*/ bool getSpellCheck() const;
|
||||
|
||||
|
|
@ -351,6 +373,21 @@ public:
|
|||
const LLWString& getWText() const;
|
||||
|
||||
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
|
||||
|
||||
void setLabel(const LLStringExplicit& label);
|
||||
virtual BOOL setLabelArg(const std::string& key, const LLStringExplicit& text );
|
||||
|
||||
const std::string& getLabel() { return mLabel.getString(); }
|
||||
const LLWString& getWlabel() { return mLabel.getWString();}
|
||||
|
||||
/**
|
||||
* If label is set, draws text label (which is LLLabelTextSegment)
|
||||
* that is visible when no user text provided
|
||||
*/
|
||||
void resetLabel();
|
||||
|
||||
void setFont(const LLFontGL* font);
|
||||
|
||||
// force reflow of text
|
||||
void needsReflow(S32 index = 0);
|
||||
|
||||
|
|
@ -390,7 +427,7 @@ public:
|
|||
bool scrolledToStart();
|
||||
bool scrolledToEnd();
|
||||
|
||||
const LLFontGL* getDefaultFont() const { return mDefaultFont; }
|
||||
const LLFontGL* getFont() const { return mFont; }
|
||||
|
||||
virtual void appendLineBreakSegment(const LLStyle::Params& style_params);
|
||||
virtual void appendImageSegment(const LLStyle::Params& style_params);
|
||||
|
|
@ -464,7 +501,9 @@ protected:
|
|||
LLTextBase(const Params &p);
|
||||
virtual ~LLTextBase();
|
||||
void initFromParams(const Params& p);
|
||||
virtual void beforeValueChange();
|
||||
virtual void onValueChange(S32 start, S32 end);
|
||||
virtual bool useLabel();
|
||||
|
||||
// draw methods
|
||||
void drawSelectionBackground(); // draws the black box behind the selected text
|
||||
|
|
@ -490,7 +529,7 @@ protected:
|
|||
void createDefaultSegment();
|
||||
virtual void updateSegments();
|
||||
void insertSegment(LLTextSegmentPtr segment_to_insert);
|
||||
const LLStyle::Params& getDefaultStyleParams();
|
||||
const LLStyle::Params& getStyleParams();
|
||||
|
||||
// manage lines
|
||||
S32 getLineStart( S32 line ) const;
|
||||
|
|
@ -535,15 +574,16 @@ protected:
|
|||
LLRect mTextBoundingRect;
|
||||
|
||||
// default text style
|
||||
LLStyle::Params mDefaultStyle;
|
||||
LLStyle::Params mStyle;
|
||||
bool mStyleDirty;
|
||||
const LLFontGL* const mDefaultFont; // font that is used when none specified, can only be set by constructor
|
||||
const LLFontGL::ShadowType mFontShadow; // shadow style, can only be set by constructor
|
||||
const LLFontGL* mFont;
|
||||
const LLFontGL::ShadowType mFontShadow;
|
||||
|
||||
// colors
|
||||
LLUIColor mCursorColor;
|
||||
LLUIColor mFgColor;
|
||||
LLUIColor mReadOnlyFgColor;
|
||||
LLUIColor mTentativeFgColor;
|
||||
LLUIColor mWriteableBgColor;
|
||||
LLUIColor mReadOnlyBgColor;
|
||||
LLUIColor mFocusBgColor;
|
||||
|
|
@ -558,7 +598,8 @@ protected:
|
|||
// selection
|
||||
S32 mSelectionStart;
|
||||
S32 mSelectionEnd;
|
||||
|
||||
LLTimer mTripleClickTimer;
|
||||
|
||||
BOOL mIsSelecting; // Are we in the middle of a drag-select?
|
||||
|
||||
// spell checking
|
||||
|
|
@ -587,6 +628,7 @@ protected:
|
|||
bool mClip; // clip text to widget rect
|
||||
bool mClipPartial; // false if we show lines that are partially inside bounding rect
|
||||
bool mPlainText; // didn't use Image or Icon segments
|
||||
bool mAutoIndent;
|
||||
S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes
|
||||
|
||||
// support widgets
|
||||
|
|
@ -602,6 +644,7 @@ protected:
|
|||
// Fired when a URL link is clicked
|
||||
commit_signal_t* mURLClickSignal;
|
||||
|
||||
LLUIString mLabel; // text label that is visible when no user text provided
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -237,6 +237,7 @@ LLTextEditor::Params::Params()
|
|||
embedded_items("embedded_items", false),
|
||||
ignore_tab("ignore_tab", true),
|
||||
show_line_numbers("show_line_numbers", false),
|
||||
auto_indent("auto_indent", true),
|
||||
default_color("default_color"),
|
||||
commit_on_focus_lost("commit_on_focus_lost", false),
|
||||
show_context_menu("show_context_menu"),
|
||||
|
|
@ -247,11 +248,13 @@ LLTextEditor::Params::Params()
|
|||
|
||||
LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
|
||||
LLTextBase(p),
|
||||
mAutoreplaceCallback(),
|
||||
mBaseDocIsPristine(TRUE),
|
||||
mPristineCmd( NULL ),
|
||||
mLastCmd( NULL ),
|
||||
mDefaultColor( p.default_color() ),
|
||||
mShowLineNumbers ( p.show_line_numbers ),
|
||||
mAutoIndent(p.auto_indent),
|
||||
mCommitOnFocusLost( p.commit_on_focus_lost),
|
||||
mAllowEmbeddedItems( p.embedded_items ),
|
||||
mMouseDownX(0),
|
||||
|
|
@ -260,7 +263,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
|
|||
mPrevalidateFunc(p.prevalidate_callback()),
|
||||
mContextMenu(NULL),
|
||||
mShowContextMenu(p.show_context_menu),
|
||||
mEnableTooltipPaste(p.enable_tooltip_paste)
|
||||
mEnableTooltipPaste(p.enable_tooltip_paste),
|
||||
mPassDelete(FALSE)
|
||||
{
|
||||
mSourceID.generate();
|
||||
|
||||
|
|
@ -1096,7 +1100,25 @@ void LLTextEditor::addChar(llwchar wc)
|
|||
}
|
||||
|
||||
setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
|
||||
|
||||
if (!mReadOnly && mAutoreplaceCallback != NULL)
|
||||
{
|
||||
// autoreplace the text, if necessary
|
||||
S32 replacement_start;
|
||||
S32 replacement_length;
|
||||
LLWString replacement_string;
|
||||
S32 new_cursor_pos = mCursorPos;
|
||||
mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, getWText());
|
||||
|
||||
if (replacement_length > 0 || !replacement_string.empty())
|
||||
{
|
||||
remove(replacement_start, replacement_length, true);
|
||||
insert(replacement_start, replacement_string, false, LLTextSegmentPtr());
|
||||
setCursorPos(new_cursor_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLTextEditor::addLineBreakChar()
|
||||
{
|
||||
if( !getEnabled() )
|
||||
|
|
@ -1621,7 +1643,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
|
|||
{
|
||||
deleteSelection(FALSE);
|
||||
}
|
||||
autoIndent(); // TODO: make this optional
|
||||
if (mAutoIndent)
|
||||
{
|
||||
autoIndent();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1792,7 +1817,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
|
|||
// virtual
|
||||
BOOL LLTextEditor::canDoDelete() const
|
||||
{
|
||||
return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) );
|
||||
return !mReadOnly && ( !mPassDelete || ( hasSelection() || (mCursorPos < getLength())) );
|
||||
}
|
||||
|
||||
void LLTextEditor::doDelete()
|
||||
|
|
@ -2061,7 +2086,7 @@ void LLTextEditor::drawPreeditMarker()
|
|||
return;
|
||||
}
|
||||
|
||||
const S32 line_height = mDefaultFont->getLineHeight();
|
||||
const S32 line_height = mFont->getLineHeight();
|
||||
|
||||
S32 line_start = getLineStart(cur_line);
|
||||
S32 line_y = mVisibleTextRect.mTop - line_height;
|
||||
|
|
@ -2100,16 +2125,16 @@ void LLTextEditor::drawPreeditMarker()
|
|||
S32 preedit_left = mVisibleTextRect.mLeft;
|
||||
if (left > line_start)
|
||||
{
|
||||
preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start);
|
||||
preedit_left += mFont->getWidth(text, line_start, left - line_start);
|
||||
}
|
||||
S32 preedit_right = mVisibleTextRect.mLeft;
|
||||
if (right < line_end)
|
||||
{
|
||||
preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start);
|
||||
preedit_right += mFont->getWidth(text, line_start, right - line_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start);
|
||||
preedit_right += mFont->getWidth(text, line_start, line_end - line_start);
|
||||
}
|
||||
|
||||
if (mPreeditStandouts[i])
|
||||
|
|
@ -2783,11 +2808,11 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
|
|||
|
||||
const LLWString textString(getWText());
|
||||
const llwchar * const text = textString.c_str();
|
||||
const S32 line_height = mDefaultFont->getLineHeight();
|
||||
const S32 line_height = mFont->getLineHeight();
|
||||
|
||||
if (coord)
|
||||
{
|
||||
const S32 query_x = mVisibleTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start);
|
||||
const S32 query_x = mVisibleTextRect.mLeft + mFont->getWidth(text, current_line_start, query - current_line_start);
|
||||
const S32 query_y = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2;
|
||||
S32 query_screen_x, query_screen_y;
|
||||
localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y);
|
||||
|
|
@ -2799,17 +2824,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
|
|||
S32 preedit_left = mVisibleTextRect.mLeft;
|
||||
if (preedit_left_position > current_line_start)
|
||||
{
|
||||
preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
|
||||
preedit_left += mFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
|
||||
}
|
||||
|
||||
S32 preedit_right = mVisibleTextRect.mLeft;
|
||||
if (preedit_right_position < current_line_end)
|
||||
{
|
||||
preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
|
||||
preedit_right += mFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start);
|
||||
preedit_right += mFont->getWidth(text, current_line_start, current_line_end - current_line_start);
|
||||
}
|
||||
|
||||
const S32 preedit_top = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height;
|
||||
|
|
@ -2886,7 +2911,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
|
|||
|
||||
S32 LLTextEditor::getPreeditFontSize() const
|
||||
{
|
||||
return llround((F32)mDefaultFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
|
||||
return llround((F32)mFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
|
||||
}
|
||||
|
||||
BOOL LLTextEditor::isDirty() const
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ public:
|
|||
show_line_numbers,
|
||||
commit_on_focus_lost,
|
||||
show_context_menu,
|
||||
enable_tooltip_paste;
|
||||
enable_tooltip_paste,
|
||||
auto_indent;
|
||||
|
||||
//colors
|
||||
Optional<LLUIColor> default_color;
|
||||
|
|
@ -157,6 +158,11 @@ public:
|
|||
BOOL isPristine() const;
|
||||
BOOL allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
|
||||
|
||||
// Autoreplace (formerly part of LLLineEditor)
|
||||
typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
|
||||
autoreplace_callback_t mAutoreplaceCallback;
|
||||
void setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
|
||||
|
||||
//
|
||||
// Text manipulation
|
||||
//
|
||||
|
|
@ -203,6 +209,8 @@ public:
|
|||
void setShowContextMenu(bool show) { mShowContextMenu = show; }
|
||||
bool getShowContextMenu() const { return mShowContextMenu; }
|
||||
|
||||
void setPassDelete(BOOL b) { mPassDelete = b; }
|
||||
|
||||
protected:
|
||||
void showContextMenu(S32 x, S32 y);
|
||||
void drawPreeditMarker();
|
||||
|
|
@ -215,8 +223,8 @@ protected:
|
|||
S32 indentLine( S32 pos, S32 spaces );
|
||||
void unindentLineBeforeCloseBrace();
|
||||
|
||||
virtual BOOL handleSpecialKey(const KEY key, const MASK mask);
|
||||
BOOL handleNavigationKey(const KEY key, const MASK mask);
|
||||
BOOL handleSpecialKey(const KEY key, const MASK mask);
|
||||
BOOL handleSelectionKey(const KEY key, const MASK mask);
|
||||
BOOL handleControlKey(const KEY key, const MASK mask);
|
||||
|
||||
|
|
@ -280,6 +288,7 @@ protected:
|
|||
LLUIColor mDefaultColor;
|
||||
|
||||
BOOL mShowLineNumbers;
|
||||
bool mAutoIndent;
|
||||
|
||||
/*virtual*/ void updateSegments();
|
||||
void updateLinkSegments();
|
||||
|
|
@ -325,6 +334,7 @@ private:
|
|||
bool mShowContextMenu;
|
||||
bool mParseOnTheFly;
|
||||
bool mEnableTooltipPaste;
|
||||
bool mPassDelete;
|
||||
|
||||
LLUUID mSourceID;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ public:
|
|||
// its visibility off.
|
||||
bool toggleVisibility();
|
||||
|
||||
LLHandle<LLToggleableMenu> getHandle() { return getDerivedHandle<LLToggleableMenu>(); }
|
||||
|
||||
protected:
|
||||
bool mClosedByButtonClick;
|
||||
LLRect mButtonRect;
|
||||
|
|
|
|||
|
|
@ -868,8 +868,15 @@ void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
|
||||
void LLToolBar::createButtons()
|
||||
{
|
||||
std::set<LLUUID> set_flashing;
|
||||
|
||||
BOOST_FOREACH(LLToolBarButton* button, mButtons)
|
||||
{
|
||||
if (button->getFlashTimer() && button->getFlashTimer()->isFlashingInProgress())
|
||||
{
|
||||
set_flashing.insert(button->getCommandId().uuid());
|
||||
}
|
||||
|
||||
if (mButtonRemoveSignal)
|
||||
{
|
||||
(*mButtonRemoveSignal)(button);
|
||||
|
|
@ -892,6 +899,11 @@ void LLToolBar::createButtons()
|
|||
{
|
||||
(*mButtonAddSignal)(button);
|
||||
}
|
||||
|
||||
if (set_flashing.find(button->getCommandId().uuid()) != set_flashing.end())
|
||||
{
|
||||
button->setFlashing(true);
|
||||
}
|
||||
}
|
||||
mNeedsLayout = true;
|
||||
}
|
||||
|
|
@ -916,6 +928,7 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
|
|||
button_p.label = LLTrans::getString(commandp->labelRef());
|
||||
button_p.tool_tip = LLTrans::getString(commandp->tooltipRef());
|
||||
button_p.image_overlay = LLUI::getUIImage(commandp->icon());
|
||||
button_p.button_flash_enable = commandp->isFlashingAllowed();
|
||||
button_p.overwriteFrom(mButtonParams[mButtonType]);
|
||||
LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
|
||||
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
|
|||
mTextBox->setText(p.message());
|
||||
}
|
||||
|
||||
S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth());
|
||||
S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth() + 1);
|
||||
S32 text_height = mTextBox->getTextPixelHeight();
|
||||
mTextBox->reshape(text_width, text_height);
|
||||
if (mInfoButton)
|
||||
|
|
|
|||
1622
indra/llui/llui.cpp
1622
indra/llui/llui.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @file llui.h
|
||||
* @brief General static UI services.
|
||||
* @brief GL function declarations and other general static UI services.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
|
|
@ -24,36 +24,121 @@
|
|||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// All immediate-mode gl drawing should happen here.
|
||||
|
||||
#ifndef LL_LLUI_H
|
||||
#define LL_LLUI_H
|
||||
|
||||
#include "llpointer.h" // LLPointer<>
|
||||
#include "llrect.h"
|
||||
#include "llcontrol.h"
|
||||
#include "llcoord.h"
|
||||
#include "v2math.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llinitparam.h"
|
||||
#include "llregistry.h"
|
||||
#include "llrender2dutils.h"
|
||||
#include "llpointer.h"
|
||||
#include "lluicolor.h"
|
||||
#include "lluicolortable.h"
|
||||
#include "lluiimage.h"
|
||||
#include <boost/signals2.hpp>
|
||||
#include "lllazyvalue.h"
|
||||
#include "llframetimer.h"
|
||||
#include <limits>
|
||||
|
||||
// LLUIFactory
|
||||
#include "llsd.h"
|
||||
|
||||
// for initparam specialization
|
||||
#include "llfontgl.h"
|
||||
|
||||
|
||||
class LLColor4;
|
||||
class LLVector3;
|
||||
class LLVector2;
|
||||
class LLUIImage;
|
||||
class LLUUID;
|
||||
class LLWindow;
|
||||
class LLView;
|
||||
class LLHelp;
|
||||
|
||||
// UI colors
|
||||
extern const LLColor4 UI_VERTEX_COLOR;
|
||||
void make_ui_sound(const char* name);
|
||||
void make_ui_sound_deferred(const char * name);
|
||||
|
||||
BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
|
||||
void gl_state_for_2d(S32 width, S32 height);
|
||||
|
||||
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
|
||||
void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
|
||||
void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
|
||||
void gl_rect_2d_simple( S32 width, S32 height );
|
||||
|
||||
void gl_draw_x(const LLRect& rect, const LLColor4& color);
|
||||
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
|
||||
void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
|
||||
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
|
||||
void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
|
||||
void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
|
||||
void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
|
||||
void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
|
||||
|
||||
void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
|
||||
|
||||
void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
|
||||
void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
|
||||
void gl_deep_circle( F32 radius, F32 depth );
|
||||
void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
|
||||
void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
|
||||
void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
|
||||
void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
|
||||
|
||||
void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
|
||||
|
||||
void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f );
|
||||
|
||||
void gl_rect_2d_simple_tex( S32 width, S32 height );
|
||||
|
||||
// segmented rectangles
|
||||
|
||||
/*
|
||||
TL |______TOP_________| TR
|
||||
/| |\
|
||||
_/_|__________________|_\_
|
||||
L| | MIDDLE | |R
|
||||
_|_|__________________|_|_
|
||||
\ | BOTTOM | /
|
||||
BL\|__________________|/ BR
|
||||
| |
|
||||
*/
|
||||
|
||||
typedef enum e_rounded_edge
|
||||
{
|
||||
ROUNDED_RECT_LEFT = 0x1,
|
||||
ROUNDED_RECT_TOP = 0x2,
|
||||
ROUNDED_RECT_RIGHT = 0x4,
|
||||
ROUNDED_RECT_BOTTOM = 0x8,
|
||||
ROUNDED_RECT_ALL = 0xf
|
||||
}ERoundedEdge;
|
||||
|
||||
|
||||
void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
|
||||
void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
|
||||
void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
|
||||
|
||||
inline void gl_rect_2d( const LLRect& rect, BOOL filled )
|
||||
{
|
||||
gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
|
||||
}
|
||||
|
||||
inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
|
||||
{
|
||||
gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
|
||||
}
|
||||
|
||||
class LLImageProviderInterface;
|
||||
|
||||
|
|
@ -190,15 +275,16 @@ public:
|
|||
static void initClass(const settings_map_t& settings,
|
||||
LLImageProviderInterface* image_provider,
|
||||
LLUIAudioCallback audio_callback = NULL,
|
||||
LLUIAudioCallback deferred_audio_callback = NULL,
|
||||
const LLVector2 *scale_factor = NULL,
|
||||
const std::string& language = LLStringUtil::null);
|
||||
static void cleanupClass();
|
||||
static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
|
||||
|
||||
static void pushMatrix() { LLRender2D::pushMatrix(); }
|
||||
static void popMatrix() { LLRender2D::popMatrix(); }
|
||||
static void loadIdentity() { LLRender2D::loadIdentity(); }
|
||||
static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
|
||||
static void pushMatrix();
|
||||
static void popMatrix();
|
||||
static void loadIdentity();
|
||||
static void translate(F32 x, F32 y, F32 z = 0.0f);
|
||||
|
||||
static LLRect sDirtyRect;
|
||||
static BOOL sDirty;
|
||||
|
|
@ -243,13 +329,10 @@ public:
|
|||
static void getMousePositionScreen(S32 *x, S32 *y);
|
||||
static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
|
||||
static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
|
||||
static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; }
|
||||
static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); }
|
||||
static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
|
||||
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
|
||||
{ return LLRender2D::getUIImageByID(image_id, priority); }
|
||||
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
|
||||
{ return LLRender2D::getUIImage(name, priority); }
|
||||
static void setScaleFactor(const LLVector2& scale_factor);
|
||||
static void setLineWidth(F32 width);
|
||||
static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
|
||||
static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
|
||||
static LLVector2 getWindowSize();
|
||||
static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
|
||||
static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
|
||||
|
|
@ -278,10 +361,13 @@ public:
|
|||
//
|
||||
static settings_map_t sSettingGroups;
|
||||
static LLUIAudioCallback sAudioCallback;
|
||||
static LLUIAudioCallback sDeferredAudioCallback;
|
||||
static LLVector2 sGLScaleFactor;
|
||||
static LLWindow* sWindow;
|
||||
static LLView* sRootView;
|
||||
static LLHelp* sHelpImpl;
|
||||
private:
|
||||
static LLImageProviderInterface* sImageProvider;
|
||||
static std::vector<std::string> sXUIPaths;
|
||||
static LLFrameTimer sMouseIdleTimer;
|
||||
static add_popup_t sAddPopupFunc;
|
||||
|
|
@ -292,6 +378,18 @@ private:
|
|||
|
||||
// Moved LLLocalClipRect to lllocalcliprect.h
|
||||
|
||||
//RN: maybe this needs to moved elsewhere?
|
||||
class LLImageProviderInterface
|
||||
{
|
||||
protected:
|
||||
LLImageProviderInterface() {};
|
||||
virtual ~LLImageProviderInterface() {};
|
||||
public:
|
||||
virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
|
||||
virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
|
||||
virtual void cleanUp() = 0;
|
||||
};
|
||||
|
||||
class LLCallbackRegistry
|
||||
{
|
||||
public:
|
||||
|
|
@ -342,10 +440,8 @@ public:
|
|||
// even if their constructors have side effects
|
||||
void reference()
|
||||
{
|
||||
#ifdef LL_WINDOWS
|
||||
S32 dummy;
|
||||
dummy = 0;
|
||||
#endif /*LL_WINDOWS*/
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -413,7 +509,7 @@ public:
|
|||
namespace LLInitParam
|
||||
{
|
||||
template<>
|
||||
class ParamValue<LLRect, TypeValues<LLRect> >
|
||||
class ParamValue<LLRect>
|
||||
: public CustomParamValue<LLRect>
|
||||
{
|
||||
typedef CustomParamValue<LLRect> super_t;
|
||||
|
|
@ -432,7 +528,7 @@ namespace LLInitParam
|
|||
};
|
||||
|
||||
template<>
|
||||
class ParamValue<LLUIColor, TypeValues<LLUIColor> >
|
||||
class ParamValue<LLUIColor>
|
||||
: public CustomParamValue<LLUIColor>
|
||||
{
|
||||
typedef CustomParamValue<LLUIColor> super_t;
|
||||
|
|
@ -450,7 +546,7 @@ namespace LLInitParam
|
|||
};
|
||||
|
||||
template<>
|
||||
class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >
|
||||
class ParamValue<const LLFontGL*>
|
||||
: public CustomParamValue<const LLFontGL* >
|
||||
{
|
||||
typedef CustomParamValue<const LLFontGL*> super_t;
|
||||
|
|
@ -490,7 +586,7 @@ namespace LLInitParam
|
|||
|
||||
|
||||
template<>
|
||||
class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
|
||||
class ParamValue<LLCoordGL>
|
||||
: public CustomParamValue<LLCoordGL>
|
||||
{
|
||||
typedef CustomParamValue<LLCoordGL> super_t;
|
||||
|
|
@ -504,4 +600,7 @@ namespace LLInitParam
|
|||
};
|
||||
}
|
||||
|
||||
extern LLGLSLShader gSolidColorProgram;
|
||||
extern LLGLSLShader gUIProgram;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -247,13 +247,13 @@ const LLInitParam::BaseBlock& get_empty_param_block()
|
|||
|
||||
// adds a widget and its param block to various registries
|
||||
//static
|
||||
void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag)
|
||||
void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name)
|
||||
{
|
||||
// associate parameter block type with template .xml file
|
||||
std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type);
|
||||
if (existing_tag != NULL)
|
||||
std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type);
|
||||
if (existing_name != NULL)
|
||||
{
|
||||
if(*existing_tag != tag)
|
||||
if(*existing_name != name)
|
||||
{
|
||||
std::cerr << "Duplicate entry for T::Params, try creating empty param block in derived classes that inherit T::Params" << std::endl;
|
||||
// forcing crash here
|
||||
|
|
@ -262,19 +262,15 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st
|
|||
}
|
||||
else
|
||||
{
|
||||
// widget already registered
|
||||
// widget already registered this name
|
||||
return;
|
||||
}
|
||||
}
|
||||
LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag);
|
||||
|
||||
LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, name);
|
||||
//FIXME: comment this in when working on schema generation
|
||||
//LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type);
|
||||
//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>);
|
||||
}
|
||||
|
||||
//static
|
||||
const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type)
|
||||
{
|
||||
return LLWidgetNameRegistry::instance().getValue(widget_type);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ private:
|
|||
ParamDefaults()
|
||||
{
|
||||
// look up template file for this param block...
|
||||
const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
|
||||
const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
|
||||
if (param_block_tag)
|
||||
{ // ...and if it exists, back fill values using the most specific template first
|
||||
PARAM_BLOCK params;
|
||||
|
|
@ -132,7 +132,6 @@ public:
|
|||
template<typename T>
|
||||
static const typename T::Params& getDefaultParams()
|
||||
{
|
||||
//#pragma message("Generating ParamDefaults")
|
||||
return ParamDefaults<typename T::Params, 0>::instance().get();
|
||||
}
|
||||
|
||||
|
|
@ -285,8 +284,6 @@ private:
|
|||
}
|
||||
|
||||
|
||||
static const std::string* getWidgetTag(const std::type_info* widget_type);
|
||||
|
||||
// this exists to get around dependency on llview
|
||||
static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
// Project includes
|
||||
#include "lluiimage.h"
|
||||
#include "llrender2dutils.h"
|
||||
#include "llui.h"
|
||||
|
||||
LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
|
||||
: mName(name),
|
||||
|
|
@ -112,6 +112,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&
|
|||
drawSolid(border_rect, color);
|
||||
}
|
||||
|
||||
void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis,
|
||||
const LLRect& rect, const LLColor4& color)
|
||||
{
|
||||
F32 border_scale = 1.f;
|
||||
F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
|
||||
F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
|
||||
if (rect.getHeight() < border_height || rect.getWidth() < border_width)
|
||||
{
|
||||
if(border_height - rect.getHeight() > border_width - rect.getWidth())
|
||||
{
|
||||
border_scale = (F32)rect.getHeight() / border_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
border_scale = (F32)rect.getWidth() / border_width;
|
||||
}
|
||||
}
|
||||
|
||||
LLUI::pushMatrix();
|
||||
{
|
||||
LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis);
|
||||
LLUI::translate(rect_origin.mV[VX],
|
||||
rect_origin.mV[VY],
|
||||
rect_origin.mV[VZ]);
|
||||
gGL.getTexUnit(0)->bind(getImage());
|
||||
gGL.color4fv(color.mV);
|
||||
|
||||
LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
|
||||
mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
|
||||
mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
|
||||
mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
|
||||
gl_segmented_rect_3d_tex(mClipRegion,
|
||||
center_uv_rect,
|
||||
LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
|
||||
(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
|
||||
(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
|
||||
(border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
|
||||
rect.getWidth() * x_axis,
|
||||
rect.getHeight() * y_axis);
|
||||
|
||||
} LLUI::popMatrix();
|
||||
}
|
||||
|
||||
|
||||
S32 LLUIImage::getWidth() const
|
||||
{
|
||||
// return clipped dimensions of actual image area
|
||||
|
|
@ -155,7 +199,7 @@ void LLUIImage::onImageLoaded()
|
|||
|
||||
namespace LLInitParam
|
||||
{
|
||||
void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
|
||||
void ParamValue<LLUIImage*>::updateValueFromBlock()
|
||||
{
|
||||
// The keyword "none" is specifically requesting a null image
|
||||
// do not default to current value. Used to overwrite template images.
|
||||
|
|
@ -165,14 +209,14 @@ namespace LLInitParam
|
|||
return;
|
||||
}
|
||||
|
||||
LLUIImage* imagep = LLRender2D::getUIImage(name());
|
||||
LLUIImage* imagep = LLUI::getUIImage(name());
|
||||
if (imagep)
|
||||
{
|
||||
updateValue(imagep);
|
||||
}
|
||||
}
|
||||
|
||||
void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative)
|
||||
void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
|
||||
{
|
||||
if (getValue() == NULL)
|
||||
{
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue