diff --git a/Filtration/Extensions/EnumerationExtension.cs b/Filtration.Common/Extensions/EnumerationExtension.cs
similarity index 94%
rename from Filtration/Extensions/EnumerationExtension.cs
rename to Filtration.Common/Extensions/EnumerationExtension.cs
index 3498157..93630bd 100644
--- a/Filtration/Extensions/EnumerationExtension.cs
+++ b/Filtration.Common/Extensions/EnumerationExtension.cs
@@ -3,9 +3,9 @@ using System.ComponentModel;
using System.Linq;
using System.Windows.Markup;
-namespace Filtration.Extensions
+namespace Filtration.Common.Extensions
{
- internal class EnumerationExtension : MarkupExtension
+ public class EnumerationExtension : MarkupExtension
{
private Type _enumType;
diff --git a/Filtration/Extensions/HyperlinkExtensions.cs b/Filtration.Common/Extensions/HyperlinkExtensions.cs
similarity index 97%
rename from Filtration/Extensions/HyperlinkExtensions.cs
rename to Filtration.Common/Extensions/HyperlinkExtensions.cs
index fd46841..140236c 100644
--- a/Filtration/Extensions/HyperlinkExtensions.cs
+++ b/Filtration.Common/Extensions/HyperlinkExtensions.cs
@@ -4,7 +4,7 @@ using System.Windows;
using System.Windows.Documents;
using System.Windows.Navigation;
-namespace Filtration.Extensions
+namespace Filtration.Common.Extensions
{
public static class HyperlinkExtensions
{
diff --git a/Filtration.Common/Filtration.Common.csproj b/Filtration.Common/Filtration.Common.csproj
index 13f3165..38b47e8 100644
--- a/Filtration.Common/Filtration.Common.csproj
+++ b/Filtration.Common/Filtration.Common.csproj
@@ -75,6 +75,8 @@
+
+
diff --git a/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs b/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs
index 2a20555..6d8296c 100644
--- a/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs
+++ b/Filtration.ItemFilterPreview.Tests/Services/TestItemFilterProcessor.cs
@@ -67,6 +67,7 @@ namespace Filtration.ItemFilterPreview.Tests.Services
}
[Test]
+ [Ignore("Outdated item filter")]
public void ProcessItemsAgainstItemFilterScript_IntegrationTest()
{
//Arrange
@@ -102,6 +103,7 @@ namespace Filtration.ItemFilterPreview.Tests.Services
}
[Test]
+ [Ignore("Outdated item filter")]
public void ProcessItemsAgainstItemFilterScript_IntegrationTest_10Items()
{
//Arrange
diff --git a/Filtration.ObjectModel.Tests/Filtration.ObjectModel.Tests.csproj b/Filtration.ObjectModel.Tests/Filtration.ObjectModel.Tests.csproj
index 69dd6ef..62cfed3 100644
--- a/Filtration.ObjectModel.Tests/Filtration.ObjectModel.Tests.csproj
+++ b/Filtration.ObjectModel.Tests/Filtration.ObjectModel.Tests.csproj
@@ -66,6 +66,9 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Permanent
+ Temporary
+
+
+
+
+
+
diff --git a/Filtration/App.xaml.cs b/Filtration/App.xaml.cs
index 6690e58..624f22e 100644
--- a/Filtration/App.xaml.cs
+++ b/Filtration/App.xaml.cs
@@ -46,6 +46,12 @@ namespace Filtration
cfg.ConstructServicesUsing(_container.Resolve);
cfg.CreateMap().ConstructUsingServiceLocator();
cfg.CreateMap().ReverseMap();
+ cfg.CreateMap().ReverseMap();
+ cfg.CreateMap().ReverseMap();
+ cfg.CreateMap().ReverseMap();
+ cfg.CreateMap().ReverseMap();
+ cfg.CreateMap().ReverseMap();
+ cfg.CreateMap().ReverseMap();
cfg.CreateMap();
});
diff --git a/Filtration/Converters/AvailableThemeComponentsConverter.cs b/Filtration/Converters/AvailableThemeComponentsConverter.cs
index 0d4b3f3..e4c5d61 100644
--- a/Filtration/Converters/AvailableThemeComponentsConverter.cs
+++ b/Filtration/Converters/AvailableThemeComponentsConverter.cs
@@ -16,7 +16,7 @@ namespace Filtration.Converters
var themeComponentsList = values[0] as ThemeComponentCollection;
if (themeComponentsList == null || themeComponentsList.Count == 0) return null;
- var blockItem = values[1] as ColorBlockItem;
+ var blockItem = values[1] as BlockItemBase;
if (blockItem == null) return null;
ThemeComponentType themeComponentType;
@@ -33,6 +33,26 @@ namespace Filtration.Converters
{
themeComponentType = ThemeComponentType.BorderColor;
}
+ else if (blockItem.GetType() == typeof(FontSizeBlockItem))
+ {
+ themeComponentType = ThemeComponentType.FontSize;
+ }
+ else if (blockItem.GetType() == typeof(SoundBlockItem) || blockItem.GetType() == typeof(PositionalSoundBlockItem))
+ {
+ themeComponentType = ThemeComponentType.AlertSound;
+ }
+ else if (blockItem.GetType() == typeof(CustomSoundBlockItem))
+ {
+ themeComponentType = ThemeComponentType.CustomSound;
+ }
+ else if (blockItem.GetType() == typeof(MapIconBlockItem))
+ {
+ themeComponentType = ThemeComponentType.Icon;
+ }
+ else if (blockItem.GetType() == typeof(PlayEffectBlockItem))
+ {
+ themeComponentType = ThemeComponentType.Effect;
+ }
else
{
return null;
diff --git a/Filtration/Converters/IconShapeToSourceConverter.cs b/Filtration/Converters/IconShapeToSourceConverter.cs
new file mode 100644
index 0000000..c727045
--- /dev/null
+++ b/Filtration/Converters/IconShapeToSourceConverter.cs
@@ -0,0 +1,37 @@
+using Filtration.ObjectModel.Enums;
+using System;
+using System.Globalization;
+using System.Windows.Data;
+
+namespace Filtration.Converters
+{
+ internal class IconShapeToSourceConverter : IValueConverter
+ {
+ public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ var iconShape = (IconShape)(int)value;
+ switch (iconShape)
+ {
+ case IconShape.Circle:
+ return "/Filtration;component/Resources/DropIcons/Circle.png";
+ case IconShape.Diamond:
+ return "/Filtration;component/Resources/DropIcons/Diamond.png";
+ case IconShape.Hexagon:
+ return "/Filtration;component/Resources/DropIcons/Hexagon.png";
+ case IconShape.Square:
+ return "/Filtration;component/Resources/DropIcons/Square.png";
+ case IconShape.Star:
+ return "/Filtration;component/Resources/DropIcons/Star.png";
+ case IconShape.Triangle:
+ return "/Filtration;component/Resources/DropIcons/Triangle.png";
+ }
+
+ return "/Filtration;component/Resources/DropIcons/NoIcon.png";
+ }
+
+ public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Filtration/Converters/SizeColorToRectConverter.cs b/Filtration/Converters/SizeColorToRectConverter.cs
new file mode 100644
index 0000000..0be1814
--- /dev/null
+++ b/Filtration/Converters/SizeColorToRectConverter.cs
@@ -0,0 +1,33 @@
+using Filtration.ObjectModel.Enums;
+using System;
+using System.Globalization;
+using System.Windows;
+using System.Windows.Data;
+
+namespace Filtration.Converters
+{
+ internal class SizeColorToRectConverter : IMultiValueConverter
+ {
+ public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
+ {
+ var size = (int)(values[0]);
+ var color = (int)(values[1]);
+
+ if (size < 0 || color < 0)
+ return new Rect(0, 0, 0, 0);
+
+ Rect cropArea = new Rect();
+ cropArea.Width = 64;
+ cropArea.Height = 64;
+ cropArea.X = 0 + size * 64;
+ cropArea.Y = 0 + color * 64;
+
+ return cropArea;
+ }
+
+ public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Filtration/Filtration.csproj b/Filtration/Filtration.csproj
index 4e0f402..6a1ac98 100644
--- a/Filtration/Filtration.csproj
+++ b/Filtration/Filtration.csproj
@@ -167,11 +167,11 @@
+
+
-
-
@@ -190,6 +190,9 @@
EditableListBoxControl.xaml
+
+ ImageComboBoxControl.xaml
+
ItemPreviewControl.xaml
@@ -230,6 +233,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -538,6 +545,13 @@
+
+
+
+
+
+
+
diff --git a/Filtration/Resources/DropIcons/Circle.png b/Filtration/Resources/DropIcons/Circle.png
new file mode 100644
index 0000000..7b59891
Binary files /dev/null and b/Filtration/Resources/DropIcons/Circle.png differ
diff --git a/Filtration/Resources/DropIcons/Diamond.png b/Filtration/Resources/DropIcons/Diamond.png
new file mode 100644
index 0000000..ab917dd
Binary files /dev/null and b/Filtration/Resources/DropIcons/Diamond.png differ
diff --git a/Filtration/Resources/DropIcons/Hexagon.png b/Filtration/Resources/DropIcons/Hexagon.png
new file mode 100644
index 0000000..549fa94
Binary files /dev/null and b/Filtration/Resources/DropIcons/Hexagon.png differ
diff --git a/Filtration/Resources/DropIcons/NoIcon.png b/Filtration/Resources/DropIcons/NoIcon.png
new file mode 100644
index 0000000..fb56f36
Binary files /dev/null and b/Filtration/Resources/DropIcons/NoIcon.png differ
diff --git a/Filtration/Resources/DropIcons/Square.png b/Filtration/Resources/DropIcons/Square.png
new file mode 100644
index 0000000..9e143cf
Binary files /dev/null and b/Filtration/Resources/DropIcons/Square.png differ
diff --git a/Filtration/Resources/DropIcons/Star.png b/Filtration/Resources/DropIcons/Star.png
new file mode 100644
index 0000000..9158e90
Binary files /dev/null and b/Filtration/Resources/DropIcons/Star.png differ
diff --git a/Filtration/Resources/DropIcons/Triangle.png b/Filtration/Resources/DropIcons/Triangle.png
new file mode 100644
index 0000000..3d8d6d9
Binary files /dev/null and b/Filtration/Resources/DropIcons/Triangle.png differ
diff --git a/Filtration/Resources/ItemBaseTypes.txt b/Filtration/Resources/ItemBaseTypes.txt
index b056064..c978d72 100644
--- a/Filtration/Resources/ItemBaseTypes.txt
+++ b/Filtration/Resources/ItemBaseTypes.txt
@@ -1,5 +1,6 @@
A Mother's Parting Gift
Abandoned Wealth
+Aberrant Fossil
Abyssal Axe
Abyssal Cry
Abyssal Sceptre
@@ -10,6 +11,7 @@ Added Cold Damage Support
Added Fire Damage Support
Added Lightning Damage Support
Additional Accuracy Support
+Aetheric Fossil
Agate Amulet
Albino Rhoa Feather
Alchemy Shard
@@ -111,9 +113,11 @@ Battle Sword
Bazaar Map
Beach Map
Bear Trap
+Beauty Through Death
Behemoth Mace
Belfry Map
Bestel's Manuscript
+Bestiary Orb
Beyond Leaguestone
Binding Shard
Birth of the Three
@@ -131,6 +135,7 @@ Blast Rain
Blessed Orb
Blessing of Chayula
Blessing of Esh
+Blessing of God
Blessing of Tul
Blessing of Uul-Netol
Blessing of Xoph
@@ -146,6 +151,7 @@ Blood Raiment
Blood Sceptre
Bloodlines Leaguestone
Bloodlust Support
+Bloodstained Fossil
Blue Pearl Amulet
Blunt Arrow Quiver
Boarding Axe
@@ -159,9 +165,11 @@ Bone Helmet
Bone Offering
Bone Spirit Shield
Bonespire Talisman
+Boon of the First Ones
Boot Blade
Boot Knife
Bottled Storm
+Bound Fossil
Boundless Realms
Bowyer's Dream
Branded Kite Shield
@@ -244,6 +252,7 @@ Chaos Orb
Chaos Shard
Chaotic Disposition
Charged Dash
+Charged Traps Support
Chateau Map
Chayula's Breachstone
Chest Splitter
@@ -290,6 +299,7 @@ Conjurer Boots
Conjurer Gloves
Conjurer's Vestment
Conquest Chainmail
+Consecrated Path
Conservatory Map
Contagion
Controlled Destruction Support
@@ -306,6 +316,7 @@ Core Map
Coronal Leather
Coronal Maul
Corroded Blade
+Corroded Fossil
Corroded Tower Shield
Corrugated Buckler
Corsair Sword
@@ -385,6 +396,7 @@ Defiled Cathedral Map
Deicide Mask
Demon Dagger
Demon's Horn
+Dense Fossil
Desecrate
Desert Brigandine
Desert Map
@@ -460,6 +472,8 @@ Emperor of Purity
Emperor's Luck
Empower Support
Enameled Buckler
+Enchanted Fossil
+Encrusted Fossil
Endurance Charge on Melee Stun Support
Enduring Cry
Enfeeble
@@ -492,6 +506,7 @@ Exalted Orb
Exalted Shard
Excavation Map
Explosive Arrow
+Explosive Trap
Exquisite Blade
Exquisite Leather
Eye Gouger
@@ -504,6 +519,7 @@ Ezomyte Dagger
Ezomyte Spiked Shield
Ezomyte Staff
Ezomyte Tower Shield
+Faceted Fossil
Factory Map
Fancy Foil
Fangjaw Talisman
@@ -531,8 +547,10 @@ Flame Dash
Flame Surge
Flame Totem
Flameblast
+Flamethrower Trap
Flammability
Flanged Mace
+Flashpowder Keg
Flaying Knife
Flesh Offering
Fleshripper
@@ -540,11 +558,13 @@ Flicker Strike
Flooded Mine Map
Fluted Bascinet
Footman Sword
+Forbidden Power
Forge of the Phoenix Map
Fork Support
Fortify Support
Fossilised Spirit Shield
Foul Staff
+Fractured Fossil
Fragment of the Chimera
Fragment of the Hydra
Fragment of the Minotaur
@@ -554,6 +574,7 @@ Freezing Pulse
Frenzy
Fright Claw
Fright Maul
+Frigid Fossil
Frontier Leather
Frost Blades
Frost Bomb
@@ -583,6 +604,7 @@ Giant Mana Flask
Gift of the Gemling Queen
Gilded Axe
Gilded Buckler
+Gilded Fossil
Gilded Sallet
Girded Tower Shield
Glacial Cascade
@@ -595,6 +617,7 @@ Glassblower's Bauble
Glimmer of Hope
Glorious Leather
Glorious Plate
+Glyphic Fossil
Gnarled Branch
Goat's Horn
Goathide Boots
@@ -654,6 +677,7 @@ Harbinger's Orb
Harbinger's Shard
Harlequin Mask
Harmonic Spirit Shield
+Harmony of Souls
Harpy Rapier
Haste
Hatred
@@ -667,8 +691,10 @@ Heavy Quiver
Heavy Strike
Hellion's Paw
Her Mask
+Herald of Agony
Herald of Ash
Herald of Ice
+Herald of Purity
Herald of Thunder
Heterochromia
Hexclaw Talisman
@@ -676,6 +702,7 @@ Highborn Bow
Highborn Staff
Highland Blade
Hinekora's Hair
+Hollow Fossil
Holy Chainmail
Hook Sword
Hope
@@ -705,6 +732,7 @@ Ignite Proliferation Support
Imbued Wand
Immolate Support
Immortal Call
+Immortal Resolve
Imp Dagger
Imperial Bow
Imperial Buckler
@@ -712,6 +740,7 @@ Imperial Claw
Imperial Maul
Imperial Skean
Imperial Staff
+Imprinted Bestiary Orb
Incinerate
Increased Area of Effect Support
Increased Critical Damage Support
@@ -749,6 +778,7 @@ Jade Chopper
Jade Flask
Jade Hatchet
Jagged Foil
+Jagged Fossil
Jagged Maul
Jasper Axe
Jasper Chopper
@@ -813,6 +843,7 @@ Light Quiver
Lighthouse Map
Lightning Arrow
Lightning Penetration Support
+Lightning Spire Trap
Lightning Strike
Lightning Tendrils
Lightning Trap
@@ -832,6 +863,7 @@ Lordly Plate
Loricated Ringmail
Lost Worlds
Loyalty
+Lucent Fossil
Lucky Connections
Lucky Deck
Lunaris Circlet
@@ -873,6 +905,7 @@ Merciless Armament
Mesa Map
Mesh Boots
Mesh Gloves
+Metallic Fossil
Miasmeter
Midnight Blade
Might is Right
@@ -923,6 +956,7 @@ Muttering Essence of Woe
Nailed Fist
Necromancer Circlet
Necromancer Silks
+Necromancy Net
Necropolis Map
Nemesis Leaguestone
Nightmare Bascinet
@@ -983,12 +1017,13 @@ Penetrating Arrow Quiver
Peninsula Map
Perandus Coin
Perandus Leaguestone
+Perfect Fossil
+Perfection
Pernarch
Petrified Club
Phantasmagoria Map
Phantom Mace
Phase Run
-Physical Projectile Attack Damage Support
Physical to Lightning Support
Pier Map
Pierce Support
@@ -1018,19 +1053,29 @@ Port Map
Portal
Portal Scroll
Portal Shredder
+Potent Alchemical Resonator
+Potent Chaotic Resonator
Power Charge On Critical Support
Power Siphon
+Powerful Alchemical Resonator
+Powerful Chaotic Resonator
Praetor Crown
Precinct Map
Prehistoric Claw
Pride Before the Fall
Primal Skull Talisman
+Prime Alchemical Resonator
+Prime Chaotic Resonator
Primeval Rapier
+Primitive Alchemical Resonator
+Primitive Chaotic Resonator
Primitive Staff
Primordial Pool Map
Primordial Staff
+Prismatic Fossil
Prismatic Jewel
Prismatic Ring
+Pristine Fossil
Profane Wand
Projectile Weakness
Promenade Map
@@ -1082,7 +1127,10 @@ Regal Orb
Regal Shard
Regicide Mask
Reinforced Greaves
+Reinforced Iron Net
Reinforced Kite Shield
+Reinforced Rope Net
+Reinforced Steel Net
Reinforced Tower Shield
Rejuvenation Totem
Relic Chambers Map
@@ -1141,6 +1189,7 @@ Sambar Sceptre
Samite Gloves
Samite Helmet
Samite Slippers
+Sanctified Fossil
Sanctified Life Flask
Sanctified Mana Flask
Sand of Eternity
@@ -1157,7 +1206,9 @@ Scarlet Round Shield
Scholar Boots
Scholar of the Seas
Scholar's Robe
+Scorched Fossil
Scorching Ray
+Scourge Arrow
Screaming Essence
Screaming Essence of Anger
Screaming Essence of Anguish
@@ -1185,6 +1236,7 @@ Scroll of Wisdom
Searching Eye Jewel
Searing Bond
Secutor Helm
+Seismic Trap
Sekhem
Sekhema Feather
Sentinel Jacket
@@ -1195,6 +1247,7 @@ Serpentscale Boots
Serpentscale Gauntlets
Serrated Arrow Quiver
Serrated Foil
+Serrated Fossil
Shabby Jerkin
Shackled Boots
Shadow Axe
@@ -1204,7 +1257,6 @@ Shagreen Gloves
Shagreen Tower Shield
Shaper's Orb
Shaper's Orb (Tier 1)
-Shaper's Orb (Tier 10)
Shaper's Orb (Tier 2)
Shaper's Orb (Tier 3)
Shaper's Orb (Tier 4)
@@ -1213,6 +1265,7 @@ Shaper's Orb (Tier 6)
Shaper's Orb (Tier 7)
Shaper's Orb (Tier 8)
Shaper's Orb (Tier 9)
+Shaper's Orb (Tier 10)
Shard of Fate
Sharkskin Boots
Sharkskin Gloves
@@ -1248,6 +1301,7 @@ Shrieking Essence of Woe
Shrieking Essence of Wrath
Shrieking Essence of Zeal
Shrine Map
+Shuddering Fossil
Siege Axe
Siege Ballista
Siege Helmet
@@ -1264,8 +1318,12 @@ Silver Coin
Silver Flask
Silver Key
Silver Locket
+Simple Iron Net
Simple Robe
+Simple Rope Net
+Simple Steel Net
Sinner Tricorne
+Siphoning Trap
Skean
Skinning Knife
Slaughter Knife
@@ -1278,6 +1336,7 @@ Small Hybrid Flask
Small Life Flask
Small Mana Flask
Smallsword
+Smite
Smoke Mine
Sniper Bow
Solar Maul
@@ -1292,6 +1351,7 @@ Sovereign Spiked Shield
Spark
Sparkling Claw
Spectral Axe
+Spectral Shield Throw
Spectral Sword
Spectral Throw
Spell Cascade Support
@@ -1341,6 +1401,7 @@ Stibnite Flask
Stiletto
Stone Axe
Stone Hammer
+Stone of Passage
Storm Barrier Support
Storm Blade
Storm Burst
@@ -1349,6 +1410,9 @@ Strand Map
Strapped Boots
Strapped Leather
Strapped Mitts
+Strong Iron Net
+Strong Rope Net
+Strong Steel Net
Struck by Lightning
Studded Belt
Studded Round Shield
@@ -1359,8 +1423,10 @@ Sulphur Vents Map
Summit Map
Summon Chaos Golem
Summon Flame Golem
+Summon Holy Relic
Summon Ice Golem
Summon Lightning Golem
+Summon Phantasm on Kill Support
Summon Raging Spirit
Summon Skeleton
Summon Stone Golem
@@ -1375,8 +1441,10 @@ Sweep
Swift Affliction Support
Talisman Leaguestone
Talon Axe
+Tangled Fossil
Tarnished Spirit Shield
Teak Round Shield
+Tectonic Slam
Tempered Foil
Tempest Leaguestone
Tempest Shield
@@ -1386,38 +1454,50 @@ Tenderizer
Terrace Map
Terror Claw
Terror Maul
+Thaumaturgical Net
Thaumetic Emblem
Thaumetic Sulphite
+The Admirer
The Aesthete
The Arena Champion
+The Army of Blood
The Artist
The Avenger
The Battle Born
+The Beast
The Betrayal
The Black Flag
The Blazing Fire
The Body
+The Breach
The Brittle Emperor
+The Cacophony
The Calling
The Carrion Crow
The Cartographer
The Cataclysm
The Catalyst
The Celestial Justicar
+The Celestial Stone
The Chains that Bind
The Coming Storm
The Conduit
The Cursed King
The Dapper Prodigy
The Dark Mage
+The Darkest Dream
+The Deceiver
The Demoness
The Devastator
The Doctor
The Doppelganger
The Dragon
The Dragon's Heart
+The Dreamer
+The Dreamland
The Drunken Aristocrat
The Encroaching Darkness
+The Endless Darkness
The Endurance
The Enlightened
The Ethereal
@@ -1425,6 +1505,7 @@ The Explorer
The Eye of Desire
The Eye of Fury
The Eye of the Dragon
+The Fathomless Depths
The Feast
The Fiend
The Fletcher
@@ -1437,15 +1518,20 @@ The Garish Power
The Gemcutter
The Gentleman
The Gladiator
+The Hale Heart
The Harvester
The Hermit
The Hoarder
The Hunger
The Immortal
The Incantation
+The Innocent
The Inoculated
+The Insatiable
The Inventor
+The Iron Bard
The Jester
+The Jeweller's Boon
The King's Blade
The King's Heart
The Last One Standing
@@ -1454,9 +1540,12 @@ The Lion
The Lord in Black
The Lover
The Lunaris Priestess
+The Master
+The Mayor
The Mercenary
The Metalsmith's Gift
The Oath
+The Obscured
The Offering
The One With All
The Opulent
@@ -1466,17 +1555,23 @@ The Penitent
The Poet
The Polymath
The Porcupine
+The Price of Protection
+The Professor
+The Puzzle
The Queen
The Rabid Rhoa
The Realm
The Risk
+The Rite of Elements
The Road to Power
The Ruthless Ceinture
The Saint's Treasure
+The Samurai's Eye
The Scarred Meadow
The Scavenger
The Scholar
The Sephirot
+The Shaper's Key
The Sigil
The Siren
The Soul
@@ -1490,14 +1585,18 @@ The Sun
The Surgeon
The Surveyor
The Survivalist
+The Sword King's Salute
The Teardrop
The Thaumaturgist
The Throne
The Tower
The Traitor
The Trial
+The Twilight Moon
The Twins
The Tyrant
+The Undaunted
+The Undisputed
The Union
The Valkyrie
The Valley of Steel Boxes
@@ -1508,11 +1607,14 @@ The Warden
The Warlord
The Watcher
The Web
+The Wilted Rose
The Wind
+The Witch
The Wolf
The Wolf's Shadow
The Wolven King's Bite
The Wolverine
+The World Eater
The Wrath
The Wretched
Thicket Bow
@@ -1523,6 +1625,7 @@ Thorn Rapier
Three Faces in the Dark
Three Hands Talisman
Three Rat Talisman
+Three Voices
Thresher Claw
Throat Stabber
Thunderous Skies
@@ -1532,6 +1635,7 @@ Tiger's Paw
Timber Axe
Time-Lost Relic
Timeworn Claw
+Timeworn Reliquary Key
Titan Gauntlets
Titan Greaves
Titanium Spirit Shield
@@ -1547,6 +1651,7 @@ Torture Chamber Map
Totemic Maul
Tower Key
Tower Map
+Toxic Rain
Toxic Sewer Map
Tranquillity
Transmutation Shard
@@ -1587,9 +1692,12 @@ Unset Ring
Unshaping Orb
Ursine Pelt
Uul-Netol's Breachstone
+Vaal Ancestral Warchief
Vaal Arc
Vaal Axe
Vaal Blade
+Vaal Blade Vortex
+Vaal Blight
Vaal Breach
Vaal Buckler
Vaal Burning Arrow
@@ -1600,6 +1708,7 @@ Vaal Cyclone
Vaal Detonate Dead
Vaal Discipline
Vaal Double Strike
+Vaal Earthquake
Vaal Fireball
Vaal Flameblast
Vaal Gauntlets
@@ -1612,6 +1721,9 @@ Vaal Haste
Vaal Hatchet
Vaal Ice Nova
Vaal Immortal Call
+Vaal Impurity of Fire
+Vaal Impurity of Ice
+Vaal Impurity of Lightning
Vaal Lightning Strike
Vaal Lightning Trap
Vaal Lightning Warp
@@ -1640,7 +1752,17 @@ Vault Map
Velvet Gloves
Velvet Slippers
Vengeance
+Vial of Awakening
+Vial of Consequence
+Vial of Dominance
+Vial of Fate
Vial Of Power
+Vial of Sacrifice
+Vial of Summoning
+Vial of the Ghost
+Vial of the Ritual
+Vial of Transcendence
+Vicious Projectiles Support
Vigilant Strike
Vile Staff
Vile Toxins Support
@@ -1718,6 +1840,7 @@ Wild Leather
Wild Strike
Wings of Vastiri
Wither
+Withering Touch Support
Wolf Pelt
Woodful Staff
Woodsplitter
diff --git a/Filtration/Resources/ItemClasses.txt b/Filtration/Resources/ItemClasses.txt
index fd87671..d38526b 100644
--- a/Filtration/Resources/ItemClasses.txt
+++ b/Filtration/Resources/ItemClasses.txt
@@ -9,6 +9,7 @@ Bows
Claws
Currency
Daggers
+Delve Stackable Currency
Divination Card
Fishing Rods
Flasks
@@ -16,6 +17,7 @@ Gems
Gloves
Helmets
Hybrid Flasks
+Incursion Item
Jewel
Labyrinth Item
Labyrinth Map Item
diff --git a/Filtration/UserControls/BlockItemControl.xaml b/Filtration/UserControls/BlockItemControl.xaml
index c9dfba3..1a0d699 100644
--- a/Filtration/UserControls/BlockItemControl.xaml
+++ b/Filtration/UserControls/BlockItemControl.xaml
@@ -7,7 +7,7 @@
xmlns:commonConverters="clr-namespace:Filtration.Common.Converters;assembly=Filtration.Common"
xmlns:blockItemBaseTypes="clr-namespace:Filtration.ObjectModel.BlockItemBaseTypes;assembly=Filtration.ObjectModel"
xmlns:blockItemTypes="clr-namespace:Filtration.ObjectModel.BlockItemTypes;assembly=Filtration.ObjectModel"
- xmlns:extensions="clr-namespace:Filtration.Extensions"
+ xmlns:extensions="clr-namespace:Filtration.Common.Extensions;assembly=Filtration.Common"
xmlns:enums="clr-namespace:Filtration.ObjectModel.Enums;assembly=Filtration.ObjectModel"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:views="clr-namespace:Filtration.Views"
@@ -75,12 +75,39 @@
-
+
+
+
+
+
+
-
+
+
+
+
+
+ Permanent
+ Temporary
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -100,9 +127,21 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -113,6 +152,14 @@
+
+
+
+
+
+
+
+
@@ -124,8 +171,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Filtration/UserControls/BlockItemControl.xaml.cs b/Filtration/UserControls/BlockItemControl.xaml.cs
index 5af5c2f..db0909c 100644
--- a/Filtration/UserControls/BlockItemControl.xaml.cs
+++ b/Filtration/UserControls/BlockItemControl.xaml.cs
@@ -6,6 +6,8 @@ using System.Windows;
using Filtration.Annotations;
using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemBaseTypes;
+using Filtration.ObjectModel.Enums;
+using Filtration.ObjectModel.ThemeEditor;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf;
using Xceed.Wpf.Toolkit;
@@ -20,10 +22,10 @@ namespace Filtration.UserControls
// ReSharper disable once PossibleNullReferenceException
(Content as FrameworkElement).DataContext = this;
- SetBlockColorCommand = new RelayCommand(OnSetBlockColorCommmand);
+ SetBlockValueCommand = new RelayCommand(OnSetBlockValueCommmand);
}
- public RelayCommand SetBlockColorCommand { get; private set; }
+ public RelayCommand SetBlockValueCommand { get; private set; }
public static readonly DependencyProperty BlockItemProperty = DependencyProperty.Register(
"BlockItem",
@@ -88,12 +90,45 @@ namespace Filtration.UserControls
"ShFusing", "ShRegal", "ShVaal"
};
- private void OnSetBlockColorCommmand()
- {
- var blockItem = BlockItem as ColorBlockItem;
- if (blockItem?.ThemeComponent == null) return;
+ private void OnSetBlockValueCommmand()
+ {
+ var blockItemWithTheme = BlockItem as IBlockItemWithTheme;
+ if (blockItemWithTheme?.ThemeComponent == null) return;
- blockItem.Color = blockItem.ThemeComponent.Color;
+ var componentType = ((IBlockItemWithTheme)BlockItem).ThemeComponent.ComponentType;
+ switch(componentType)
+ {
+ case ThemeComponentType.BackgroundColor:
+ case ThemeComponentType.BorderColor:
+ case ThemeComponentType.TextColor:
+ var colorBlockItem = BlockItem as ColorBlockItem;
+ colorBlockItem.Color = ((ColorThemeComponent)colorBlockItem.ThemeComponent).Color;
+ break;
+ case ThemeComponentType.FontSize:
+ var integerBlockItem = BlockItem as IntegerBlockItem;
+ integerBlockItem.Value = ((IntegerThemeComponent)integerBlockItem.ThemeComponent).Value;
+ break;
+ case ThemeComponentType.AlertSound:
+ var strIntBlockItem = BlockItem as StrIntBlockItem;
+ strIntBlockItem.Value = ((StrIntThemeComponent)strIntBlockItem.ThemeComponent).Value;
+ strIntBlockItem.SecondValue = ((StrIntThemeComponent)strIntBlockItem.ThemeComponent).SecondValue;
+ break;
+ case ThemeComponentType.CustomSound:
+ var stringBlockItem = BlockItem as StringBlockItem;
+ stringBlockItem.Value = ((StringThemeComponent)stringBlockItem.ThemeComponent).Value;
+ break;
+ case ThemeComponentType.Icon:
+ var iconBlockItem = BlockItem as IconBlockItem;
+ iconBlockItem.Size = ((IconThemeComponent)iconBlockItem.ThemeComponent).IconSize;
+ iconBlockItem.Color = ((IconThemeComponent)iconBlockItem.ThemeComponent).IconColor;
+ iconBlockItem.Shape = ((IconThemeComponent)iconBlockItem.ThemeComponent).IconShape;
+ break;
+ case ThemeComponentType.Effect:
+ var effectColorBlockItem = BlockItem as EffectColorBlockItem;
+ effectColorBlockItem.Color = ((EffectColorThemeComponent)effectColorBlockItem.ThemeComponent).EffectColor;
+ effectColorBlockItem.Temporary = ((EffectColorThemeComponent)effectColorBlockItem.ThemeComponent).Temporary;
+ break;
+ }
}
public event PropertyChangedEventHandler PropertyChanged;
diff --git a/Filtration/UserControls/ImageComboBoxControl.xaml b/Filtration/UserControls/ImageComboBoxControl.xaml
new file mode 100644
index 0000000..88b1726
--- /dev/null
+++ b/Filtration/UserControls/ImageComboBoxControl.xaml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Filtration/UserControls/ImageComboBoxControl.xaml.cs b/Filtration/UserControls/ImageComboBoxControl.xaml.cs
new file mode 100644
index 0000000..0921355
--- /dev/null
+++ b/Filtration/UserControls/ImageComboBoxControl.xaml.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace Filtration.UserControls
+{
+ ///
+ /// Interaction logic for ImageComboBoxControl.xaml
+ ///
+ public partial class ImageComboBoxControl : UserControl
+ {
+ public ImageComboBoxControl()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/Filtration/UserControls/ItemPreviewControl.xaml b/Filtration/UserControls/ItemPreviewControl.xaml
index f9232fe..0ba9de4 100644
--- a/Filtration/UserControls/ItemPreviewControl.xaml
+++ b/Filtration/UserControls/ItemPreviewControl.xaml
@@ -8,7 +8,7 @@
d:DataContext="{d:DesignInstance Type=userControls:ItemPreviewControl}"
d:DesignHeight="35" d:DesignWidth="170">
-
+
diff --git a/Filtration/UserControls/NumericFilterPredicateControl.xaml b/Filtration/UserControls/NumericFilterPredicateControl.xaml
index 32ce079..8d8d03f 100644
--- a/Filtration/UserControls/NumericFilterPredicateControl.xaml
+++ b/Filtration/UserControls/NumericFilterPredicateControl.xaml
@@ -5,7 +5,7 @@
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:extensions="clr-namespace:Filtration.Extensions"
+ xmlns:extensions="clr-namespace:Filtration.Common.Extensions;assembly=Filtration.Common"
xmlns:userControls="clr-namespace:Filtration.UserControls"
xmlns:enums="clr-namespace:Filtration.ObjectModel.Enums;assembly=Filtration.ObjectModel"
mc:Ignorable="d"
diff --git a/Filtration/UserControls/ThemeComponentSelectionControl.xaml b/Filtration/UserControls/ThemeComponentSelectionControl.xaml
index 19d17ab..ae2f094 100644
--- a/Filtration/UserControls/ThemeComponentSelectionControl.xaml
+++ b/Filtration/UserControls/ThemeComponentSelectionControl.xaml
@@ -4,6 +4,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:userControls="clr-namespace:Filtration.UserControls"
+ xmlns:themeEditor="clr-namespace:Filtration.ObjectModel.ThemeEditor;assembly=Filtration.ObjectModel"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=userControls:ThemeComponentSelectionControl}"
@@ -21,7 +22,7 @@
-
+
@@ -32,44 +33,59 @@
Visibility="{Binding ShowThemeComponentComboBox, Converter={StaticResource BooleanToVisibilityConverter}}">
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/Filtration/ViewModels/ItemFilterBlockViewModel.cs b/Filtration/ViewModels/ItemFilterBlockViewModel.cs
index 5cf0c0c..ac2411a 100644
--- a/Filtration/ViewModels/ItemFilterBlockViewModel.cs
+++ b/Filtration/ViewModels/ItemFilterBlockViewModel.cs
@@ -2,14 +2,17 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
+using System.IO;
using System.Linq;
using System.Windows.Media;
using Filtration.ObjectModel;
using Filtration.ObjectModel.BlockItemBaseTypes;
using Filtration.ObjectModel.BlockItemTypes;
+using Filtration.ObjectModel.Enums;
using Filtration.Services;
using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf;
+using Microsoft.Win32;
using Xceed.Wpf.Toolkit;
namespace Filtration.ViewModels
@@ -28,6 +31,7 @@ namespace Filtration.ViewModels
private readonly IStaticDataService _staticDataService;
private readonly IReplaceColorsViewModel _replaceColorsViewModel;
private readonly MediaPlayer _mediaPlayer = new MediaPlayer();
+ public static ObservableCollection _customSoundsAvailable;
private bool _displaySettingsPopupOpen;
private bool _isExpanded;
@@ -47,6 +51,16 @@ namespace Filtration.ViewModels
SwitchBlockItemsViewCommand = new RelayCommand(OnSwitchBlockItemsViewCommand);
PlaySoundCommand = new RelayCommand(OnPlaySoundCommand, () => HasSound);
PlayPositionalSoundCommand = new RelayCommand(OnPlayPositionalSoundCommand, () => HasPositionalSound);
+ PlayCustomSoundCommand = new RelayCommand(OnPlayCustomSoundCommand, () => HasCustomSound);
+ CustomSoundFileDialogCommand = new RelayCommand(OnCustomSoundFileDialog);
+
+ if(_customSoundsAvailable == null || _customSoundsAvailable.Count < 1)
+ {
+ _customSoundsAvailable = new ObservableCollection {
+ "1maybevaluable.mp3", "2currency.mp3", "3uniques.mp3", "4maps.mp3", "5highmaps.mp3",
+ "6veryvaluable.mp3", "7chancing.mp3", "12leveling.mp3", "placeholder.mp3"
+ };
+ }
}
public override void Initialise(IItemFilterBlockBase itemFilterBlockBase, IItemFilterScriptViewModel parentScriptViewModel)
@@ -66,9 +80,16 @@ namespace Filtration.ViewModels
foreach (var blockItem in itemFilterBlock.BlockItems)
{
blockItem.PropertyChanged += OnBlockItemChanged;
+
+ var customSoundBlockItem = blockItem as CustomSoundBlockItem;
+ if (customSoundBlockItem != null)
+ {
+ if (!string.IsNullOrWhiteSpace(customSoundBlockItem.Value) && _customSoundsAvailable.IndexOf(customSoundBlockItem.Value) < 0)
+ {
+ _customSoundsAvailable.Add(customSoundBlockItem.Value);
+ }
+ }
}
-
-
base.Initialise(itemFilterBlock, parentScriptViewModel);
}
@@ -81,6 +102,8 @@ namespace Filtration.ViewModels
public RelayCommand PlaySoundCommand { get; }
public RelayCommand PlayPositionalSoundCommand { get; }
public RelayCommand SwitchBlockItemsViewCommand { get; }
+ public RelayCommand CustomSoundFileDialogCommand { get; }
+ public RelayCommand PlayCustomSoundCommand { get; }
public IItemFilterBlock Block { get; private set; }
@@ -159,7 +182,12 @@ namespace Filtration.ViewModels
typeof (CorruptedBlockItem),
typeof (ElderItemBlockItem),
typeof (ShaperItemBlockItem),
- typeof (ShapedMapBlockItem)
+ typeof (MapTierBlockItem),
+ typeof (ShapedMapBlockItem),
+ typeof (ElderMapBlockItem),
+ typeof (GemLevelBlockItem),
+ typeof (StackSizeBlockItem),
+ typeof (HasExplicitModBlockItem)
};
public List AudioVisualBlockItemTypesAvailable => new List
@@ -169,7 +197,11 @@ namespace Filtration.ViewModels
typeof (BorderColorBlockItem),
typeof (FontSizeBlockItem),
typeof (SoundBlockItem),
- typeof (PositionalSoundBlockItem)
+ typeof (PositionalSoundBlockItem),
+ typeof (DisableDropSoundBlockItem),
+ typeof (MapIconBlockItem),
+ typeof (PlayEffectBlockItem),
+ typeof (CustomSoundBlockItem)
};
public bool BlockEnabled
@@ -205,13 +237,20 @@ namespace Filtration.ViewModels
public ObservableCollection AvailableColors => PathOfExileColors.DefaultColors;
+ public ObservableCollection CustomSoundsAvailable => _customSoundsAvailable;
+
public Color DisplayTextColor => Block.DisplayTextColor;
public Color DisplayBackgroundColor => Block.DisplayBackgroundColor;
public Color DisplayBorderColor => Block.DisplayBorderColor;
public double DisplayFontSize => Block.DisplayFontSize/1.8;
-
+ public int DisplayIconSize => Block.DisplayIconSize;
+ public int DisplayIconColor => Block.DisplayIconColor;
+ public int DisplayIconShape => Block.DisplayIconShape;
+ public Color DisplayEffectColor => Block.DisplayEffectColor;
+
public bool HasSound => Block.HasBlockItemOfType();
public bool HasPositionalSound => Block.HasBlockItemOfType();
+ public bool HasCustomSound => Block.HasBlockItemOfType();
public bool HasAudioVisualBlockItems => AudioVisualBlockItems.Any();
@@ -419,7 +458,16 @@ namespace Filtration.ViewModels
{
IsDirty = true;
}
-
+ var customSoundBlockItem = sender as CustomSoundBlockItem;
+ if (customSoundBlockItem != null)
+ {
+ if (!string.IsNullOrWhiteSpace(customSoundBlockItem.Value) && _customSoundsAvailable.IndexOf(customSoundBlockItem.Value) < 0)
+ {
+ _customSoundsAvailable.Add(customSoundBlockItem.Value);
+ }
+ RaisePropertyChanged(nameof(CustomSoundsAvailable));
+ }
+ Block.IsEdited = true;
//if (sender is IAudioVisualBlockItem)
//{
RefreshBlockPreview();
@@ -432,7 +480,13 @@ namespace Filtration.ViewModels
RaisePropertyChanged(nameof(DisplayBackgroundColor));
RaisePropertyChanged(nameof(DisplayBorderColor));
RaisePropertyChanged(nameof(DisplayFontSize));
+ RaisePropertyChanged(nameof(DisplayIconSize));
+ RaisePropertyChanged(nameof(DisplayIconColor));
+ RaisePropertyChanged(nameof(DisplayIconShape));
+ RaisePropertyChanged(nameof(DisplayEffectColor));
RaisePropertyChanged(nameof(HasSound));
+ RaisePropertyChanged(nameof(HasPositionalSound));
+ RaisePropertyChanged(nameof(HasCustomSound));
}
private void OnBlockItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@@ -442,5 +496,53 @@ namespace Filtration.ViewModels
RaisePropertyChanged(nameof(AudioVisualBlockItems));
RaisePropertyChanged(nameof(HasAudioVisualBlockItems));
}
+
+ private void OnCustomSoundFileDialog()
+ {
+ OpenFileDialog fileDialog = new OpenFileDialog();
+ fileDialog.DefaultExt = ".mp3";
+ var poePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToString() + @"\My Games\Path of Exile\";
+ fileDialog.InitialDirectory = poePath;
+
+ Nullable result = fileDialog.ShowDialog();
+ if (result == true)
+ {
+ var fileName = fileDialog.FileName;
+ if(fileName.StartsWith(poePath))
+ {
+ fileName = fileName.Replace(poePath, "");
+ }
+
+ var customSoundBlockItem = BlockItems.First(b => b.GetType() == typeof(CustomSoundBlockItem)) as CustomSoundBlockItem;
+
+ if (CustomSoundsAvailable.IndexOf(fileName) < 0)
+ {
+ CustomSoundsAvailable.Add(fileName);
+ RaisePropertyChanged(nameof(CustomSoundsAvailable));
+ }
+ customSoundBlockItem.Value = fileName;
+ }
+ }
+
+ private void OnPlayCustomSoundCommand()
+ {
+ var poePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToString() + @"\My Games\Path of Exile\";
+ var identifier = BlockItems.OfType().First().Value;
+
+ if(!Path.IsPathRooted(identifier))
+ {
+ identifier = poePath + identifier;
+ }
+
+ try
+ {
+ _mediaPlayer.Open(new Uri(identifier, UriKind.Absolute));
+ _mediaPlayer.Play();
+ }
+ catch
+ {
+ MessageBox.Show("Couldn't play the file. Please be sure it is a valid audio file.");
+ }
+ }
}
}
diff --git a/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs b/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs
index 86dcfcb..395bbe1 100644
--- a/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs
+++ b/Filtration/ViewModels/ItemFilterBlockViewModelBase.cs
@@ -9,13 +9,15 @@ namespace Filtration.ViewModels
{
void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel);
IItemFilterBlockBase BaseBlock { get; }
- bool IsDirty { get; set; }
+ bool IsDirty { get; set; }
+ bool IsVisible { get; set; }
event EventHandler BlockBecameDirty;
}
internal abstract class ItemFilterBlockViewModelBase : ViewModelBase, IItemFilterBlockViewModelBase
{
private bool _isDirty;
+ private bool _isVisible;
public ItemFilterBlockViewModelBase()
{
@@ -28,6 +30,8 @@ namespace Filtration.ViewModels
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand);
+
+ _isVisible = true;
}
@@ -64,6 +68,16 @@ namespace Filtration.ViewModels
BlockBecameDirty?.Invoke(this, EventArgs.Empty);
}
}
+ }
+
+ public bool IsVisible
+ {
+ get => _isVisible;
+ set
+ {
+ _isVisible = value;
+ RaisePropertyChanged();
+ }
}
private void OnCopyBlockCommand()
diff --git a/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs b/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs
index 08f5f23..618065a 100644
--- a/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs
+++ b/Filtration/ViewModels/ItemFilterCommentBlockViewModel.cs
@@ -1,15 +1,29 @@
-using Filtration.ObjectModel;
-
+using Filtration.ObjectModel;
+using GalaSoft.MvvmLight.CommandWpf;
+using System;
+
namespace Filtration.ViewModels
{
internal interface IItemFilterCommentBlockViewModel : IItemFilterBlockViewModelBase
{
IItemFilterCommentBlock ItemFilterCommentBlock { get; }
- string Comment { get; }
+ string Comment { get; }
+ bool IsExpanded { get; set; }
+ bool HasChild { get; set; }
}
internal class ItemFilterCommentBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterCommentBlockViewModel
- {
+ {
+ private bool _isExpanded;
+ private bool _hasChild;
+
+ public ItemFilterCommentBlockViewModel()
+ {
+ _isExpanded = true;
+
+ ToggleSectionCommand = new RelayCommand(OnToggleSectionCommand);
+ }
+
public override void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel)
{
_parentScriptViewModel = itemFilterScriptViewModel;
@@ -17,7 +31,9 @@ namespace Filtration.ViewModels
BaseBlock = ItemFilterCommentBlock;
base.Initialise(itemfilterBlock, itemFilterScriptViewModel);
- }
+ }
+
+ public RelayCommand ToggleSectionCommand { get; }
public IItemFilterCommentBlock ItemFilterCommentBlock { get; private set; }
@@ -34,8 +50,60 @@ namespace Filtration.ViewModels
ItemFilterCommentBlock.Comment = value;
IsDirty = true;
RaisePropertyChanged();
+ RaisePropertyChanged("Header");
}
}
}
+
+ public string Header
+ {
+ get
+ {
+ string[] commentLines = ItemFilterCommentBlock.Comment.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
+ var titleOffset = 1;
+ if (commentLines.Length > 1 && (commentLines[0].TrimStart(' ').StartsWith(@"============") || commentLines[0].TrimStart(' ').StartsWith(@"------------")))
+ {
+ titleOffset = 3;
+ commentLines[0] = commentLines[1];
+ }
+
+ commentLines[0] = commentLines[0].TrimStart(' ');
+ if (commentLines[0].Length > 80)
+ {
+ commentLines[0] = commentLines[0].Substring(0, 80) + " (...)";
+ }
+ else if (commentLines.Length > titleOffset)
+ {
+ commentLines[0] = commentLines[0] + " (...)";
+ }
+
+ return commentLines[0];
+ }
+ }
+
+ public bool IsExpanded
+ {
+ get => _isExpanded;
+ set
+ {
+ _isExpanded = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ public bool HasChild
+ {
+ get => _hasChild;
+ set
+ {
+ _hasChild = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ private void OnToggleSectionCommand()
+ {
+ _parentScriptViewModel.ToggleSection(this);
+ }
}
}
\ No newline at end of file
diff --git a/Filtration/ViewModels/ItemFilterScriptViewModel.cs b/Filtration/ViewModels/ItemFilterScriptViewModel.cs
index e76f10f..01564a4 100644
--- a/Filtration/ViewModels/ItemFilterScriptViewModel.cs
+++ b/Filtration/ViewModels/ItemFilterScriptViewModel.cs
@@ -6,6 +6,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
@@ -44,11 +45,16 @@ namespace Filtration.ViewModels
void SetDirtyFlag();
bool HasSelectedEnabledBlock();
bool HasSelectedDisabledBlock();
+ bool HasSelectedCommentBlock();
RelayCommand AddBlockCommand { get; }
RelayCommand AddSectionCommand { get; }
RelayCommand DisableBlockCommand { get; }
RelayCommand EnableBlockCommand { get; }
+ RelayCommand DisableSectionCommand { get; }
+ RelayCommand EnableSectionCommand { get; }
+ RelayCommand ExpandSectionCommand { get; }
+ RelayCommand CollapseSectionCommand { get; }
RelayCommand DeleteBlockCommand { get; }
RelayCommand MoveBlockUpCommand { get; }
RelayCommand MoveBlockDownCommand { get; }
@@ -60,6 +66,8 @@ namespace Filtration.ViewModels
RelayCommand PasteBlockStyleCommand { get; }
RelayCommand ExpandAllBlocksCommand { get; }
RelayCommand CollapseAllBlocksCommand { get; }
+ RelayCommand ExpandAllSectionsCommand { get; }
+ RelayCommand CollapseAllSectionsCommand { get; }
RelayCommand ToggleShowAdvancedCommand { get; }
RelayCommand ClearFilterCommand { get; }
@@ -74,6 +82,7 @@ namespace Filtration.ViewModels
void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase);
void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase);
void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase);
+ void ToggleSection(IItemFilterCommentBlockViewModel targetCommentBlockViewModelBase, bool updateViewModels = true);
}
internal class ItemFilterScriptViewModel : PaneViewModel, IItemFilterScriptViewModel
@@ -92,6 +101,7 @@ namespace Filtration.ViewModels
private IItemFilterBlockViewModelBase _selectedBlockViewModel;
private IItemFilterCommentBlockViewModel _sectionBrowserSelectedBlockViewModel;
private readonly ObservableCollection _itemFilterBlockViewModels;
+ private ObservableCollection _viewItemFilterBlockViewModels;
private ICollectionView _itemFilterBlockViewModelsCollectionView;
private Predicate _blockFilterPredicate;
private ICommandManager _scriptCommandManager;
@@ -131,18 +141,26 @@ namespace Filtration.ViewModels
AddSectionCommand = new RelayCommand(OnAddCommentBlockCommand, () => SelectedBlockViewModel != null);
DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, HasSelectedEnabledBlock);
EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, HasSelectedDisabledBlock);
+ DisableSectionCommand = new RelayCommand(OnDisableSectionCommand, HasSelectedCommentBlock);
+ EnableSectionCommand = new RelayCommand(OnEnableSectionCommand, HasSelectedCommentBlock);
+ ExpandSectionCommand = new RelayCommand(OnExpandSectionCommand, HasSelectedCommentBlock);
+ CollapseSectionCommand = new RelayCommand(OnCollapseSectionCommand, HasSelectedCommentBlock);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => SelectedBlockViewModel != null);
CopyBlockStyleCommand = new RelayCommand(OnCopyBlockStyleCommand, () => SelectedBlockViewModel != null);
PasteBlockCommand = new RelayCommand(OnPasteBlockCommand, () => SelectedBlockViewModel != null);
PasteBlockStyleCommand = new RelayCommand(OnPasteBlockStyleCommand, () => SelectedBlockViewModel != null);
ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand);
CollapseAllBlocksCommand = new RelayCommand(OnCollapseAllBlocksCommand);
+ ExpandAllSectionsCommand = new RelayCommand(ExpandAllSections);
+ CollapseAllSectionsCommand = new RelayCommand(CollapseAllSections);
var icon = new BitmapImage();
icon.BeginInit();
icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/script_icon.png");
icon.EndInit();
IconSource = icon;
+
+ _viewItemFilterBlockViewModels = new ObservableCollection();
}
public void Initialise(IItemFilterScript itemFilterScript, bool newScript)
@@ -164,6 +182,9 @@ namespace Filtration.ViewModels
Title = Filename;
ContentId = "ScriptContentId";
+
+ CollapseAllSections();
+ UpdateBlockModelsForView();
}
private void ItemFilterBlocksOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
@@ -186,6 +207,8 @@ namespace Filtration.ViewModels
break;
}
}
+
+ UpdateBlockModelsForView();
}
private void AddItemFilterBlockViewModels(IEnumerable itemFilterBlocks, int addAtIndex)
@@ -245,12 +268,18 @@ namespace Filtration.ViewModels
public RelayCommand AddSectionCommand { get; }
public RelayCommand EnableBlockCommand { get; }
public RelayCommand DisableBlockCommand { get; }
+ public RelayCommand DisableSectionCommand { get; }
+ public RelayCommand EnableSectionCommand { get; }
+ public RelayCommand ExpandSectionCommand { get; }
+ public RelayCommand CollapseSectionCommand { get; }
public RelayCommand CopyBlockCommand { get; }
public RelayCommand CopyBlockStyleCommand { get; }
public RelayCommand PasteBlockCommand { get; }
public RelayCommand PasteBlockStyleCommand { get; }
public RelayCommand ExpandAllBlocksCommand { get; }
public RelayCommand CollapseAllBlocksCommand { get; }
+ public RelayCommand ExpandAllSectionsCommand { get; }
+ public RelayCommand CollapseAllSectionsCommand { get; }
public bool IsActiveDocument
{
@@ -264,6 +293,19 @@ namespace Filtration.ViewModels
}
}
+ public ObservableCollection ViewItemFilterBlockViewModels
+ {
+ get
+ {
+ return _viewItemFilterBlockViewModels;
+ }
+ set
+ {
+ _viewItemFilterBlockViewModels = value;
+ RaisePropertyChanged();
+ }
+ }
+
public ObservableCollection ItemFilterBlockViewModels
{
get
@@ -359,6 +401,13 @@ namespace Filtration.ViewModels
return SelectedBlockViewModel != null;
}
+ public bool HasSelectedCommentBlock()
+ {
+ var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+
+ return selectedBlockViewModel != null;
+ }
+
public IItemFilterBlockViewModelBase SelectedBlockViewModel
{
get => _selectedBlockViewModel;
@@ -514,7 +563,7 @@ namespace Filtration.ViewModels
Script.ThemeComponents.Where(
t =>
Script.ItemFilterBlocks.OfType().Count(
- b => b.BlockItems.OfType().Count(i => i.ThemeComponent == t) > 0) == 0).ToList();
+ b => b.BlockItems.OfType().Count(i => i.ThemeComponent == t) > 0) == 0).ToList();
if (unusedThemeComponents.Count <= 0) return true;
@@ -634,7 +683,15 @@ namespace Filtration.ViewModels
private void OnCopyBlockCommand()
{
- CopyBlock(SelectedBlockViewModel);
+ var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded)
+ {
+ CopyBlock(SelectedBlockViewModel);
+ }
+ else
+ {
+ CopySection(commentBlockViewModel);
+ }
}
public void CopyBlock(IItemFilterBlockViewModelBase targetBlockViewModel)
@@ -649,6 +706,26 @@ namespace Filtration.ViewModels
}
}
+ public void CopySection(IItemFilterCommentBlockViewModel targetCommentBlockViewModel)
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel) + 1;
+ var copyText = _blockTranslator.TranslateItemFilterBlockBaseToString(targetCommentBlockViewModel.BaseBlock);
+ while (sectionStart < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionStart] as IItemFilterCommentBlockViewModel == null)
+ {
+ copyText += Environment.NewLine + "##CopySection##" + Environment.NewLine + _blockTranslator.TranslateItemFilterBlockBaseToString(ItemFilterBlockViewModels[sectionStart].BaseBlock);
+ sectionStart++;
+ }
+
+ try
+ {
+ _clipboardService.SetClipboardText(copyText);
+ }
+ catch
+ {
+ _messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.", MessageBoxButton.OK, MessageBoxImage.Error);
+ }
+ }
+
private void OnCopyBlockStyleCommand()
{
var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterBlockViewModel;
@@ -709,15 +786,65 @@ namespace Filtration.ViewModels
public void PasteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{
+ var commentBlock = targetBlockViewModelBase as IItemFilterCommentBlockViewModel;
+ if(commentBlock != null && !commentBlock.IsExpanded)
+ {
+ var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase) + 1;
+ while (blockIndex < ItemFilterBlockViewModels.Count && (ItemFilterBlockViewModels[blockIndex] as IItemFilterCommentBlockViewModel) == null)
+ {
+ blockIndex++;
+ }
+ targetBlockViewModelBase = ItemFilterBlockViewModels[blockIndex - 1];
+ }
try
{
var clipboardText = _clipboardService.GetClipboardText();
if (string.IsNullOrEmpty(clipboardText)) return;
-
- var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script, true); // TODO: Doesn't handle pasting comment blocks?
- if (translatedBlock == null) return;
- _scriptCommandManager.ExecuteCommand(new PasteBlockCommand(Script, translatedBlock, targetBlockViewModelBase.BaseBlock));
+ string[] blockTexts = clipboardText.Split(new string[] { Environment.NewLine + "##CopySection##" + Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+
+ List blocksToPaste = new List();
+ foreach (var curBlock in blockTexts)
+ {
+ IItemFilterBlockBase translatedBlock;
+ var preparedString = PrepareBlockForParsing(curBlock);
+ var isCommentBlock = true;
+ string[] textLines = preparedString.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
+ foreach(var line in textLines)
+ {
+ if(!line.StartsWith(@"#"))
+ {
+ isCommentBlock = false;
+ break;
+ }
+ }
+
+ if (isCommentBlock)
+ {
+ translatedBlock = _blockTranslator.TranslateStringToItemFilterCommentBlock(preparedString, Script, curBlock);
+ }
+ else
+ {
+ translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(preparedString, Script, curBlock, true);
+ }
+
+ if (translatedBlock == null) continue;
+
+ blocksToPaste.Add(translatedBlock);
+ }
+
+ if (blocksToPaste.Count < 1)
+ return;
+
+ var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase) + 1;
+ _scriptCommandManager.ExecuteCommand(new PasteSectionCommand(Script, blocksToPaste, targetBlockViewModelBase.BaseBlock));
+ SelectedBlockViewModel = ItemFilterBlockViewModels[blockIndex];
+ RaisePropertyChanged("SelectedBlockViewModel");
+ var firstBlockAsComment = blocksToPaste[0] as IItemFilterCommentBlock;
+ if (firstBlockAsComment != null)
+ {
+ OnCollapseSectionCommand();
+ }
}
catch (Exception e)
{
@@ -728,39 +855,250 @@ namespace Filtration.ViewModels
}
}
+ private string PrepareBlockForParsing(string inputString)
+ {
+ inputString = inputString.Replace("\t", "");
+ var lines = Regex.Split(inputString, "\r\n|\r|\n").ToList();
+ for (var i = 0; i < lines.Count; i++)
+ {
+ if (lines[i].Length == 0)
+ {
+ lines.RemoveAt(i--);
+ }
+ else
+ break;
+ }
+ for (var i = lines.Count - 1; i >= 0; i--)
+ {
+ if (lines[i].Length == 0)
+ {
+ lines.RemoveAt(i++);
+ }
+ else
+ break;
+ }
+ var allCommented = true;
+ for (var i = 0; i < lines.Count; i++)
+ {
+ lines[i] = Regex.Replace(lines[i], @"\s+", " ");
+ if(lines[i][0] == '#')
+ {
+ if (lines[i].Length > 1 && lines[i][1] != ' ')
+ {
+ lines[i] = "# " + lines[i].Substring(1);
+ }
+ }
+ else
+ {
+ allCommented = false;
+ }
+ }
+
+ var disabledBlock = -1;
+ if (allCommented)
+ {
+ for (var i = 0; i < lines.Count; i++)
+ {
+ if (lines[i].StartsWith("#"))
+ {
+ string curLine = Regex.Replace(lines[i].Substring(1), @"\s+", "");
+ if ((curLine.StartsWith("Show") || curLine.StartsWith("Hide")) && (curLine.Length == 4 || curLine[4] == '#'))
+ {
+ lines[i] = lines[i].Substring(0, 6) + "Disabled" + lines[i].Substring(6);
+ disabledBlock = i;
+ break;
+ }
+ }
+ }
+ }
+
+ if(disabledBlock >= 0)
+ {
+ for (var i = disabledBlock; i < lines.Count; i++)
+ {
+ lines[i] = lines[i].Substring(2);
+ }
+ }
+
+ return string.Join(Environment.NewLine, lines);
+ }
+
private void OnMoveBlockToTopCommand()
{
- MoveBlockToTop(SelectedBlockViewModel);
+ var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded)
+ {
+ MoveBlockToTop(SelectedBlockViewModel);
+ }
+ else
+ {
+ MoveSectionToTop(commentBlockViewModel);
+ }
}
private void OnMoveBlockUpCommand()
{
- MoveBlockUp(SelectedBlockViewModel);
+ var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if(commentBlockViewModel == null || commentBlockViewModel.IsExpanded)
+ {
+ MoveBlockUp(SelectedBlockViewModel);
+ }
+ else
+ {
+ MoveSectionUp(commentBlockViewModel);
+ }
}
public void MoveBlockUp(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{
- _scriptCommandManager.ExecuteCommand(new MoveBlockUpCommand(Script, targetBlockViewModelBase?.BaseBlock));
+ var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase);
+ if (ItemFilterBlockViewModels[blockIndex - 1].IsVisible)
+ {
+ _scriptCommandManager.ExecuteCommand(new MoveBlockUpCommand(Script, targetBlockViewModelBase?.BaseBlock));
+ SelectedBlockViewModel = ItemFilterBlockViewModels[blockIndex - 1];
+ RaisePropertyChanged("SelectedBlockViewModel");
+ }
+ else
+ {
+ var aboveSectionStart = blockIndex - 1;
+ while(ItemFilterBlockViewModels[aboveSectionStart] as IItemFilterCommentBlockViewModel == null)
+ {
+ aboveSectionStart--;
+ }
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, blockIndex, 1, aboveSectionStart));
+ SelectedBlockViewModel = ItemFilterBlockViewModels[aboveSectionStart];
+ RaisePropertyChanged("SelectedBlockViewModel");
+ }
+ }
+
+ public void MoveSectionUp(IItemFilterCommentBlockViewModel targetCommentBlockViewModel)
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel);
+ var sectionEnd = sectionStart + 1;
+ while(sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+
+ var newLocation = sectionStart - 1;
+ if (ItemFilterBlockViewModels[newLocation].IsVisible)
+ {
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation));
+ }
+ else
+ {
+ while (ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel == null)
+ {
+ newLocation--;
+ }
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation));
+ }
+
+ ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel);
+ SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation];
+ RaisePropertyChanged("SelectedBlockViewModel");
}
private void OnMoveBlockDownCommand()
{
- MoveBlockDown(SelectedBlockViewModel);
+ var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded)
+ {
+ MoveBlockDown(SelectedBlockViewModel);
+ }
+ else
+ {
+ MoveSectionDown(commentBlockViewModel);
+ }
}
public void MoveBlockDown(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{
- _scriptCommandManager.ExecuteCommand(new MoveBlockDownCommand(Script, targetBlockViewModelBase?.BaseBlock));
+ var blockIndex = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase);
+ var beloveBlockAsComment = ItemFilterBlockViewModels[blockIndex + 1] as IItemFilterCommentBlockViewModel;
+ if (beloveBlockAsComment == null || beloveBlockAsComment.IsExpanded)
+ {
+ _scriptCommandManager.ExecuteCommand(new MoveBlockDownCommand(Script, targetBlockViewModelBase?.BaseBlock));
+ SelectedBlockViewModel = ItemFilterBlockViewModels[blockIndex + 1];
+ RaisePropertyChanged("SelectedBlockViewModel");
+ }
+ else
+ {
+ var beloveSectionEnd = blockIndex + 2;
+ while (beloveSectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[beloveSectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ beloveSectionEnd++;
+ }
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, blockIndex, 1, beloveSectionEnd - 1));
+ SelectedBlockViewModel = ItemFilterBlockViewModels[beloveSectionEnd - 1];
+ RaisePropertyChanged("SelectedBlockViewModel");
+ }
+ }
+
+ public void MoveSectionDown(IItemFilterCommentBlockViewModel targetCommentBlockViewModel)
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel);
+ var sectionEnd = sectionStart + 1;
+ while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+
+ if (sectionEnd >= ItemFilterBlockViewModels.Count)
+ return;
+
+ var sectionSize = sectionEnd - sectionStart;
+
+ var newLocation = sectionStart + 1;
+ var beloveBlockAsComment = ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel;
+ if (beloveBlockAsComment == null || beloveBlockAsComment.IsExpanded)
+ {
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionSize, newLocation));
+ }
+ else
+ {
+ while ((newLocation + sectionSize) < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[newLocation + sectionSize] as IItemFilterCommentBlockViewModel == null)
+ {
+ newLocation++;
+ }
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation));
+ }
+
+ ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel);
+ SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation];
+ RaisePropertyChanged("SelectedBlockViewModel");
}
private void OnMoveBlockToBottomCommand()
{
- MoveBlockToBottom(SelectedBlockViewModel);
+ var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded)
+ {
+ MoveBlockToBottom(SelectedBlockViewModel);
+ }
+ else
+ {
+ MoveSectionToBottom(commentBlockViewModel);
+ }
}
private void OnAddBlockCommand()
{
- AddBlock(SelectedBlockViewModel);
+ var selectedBlockAsCommentBlock = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if(selectedBlockAsCommentBlock == null || selectedBlockAsCommentBlock.IsExpanded)
+ {
+ AddBlock(SelectedBlockViewModel);
+ }
+ else
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(selectedBlockAsCommentBlock);
+ var sectionEnd = sectionStart + 1;
+ while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+ AddBlock(ItemFilterBlockViewModels[sectionEnd - 1]);
+ }
}
public void AddBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase)
@@ -776,7 +1114,22 @@ namespace Filtration.ViewModels
public void DeleteBlock(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{
- _scriptCommandManager.ExecuteCommand(new RemoveBlockCommand(Script, targetBlockViewModelBase.BaseBlock));
+ var commentBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (commentBlockViewModel == null || commentBlockViewModel.IsExpanded)
+ {
+ _scriptCommandManager.ExecuteCommand(new RemoveBlockCommand(Script, targetBlockViewModelBase.BaseBlock));
+ }
+ else
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(targetBlockViewModelBase);
+ var sectionEnd = sectionStart + 1;
+ while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+
+ _scriptCommandManager.ExecuteCommand(new RemoveSectionCommand(Script, sectionStart, sectionEnd - sectionStart));
+ }
}
public void MoveBlockToBottom(IItemFilterBlockViewModelBase targetBlockViewModelBase)
@@ -784,11 +1137,43 @@ namespace Filtration.ViewModels
_scriptCommandManager.ExecuteCommand(new MoveBlockToBottomCommand(Script, targetBlockViewModelBase.BaseBlock));
}
+ public void MoveSectionToBottom(IItemFilterCommentBlockViewModel targetCommentBlockViewModel)
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel);
+ var sectionEnd = sectionStart + 1;
+ while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+
+ var newLocation = ItemFilterBlockViewModels.Count - (sectionEnd - sectionStart);
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation));
+
+ ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel);
+ SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation];
+ }
+
public void MoveBlockToTop(IItemFilterBlockViewModelBase targetBlockViewModelBase)
{
_scriptCommandManager.ExecuteCommand(new MoveBlockToTopCommand(Script, targetBlockViewModelBase.BaseBlock));
}
+ public void MoveSectionToTop(IItemFilterCommentBlockViewModel targetCommentBlockViewModel)
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModel);
+ var sectionEnd = sectionStart + 1;
+ while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+
+ var newLocation = 0;
+ _scriptCommandManager.ExecuteCommand(new MoveSectionToIndexCommand(Script, sectionStart, sectionEnd - sectionStart, newLocation));
+
+ ToggleSection(ItemFilterBlockViewModels[newLocation] as IItemFilterCommentBlockViewModel);
+ SelectedBlockViewModel = ItemFilterBlockViewModels[newLocation];
+ }
+
private void OnBlockBecameDirty(object sender, EventArgs e)
{
SetDirtyFlag();
@@ -796,7 +1181,21 @@ namespace Filtration.ViewModels
private void OnAddCommentBlockCommand()
{
- AddCommentBlock(SelectedBlockViewModel);
+ var selectedBlockAsCommentBlock = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (selectedBlockAsCommentBlock == null || selectedBlockAsCommentBlock.IsExpanded)
+ {
+ AddCommentBlock(SelectedBlockViewModel);
+ }
+ else
+ {
+ var sectionStart = ItemFilterBlockViewModels.IndexOf(selectedBlockAsCommentBlock);
+ var sectionEnd = sectionStart + 1;
+ while (sectionEnd < ItemFilterBlockViewModels.Count && ItemFilterBlockViewModels[sectionEnd] as IItemFilterCommentBlockViewModel == null)
+ {
+ sectionEnd++;
+ }
+ AddCommentBlock(ItemFilterBlockViewModels[sectionEnd - 1]);
+ }
}
private void OnExpandAllBlocksCommand()
@@ -837,5 +1236,181 @@ namespace Filtration.ViewModels
selectedBlockViewModel.BlockEnabled = true;
}
}
+
+ private void OnDisableSectionCommand()
+ {
+ var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (selectedBlockViewModel != null)
+ {
+ var sectionIndex = ItemFilterBlockViewModels.IndexOf(selectedBlockViewModel);
+ for (int i = sectionIndex + 1; i < ItemFilterBlockViewModels.Count; i++)
+ {
+ var block = ItemFilterBlockViewModels[i] as IItemFilterBlockViewModel;
+ if (block != null)
+ {
+ block.BlockEnabled = false;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ private void OnEnableSectionCommand()
+ {
+ var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (selectedBlockViewModel != null)
+ {
+ var sectionIndex = ItemFilterBlockViewModels.IndexOf(selectedBlockViewModel);
+ for (int i = sectionIndex + 1; i < ItemFilterBlockViewModels.Count; i++)
+ {
+ var block = ItemFilterBlockViewModels[i] as IItemFilterBlockViewModel;
+ if (block != null)
+ {
+ block.BlockEnabled = true;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ private void OnExpandSectionCommand()
+ {
+ var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (selectedBlockViewModel != null && !selectedBlockViewModel.IsExpanded)
+ {
+ ToggleSection(selectedBlockViewModel);
+ }
+ }
+
+ private void OnCollapseSectionCommand()
+ {
+ var selectedBlockViewModel = SelectedBlockViewModel as IItemFilterCommentBlockViewModel;
+ if (selectedBlockViewModel != null && selectedBlockViewModel.IsExpanded)
+ {
+ ToggleSection(selectedBlockViewModel);
+ }
+ }
+
+ public void ToggleSection(IItemFilterCommentBlockViewModel targetCommentBlockViewModelBase, bool updateViewModels = true)
+ {
+ var newState = !targetCommentBlockViewModelBase.IsExpanded;
+ targetCommentBlockViewModelBase.IsExpanded = newState;
+ var sectionIndex = ItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModelBase);
+ var viewIndex = ViewItemFilterBlockViewModels.IndexOf(targetCommentBlockViewModelBase);
+ for (int i = sectionIndex + 1; i < ItemFilterBlockViewModels.Count; i++)
+ {
+ var block = ItemFilterBlockViewModels[i] as IItemFilterBlockViewModel;
+ if (block != null)
+ {
+ if (newState)
+ viewIndex++;
+
+ if (newState == block.IsVisible)
+ {
+ continue;
+ }
+
+ if(updateViewModels)
+ {
+ if(newState)
+ {
+ if(viewIndex < ViewItemFilterBlockViewModels.Count)
+ {
+ ViewItemFilterBlockViewModels.Insert(viewIndex, block);
+ }
+ else
+ {
+ ViewItemFilterBlockViewModels.Add(block);
+ }
+ }
+ else
+ {
+ ViewItemFilterBlockViewModels.RemoveAt(viewIndex + 1);
+ }
+ }
+ block.IsVisible = newState;
+ }
+ else
+ break;
+ }
+ }
+
+ private void UpdateBlockModelsForView()
+ {
+ ObservableCollection blocksForView = new ObservableCollection();
+ for (var i = 0; i < ItemFilterBlockViewModels.Count; i++)
+ {
+ var block = ItemFilterBlockViewModels[i];
+ if (block.IsVisible)
+ {
+ blocksForView.Add(block);
+
+ var blockAsComment = block as IItemFilterCommentBlockViewModel;
+ if(blockAsComment != null && i < (ItemFilterBlockViewModels.Count - 1))
+ {
+ var followingBlock = ItemFilterBlockViewModels[i + 1] as IItemFilterBlockViewModel;
+ if(followingBlock != null)
+ {
+ blockAsComment.HasChild = true;
+ }
+ else
+ {
+ blockAsComment.HasChild = false;
+ }
+ }
+ }
+ }
+
+ ViewItemFilterBlockViewModels = blocksForView;
+ }
+
+ private void CollapseAllSections()
+ {
+ ObservableCollection blocksForView = new ObservableCollection();
+ for (int i = 0; i < ItemFilterBlockViewModels.Count; i++)
+ {
+ var block = ItemFilterBlockViewModels[i] as IItemFilterCommentBlockViewModel;
+ if (block != null)
+ {
+ blocksForView.Add(block);
+
+ if(block.IsExpanded)
+ {
+ ToggleSection(block, false);
+ }
+ }
+ }
+
+ if (SelectedBlockViewModel == null && blocksForView.Count > 0)
+ {
+ SelectedBlockViewModel = blocksForView[0];
+ }
+
+ ViewItemFilterBlockViewModels = blocksForView;
+ }
+
+ private void ExpandAllSections()
+ {
+ ObservableCollection blocksForView = new ObservableCollection();
+ for (int i = 0; i < ItemFilterBlockViewModels.Count; i++)
+ {
+ blocksForView.Add(ItemFilterBlockViewModels[i]);
+
+ var block = ItemFilterBlockViewModels[i] as IItemFilterCommentBlockViewModel;
+ if (block != null && !block.IsExpanded)
+ {
+ ToggleSection(block, false);
+ }
+ }
+
+ if(SelectedBlockViewModel == null && blocksForView.Count > 0)
+ {
+ SelectedBlockViewModel = blocksForView[0];
+ }
+
+ ViewItemFilterBlockViewModels = blocksForView;
+ }
}
}
diff --git a/Filtration/ViewModels/MainWindowViewModel.cs b/Filtration/ViewModels/MainWindowViewModel.cs
index 7fe247c..74e6534 100644
--- a/Filtration/ViewModels/MainWindowViewModel.cs
+++ b/Filtration/ViewModels/MainWindowViewModel.cs
@@ -100,6 +100,10 @@ namespace Filtration.ViewModels
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedEnabledBlock);
EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedDisabledBlock);
+ DisableSectionCommand = new RelayCommand(OnDisableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
+ EnableSectionCommand = new RelayCommand(OnEnableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
+ ExpandSectionCommand = new RelayCommand(OnExpandSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
+ CollapseSectionCommand = new RelayCommand(OnCollapseSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand);
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => ActiveDocumentIsScript);
@@ -110,11 +114,19 @@ namespace Filtration.ViewModels
AddTextColorThemeComponentCommand = new RelayCommand(OnAddTextColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
AddBackgroundColorThemeComponentCommand = new RelayCommand(OnAddBackgroundColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
AddBorderColorThemeComponentCommand = new RelayCommand(OnAddBorderColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
+ AddFontSizeThemeComponentCommand = new RelayCommand(OnAddFontSizeThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
+ AddAlertSoundThemeComponentCommand = new RelayCommand(OnAddAlertSoundThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
+ AddCustomSoundThemeComponentCommand = new RelayCommand(OnAddCustomSoundThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
+ AddIconThemeComponentCommand = new RelayCommand(OnAddIconThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
+ AddEffectColorThemeComponentCommand = new RelayCommand(OnAddEffectColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable && _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent != null);
ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand, () => ActiveDocumentIsScript);
CollapseAllBlocksCommand = new RelayCommand(OnCollapseAllBlocksCommand, () => ActiveDocumentIsScript);
+ ExpandAllSectionsCommand = new RelayCommand(OnExpandAllSectionsCommand, () => ActiveDocumentIsScript);
+ CollapseAllSectionsCommand = new RelayCommand(OnCollapseAllSectionsCommand, () => ActiveDocumentIsScript);
+
ToggleShowAdvancedCommand = new RelayCommand(OnToggleShowAdvancedCommand, s => ActiveDocumentIsScript);
ClearFiltersCommand = new RelayCommand(OnClearFiltersCommand, () => ActiveDocumentIsScript);
@@ -206,6 +218,11 @@ namespace Filtration.ViewModels
public RelayCommand AddTextColorThemeComponentCommand { get; }
public RelayCommand AddBackgroundColorThemeComponentCommand { get; }
public RelayCommand AddBorderColorThemeComponentCommand { get; }
+ public RelayCommand AddFontSizeThemeComponentCommand { get; }
+ public RelayCommand AddAlertSoundThemeComponentCommand { get; }
+ public RelayCommand AddCustomSoundThemeComponentCommand { get; }
+ public RelayCommand AddIconThemeComponentCommand { get; }
+ public RelayCommand AddEffectColorThemeComponentCommand { get; }
public RelayCommand DeleteThemeComponentCommand { get; }
public RelayCommand AddBlockCommand { get; }
@@ -213,6 +230,10 @@ namespace Filtration.ViewModels
public RelayCommand DeleteBlockCommand { get; }
public RelayCommand DisableBlockCommand { get; }
public RelayCommand EnableBlockCommand { get; }
+ public RelayCommand DisableSectionCommand { get; }
+ public RelayCommand EnableSectionCommand { get; }
+ public RelayCommand ExpandSectionCommand { get; }
+ public RelayCommand CollapseSectionCommand { get; }
public RelayCommand MoveBlockUpCommand { get; }
public RelayCommand MoveBlockDownCommand { get; }
@@ -222,6 +243,9 @@ namespace Filtration.ViewModels
public RelayCommand ExpandAllBlocksCommand { get; }
public RelayCommand CollapseAllBlocksCommand { get; }
+ public RelayCommand ExpandAllSectionsCommand { get; }
+ public RelayCommand CollapseAllSectionsCommand { get; }
+
public RelayCommand ToggleShowAdvancedCommand { get; }
public RelayCommand ClearFiltersCommand { get; }
@@ -260,6 +284,9 @@ namespace Filtration.ViewModels
public bool ActiveScriptHasSelectedDisabledBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.HasSelectedDisabledBlock();
+ public bool ActiveScriptHasSelectedCommentBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.HasSelectedCommentBlock();
+
+
public bool ActiveThemeIsEditable => AvalonDockWorkspaceViewModel.ActiveThemeViewModel.IsMasterTheme;
private bool ActiveDocumentIsEditable()
@@ -595,6 +622,26 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.EnableBlockCommand.Execute(null);
}
+ private void OnDisableSectionCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveScriptViewModel.DisableSectionCommand.Execute(null);
+ }
+
+ private void OnEnableSectionCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveScriptViewModel.EnableSectionCommand.Execute(null);
+ }
+
+ private void OnExpandSectionCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveScriptViewModel.ExpandSectionCommand.Execute(null);
+ }
+
+ private void OnCollapseSectionCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveScriptViewModel.CollapseSectionCommand.Execute(null);
+ }
+
private void OnExpandAllBlocksCommand()
{
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.ExpandAllBlocksCommand.Execute(null);
@@ -605,6 +652,16 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.CollapseAllBlocksCommand.Execute(null);
}
+ private void OnExpandAllSectionsCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveScriptViewModel.ExpandAllSectionsCommand.Execute(null);
+ }
+
+ private void OnCollapseAllSectionsCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveScriptViewModel.CollapseAllSectionsCommand.Execute(null);
+ }
+
private void OnToggleShowAdvancedCommand(bool showAdvanced)
{
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.ToggleShowAdvancedCommand.Execute(showAdvanced);
@@ -630,6 +687,31 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.BorderColor);
}
+ private void OnAddFontSizeThemeComponentCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.FontSize);
+ }
+
+ private void OnAddAlertSoundThemeComponentCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.AlertSound);
+ }
+
+ private void OnAddCustomSoundThemeComponentCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.CustomSound);
+ }
+
+ private void OnAddIconThemeComponentCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.Icon);
+ }
+
+ private void OnAddEffectColorThemeComponentCommand()
+ {
+ _avalonDockWorkspaceViewModel.ActiveThemeViewModel.AddThemeComponentCommand.Execute(ThemeComponentType.Effect);
+ }
+
private void OnDeleteThemeComponentCommand()
{
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.DeleteThemeComponentCommand.Execute(
diff --git a/Filtration/ViewModels/ToolPanes/BlockGroupBrowserViewModel.cs b/Filtration/ViewModels/ToolPanes/BlockGroupBrowserViewModel.cs
index a13f3c4..f205a39 100644
--- a/Filtration/ViewModels/ToolPanes/BlockGroupBrowserViewModel.cs
+++ b/Filtration/ViewModels/ToolPanes/BlockGroupBrowserViewModel.cs
@@ -28,6 +28,9 @@ namespace Filtration.ViewModels.ToolPanes
icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/block_group_browser_icon.png");
icon.EndInit();
IconSource = icon;
+
+ IsVisible = false;
+
Messenger.Default.Register>(this, message =>
{
switch (message.Notification)
diff --git a/Filtration/ViewModels/ToolPanes/CommentBlockBrowserViewModel.cs b/Filtration/ViewModels/ToolPanes/CommentBlockBrowserViewModel.cs
index e2c9880..9dc542a 100644
--- a/Filtration/ViewModels/ToolPanes/CommentBlockBrowserViewModel.cs
+++ b/Filtration/ViewModels/ToolPanes/CommentBlockBrowserViewModel.cs
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Windows.Data;
using System.Windows.Media.Imaging;
using GalaSoft.MvvmLight.Messaging;
@@ -15,6 +17,8 @@ namespace Filtration.ViewModels.ToolPanes
{
private IEnumerable _itemFilterCommentBlockViewModels;
private IItemFilterCommentBlockViewModel _selectedItemFilterCommentBlockViewModel;
+ private CollectionView _commentBlocksView;
+ private string _searchText;
public CommentBlockBrowserViewModel() : base("Section Browser")
{
@@ -24,7 +28,9 @@ namespace Filtration.ViewModels.ToolPanes
icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/add_section_icon.png");
icon.EndInit();
IconSource = icon;
-
+ _searchText = "";
+ _commentBlocksView = (CollectionView)CollectionViewSource.GetDefaultView(new List());
+
Messenger.Default.Register(this, message =>
{
switch (message.Notification)
@@ -46,7 +52,23 @@ namespace Filtration.ViewModels.ToolPanes
private set
{
_itemFilterCommentBlockViewModels = value;
- RaisePropertyChanged();
+
+ _commentBlocksView = _itemFilterCommentBlockViewModels != null ?
+ (CollectionView)CollectionViewSource.GetDefaultView(_itemFilterCommentBlockViewModels)
+ : (CollectionView)CollectionViewSource.GetDefaultView(new List());
+
+ _commentBlocksView.Filter = SearchFilter;
+ _commentBlocksView.Refresh();
+ RaisePropertyChanged("CommentBlocksView");
+ }
+ }
+
+ public CollectionView CommentBlocksView
+ {
+ get => _commentBlocksView;
+ private set
+ {
+ _commentBlocksView = value;
}
}
@@ -64,6 +86,18 @@ namespace Filtration.ViewModels.ToolPanes
}
}
+ public string SearchText
+ {
+ get => _searchText;
+ set
+ {
+ _searchText = value;
+ _commentBlocksView.Refresh();
+ RaisePropertyChanged();
+ RaisePropertyChanged("CommentBlocksView");
+ }
+ }
+
protected override void OnActiveDocumentChanged(object sender, EventArgs e)
{
if (AvalonDockWorkspaceViewModel.ActiveScriptViewModel != null && AvalonDockWorkspaceViewModel.ActiveDocument.IsScript)
@@ -81,5 +115,24 @@ namespace Filtration.ViewModels.ToolPanes
ItemFilterCommentBlockViewModels = null;
SelectedItemFilterCommentBlockViewModel = null;
}
+
+ private bool SearchFilter(object obj)
+ {
+ if (string.IsNullOrEmpty(_searchText))
+ return true;
+
+ var block = obj as IItemFilterCommentBlockViewModel;
+ var searchWords = Regex.Split(_searchText, @"\s+");
+ foreach(var word in searchWords)
+ {
+ if (string.IsNullOrEmpty(word))
+ continue;
+
+ if (block.Comment.IndexOf(word, StringComparison.OrdinalIgnoreCase) >= 0)
+ return true;
+ }
+
+ return false;
+ }
}
}
diff --git a/Filtration/Views/AboutWindow.xaml b/Filtration/Views/AboutWindow.xaml
index 9b8c9ae..9862989 100644
--- a/Filtration/Views/AboutWindow.xaml
+++ b/Filtration/Views/AboutWindow.xaml
@@ -1,7 +1,7 @@
-
+
diff --git a/Filtration/Views/ItemFilterBlockView.xaml b/Filtration/Views/ItemFilterBlockView.xaml
index 98b941c..af675b4 100644
--- a/Filtration/Views/ItemFilterBlockView.xaml
+++ b/Filtration/Views/ItemFilterBlockView.xaml
@@ -18,6 +18,8 @@
+
+