From adf22a9da7862f1fe48df58f4014aee24fa4e6fb Mon Sep 17 00:00:00 2001 From: briandunnington Date: Thu, 27 Aug 2009 22:03:55 +0000 Subject: [PATCH] added Feed Monitor project --- .../Feed Monitor Deployment.vdproj | 818 ++++++++++++++++++ .../FeedListView.Designer.cs | 36 + .../GrowlExtras.FeedMonitor/FeedListView.cs | 157 ++++ .../GrowlExtras.FeedMonitor.csproj | 126 +++ .../GrowlExtras.FeedMonitor.sln | 24 + .../GrowlExtras.FeedMonitor/MainComponent.cs | 221 +++++ .../MainForm.Designer.cs | 271 ++++++ .../GrowlExtras.FeedMonitor/MainForm.cs | 251 ++++++ .../GrowlExtras.FeedMonitor/MainForm.resx | 123 +++ .../GrowlExtras.FeedMonitor/Program.cs | 24 + .../Properties/AssemblyInfo.cs | 36 + .../Properties/Resources.Designer.cs | 84 ++ .../Properties/Resources.resx | 130 +++ .../Properties/Settings.Designer.cs | 38 + .../Properties/Settings.settings | 9 + .../Resources/close_blue.png | Bin 0 -> 769 bytes .../Resources/close_red.png | Bin 0 -> 916 bytes .../Resources/feed.ico | Bin 0 -> 67646 bytes .../GrowlExtras.FeedMonitor/_source/Feed.cs | 274 ++++++ .../_source/Rss10FeedFormatter.cs | 278 ++++++ .../_source/SettingsPersister.cs | 195 +++++ .../_source/User32DLL.cs | 44 + .../GrowlExtras.FeedMonitor/app.config | 15 + 23 files changed, 3154 insertions(+) create mode 100644 Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.Designer.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.csproj create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.sln create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.resx create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Program.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.Designer.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.resx create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.Designer.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.settings create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Resources/close_blue.png create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Resources/close_red.png create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Resources/feed.ico create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Feed.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Rss10FeedFormatter.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/User32DLL.cs create mode 100644 Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/app.config diff --git a/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj b/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj new file mode 100644 index 0000000..6fffc40 --- /dev/null +++ b/Growl Extras/Feed Monitor/Feed Monitor Deployment/Feed Monitor Deployment.vdproj @@ -0,0 +1,818 @@ +"DeployProject" +{ +"VSVersion" = "3:800" +"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" +"IsWebType" = "8:FALSE" +"ProjectName" = "8:Feed Monitor Deployment" +"LanguageId" = "3:1033" +"CodePage" = "3:1252" +"UILanguageId" = "3:1033" +"SccProjectName" = "8:" +"SccLocalPath" = "8:" +"SccAuxPath" = "8:" +"SccProvider" = "8:" + "Hierarchy" + { + "Entry" + { + "MsmKey" = "8:_7F051F116AD0063C7AF09DB0713E5F32" + "OwnerKey" = "8:_D40519D7C2A2C2EFD0E2C2B180072549" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_7F051F116AD0063C7AF09DB0713E5F32" + "OwnerKey" = "8:_C67A5587097A4441ADB422A23AA85F88" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_C67A5587097A4441ADB422A23AA85F88" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_D40519D7C2A2C2EFD0E2C2B180072549" + "OwnerKey" = "8:_C67A5587097A4441ADB422A23AA85F88" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_C67A5587097A4441ADB422A23AA85F88" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_D40519D7C2A2C2EFD0E2C2B180072549" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { + "MsmKey" = "8:_UNDEFINED" + "OwnerKey" = "8:_7F051F116AD0063C7AF09DB0713E5F32" + "MsmSig" = "8:_UNDEFINED" + } + } + "Configurations" + { + "Debug" + { + "DisplayName" = "8:Debug" + "IsDebugOnly" = "11:TRUE" + "IsReleaseOnly" = "11:FALSE" + "OutputFilename" = "8:Debug\\Feed Monitor Deployment.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + } + } + "Release" + { + "DisplayName" = "8:Release" + "IsDebugOnly" = "11:FALSE" + "IsReleaseOnly" = "11:TRUE" + "OutputFilename" = "8:Release\\Feed Monitor Deployment.msi" + "PackageFilesAs" = "3:2" + "PackageFileSize" = "3:-2147483648" + "CabType" = "3:1" + "Compression" = "3:2" + "SignOutput" = "11:FALSE" + "CertificateFile" = "8:" + "PrivateKeyFile" = "8:" + "TimeStampServer" = "8:" + "InstallerBootstrapper" = "3:2" + "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" + { + "Enabled" = "11:TRUE" + "PromptEnabled" = "11:TRUE" + "PrerequisitesLocation" = "2:1" + "Url" = "8:" + "ComponentsUrl" = "8:" + } + } + } + "Deployable" + { + "CustomAction" + { + } + "DefaultFeature" + { + "Name" = "8:DefaultFeature" + "Title" = "8:" + "Description" = "8:" + } + "ExternalPersistence" + { + "LaunchCondition" + { + "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_07749E3BC63D4FF7B73D919230E07807" + { + "Name" = "8:.NET Framework" + "Message" = "8:[VSDNETMSG]" + "Version" = "8:3.5.21022" + "AllowLaterVersions" = "11:FALSE" + "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=76617" + } + } + } + "File" + { + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_7F051F116AD0063C7AF09DB0713E5F32" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Growl.CoreLibrary, Version=2.0.0.0, Culture=neutral, PublicKeyToken=13e59d82e007b064, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_7F051F116AD0063C7AF09DB0713E5F32" + { + "Name" = "8:Growl.CoreLibrary.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Growl.CoreLibrary.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_194ABD0627A144529BAE11330BC2D515" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_D40519D7C2A2C2EFD0E2C2B180072549" + { + "AssemblyRegister" = "3:1" + "AssemblyIsInGAC" = "11:FALSE" + "AssemblyAsmDisplayName" = "8:Growl.Connector, Version=2.0.0.0, Culture=neutral, PublicKeyToken=980c2339411be384, processorArchitecture=MSIL" + "ScatterAssemblies" + { + "_D40519D7C2A2C2EFD0E2C2B180072549" + { + "Name" = "8:Growl.Connector.dll" + "Attributes" = "3:512" + } + } + "SourcePath" = "8:Growl.Connector.dll" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_194ABD0627A144529BAE11330BC2D515" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:TRUE" + "IsolateTo" = "8:" + } + } + "FileType" + { + } + "Folder" + { + "{3C67513D-01DD-4637-8A68-80971EB9504F}:_194ABD0627A144529BAE11330BC2D515" + { + "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]" + "Name" = "8:#1925" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:TARGETDIR" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_965D187123314E7EB91B1B1F91B1ADFC" + { + "Name" = "8:#1919" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:ProgramMenuFolder" + "Folders" + { + } + } + "{1525181F-901A-416C-8A58-119130FE478E}:_9BA5008E8D934400AC81F640B8A0132F" + { + "Name" = "8:#1916" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:DesktopFolder" + "Folders" + { + } + } + } + "LaunchCondition" + { + } + "Locator" + { + } + "MsiBootstrapper" + { + "LangId" = "3:1033" + "RequiresElevation" = "11:FALSE" + } + "Product" + { + "Name" = "8:Microsoft Visual Studio" + "ProductName" = "8:Feed Monitor" + "ProductCode" = "8:{E9DDAEC7-E0DA-4276-8AF9-DC7AA949EA77}" + "PackageCode" = "8:{55F42076-6BAF-4B26-9D91-1F3DB212F9E1}" + "UpgradeCode" = "8:{E8D784D8-949E-4CC9-BA80-A316D25574D7}" + "RestartWWWService" = "11:FALSE" + "RemovePreviousVersions" = "11:TRUE" + "DetectNewerInstalledVersion" = "11:TRUE" + "InstallAllUsers" = "11:FALSE" + "ProductVersion" = "8:1.0.1" + "Manufacturer" = "8:element code project" + "ARPHELPTELEPHONE" = "8:" + "ARPHELPLINK" = "8:" + "Title" = "8:Feed Monitor" + "Subject" = "8:" + "ARPCONTACT" = "8:element code project" + "Keywords" = "8:" + "ARPCOMMENTS" = "8:" + "ARPURLINFOABOUT" = "8:" + "ARPPRODUCTICON" = "8:" + "ARPIconIndex" = "3:0" + "SearchPath" = "8:" + "UseSystemSearchPath" = "11:TRUE" + "TargetPlatform" = "3:0" + "PreBuildEvent" = "8:" + "PostBuildEvent" = "8:" + "RunPostBuildEvent" = "3:0" + } + "Registry" + { + "HKLM" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_7AB8B6DD4EF2451F9CEE42423C5B6C55" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_09F393CDFC9B419CA6A3FA883C68FA5B" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCU" + { + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_0B6721D2F01741218DA95A85FE703A25" + { + "Name" = "8:Software" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_14F4DF1570EA423FBC6BCF91CA833E4E" + { + "Name" = "8:[Manufacturer]" + "Condition" = "8:" + "AlwaysCreate" = "11:FALSE" + "DeleteAtUninstall" = "11:FALSE" + "Transitive" = "11:FALSE" + "Keys" + { + } + "Values" + { + } + } + } + "Values" + { + } + } + } + } + "HKCR" + { + "Keys" + { + } + } + "HKU" + { + "Keys" + { + } + } + "HKPU" + { + "Keys" + { + } + } + } + "Sequences" + { + } + "Shortcut" + { + "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_C18B2788EE074CE4A2764D035DDF8AB0" + { + "Name" = "8:Feed Monitor" + "Arguments" = "8:" + "Description" = "8:" + "ShowCmd" = "3:1" + "IconIndex" = "3:32512" + "Transitive" = "11:FALSE" + "Target" = "8:_C67A5587097A4441ADB422A23AA85F88" + "Folder" = "8:_9BA5008E8D934400AC81F640B8A0132F" + "WorkingFolder" = "8:_194ABD0627A144529BAE11330BC2D515" + "Icon" = "8:_C67A5587097A4441ADB422A23AA85F88" + "Feature" = "8:" + } + } + "UserInterface" + { + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_60CC3296633E443EAFD95528D9CE457C" + { + "Name" = "8:#1901" + "Sequence" = "3:1" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3E95DA0EAC8C4C54B1EAA8DAEEB9E973" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_7B7A06AF71834B619A5F241A56B610F0" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdUserInterface.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_7BB7111A08F44E9A8A3F04175C504809" + { + "Name" = "8:#1900" + "Sequence" = "3:1" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_12D9B6AB9124473694959927DC9B466D" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_30881ED85F014AA3862C9F0BA1A46705" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9E79AA18DA524BD6AC3DF76EB24AC19D" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "InstallAllUsersVisible" + { + "Name" = "8:InstallAllUsersVisible" + "DisplayName" = "8:#1059" + "Description" = "8:#1159" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_87F37175D82446928DB687E0EB05E278" + { + "UseDynamicProperties" = "11:FALSE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdBasicDialogs.wim" + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_9B142A583DFE4CBB88A51C64958C1C17" + { + "Name" = "8:#1900" + "Sequence" = "3:2" + "Attributes" = "3:1" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_2BB9B191D68848FE9E35A14B7733AEC1" + { + "Sequence" = "3:300" + "DisplayName" = "8:Confirm Installation" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_8BE28CADC24649D69B4CD5DE9704FB44" + { + "Sequence" = "3:200" + "DisplayName" = "8:Installation Folder" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFolderDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_98402C2188BF4E8AAE70443F688114F5" + { + "Sequence" = "3:100" + "DisplayName" = "8:Welcome" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "CopyrightWarning" + { + "Name" = "8:CopyrightWarning" + "DisplayName" = "8:#1002" + "Description" = "8:#1102" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1202" + "DefaultValue" = "8:#1202" + "UsePlugInResources" = "11:TRUE" + } + "Welcome" + { + "Name" = "8:Welcome" + "DisplayName" = "8:#1003" + "Description" = "8:#1103" + "Type" = "3:3" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1203" + "DefaultValue" = "8:#1203" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_A6B13F6F18F942E48F53964A9F002522" + { + "Name" = "8:#1901" + "Sequence" = "3:2" + "Attributes" = "3:2" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_AC29CD3CB16C4B6C8F9E6A4CA9BFA290" + { + "Sequence" = "3:100" + "DisplayName" = "8:Progress" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminProgressDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "ShowProgress" + { + "Name" = "8:ShowProgress" + "DisplayName" = "8:#1009" + "Description" = "8:#1109" + "Type" = "3:5" + "ContextData" = "8:1;True=1;False=0" + "Attributes" = "3:0" + "Setting" = "3:0" + "Value" = "3:1" + "DefaultValue" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_B79176ABC2854FDAAF3E00C77B8AFA8B" + { + "Name" = "8:#1902" + "Sequence" = "3:2" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_FCB0D14B99474437A060C0DB94545ED8" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_E85CF83DB7024368BE8E8DDCB53325FB" + { + "Name" = "8:#1902" + "Sequence" = "3:1" + "Attributes" = "3:3" + "Dialogs" + { + "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3C44D61D437D4FDCA9C11D27FB1AA3A5" + { + "Sequence" = "3:100" + "DisplayName" = "8:Finished" + "UseDynamicProperties" = "11:TRUE" + "IsDependency" = "11:FALSE" + "SourcePath" = "8:\\VsdFinishedDlg.wid" + "Properties" + { + "BannerBitmap" + { + "Name" = "8:BannerBitmap" + "DisplayName" = "8:#1001" + "Description" = "8:#1101" + "Type" = "3:8" + "ContextData" = "8:Bitmap" + "Attributes" = "3:4" + "Setting" = "3:1" + "UsePlugInResources" = "11:TRUE" + } + "UpdateText" + { + "Name" = "8:UpdateText" + "DisplayName" = "8:#1058" + "Description" = "8:#1158" + "Type" = "3:15" + "ContextData" = "8:" + "Attributes" = "3:0" + "Setting" = "3:1" + "Value" = "8:#1258" + "DefaultValue" = "8:#1258" + "UsePlugInResources" = "11:TRUE" + } + } + } + } + } + } + "MergeModule" + { + } + "ProjectOutput" + { + "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_C67A5587097A4441ADB422A23AA85F88" + { + "SourcePath" = "8:..\\GrowlExtras.FeedMonitor\\obj\\Release\\GrowlExtras.FeedMonitor.exe" + "TargetName" = "8:" + "Tag" = "8:" + "Folder" = "8:_194ABD0627A144529BAE11330BC2D515" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + "ProjectOutputGroupRegister" = "3:1" + "OutputConfiguration" = "8:" + "OutputGroupCanonicalName" = "8:Built" + "OutputProjectGuid" = "8:{40C8E85D-CED7-4CB5-8584-EB7E27C516FD}" + "ShowKeyOutput" = "11:TRUE" + "ExcludeFilters" + { + } + } + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.Designer.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.Designer.cs new file mode 100644 index 0000000..9b62899 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.Designer.cs @@ -0,0 +1,36 @@ +namespace GrowlExtras.FeedMonitor +{ + partial class FeedListView + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs new file mode 100644 index 0000000..324955b --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/FeedListView.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +namespace GrowlExtras.FeedMonitor +{ + public partial class FeedListView : ListView + { + private ToolTip tooltip = new ToolTip(); + + public FeedListView(IContainer container) + { + container.Add(this); + + InitializeComponent(); + + this.SuspendLayout(); + + this.OwnerDraw = true; + this.DoubleBuffered = true; + + // columns + ColumnHeader nameHeader = new ColumnHeader(); + ColumnHeader urlHeader = new ColumnHeader(); + this.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + nameHeader, + urlHeader}); + + this.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + //this.LargeImageList = this.imageList; + this.MultiSelect = false; + this.UseCompatibleStateImageBehavior = false; + this.View = System.Windows.Forms.View.Tile; + this.Scrollable = false; + this.ShowItemToolTips = true; + this.LabelWrap = false; + + this.DrawItem += new DrawListViewItemEventHandler(FeedListView_DrawItem); + + // uncomment this to use custom tool tips + //this.ShowItemToolTips = false; + this.ItemMouseHover += new ListViewItemMouseHoverEventHandler(FeedListView_ItemMouseHover); + //this.MouseLeave += new EventHandler(FeedListView_MouseLeave); + + this.ResumeLayout(); + } + + void FeedListView_DrawItem(object sender, DrawListViewItemEventArgs e) + { + if (this.View == View.Tile) + { + Feed feed = (Feed) e.Item.Tag; + + // draw the background and focus rectangle for selected and non-selected states + if ((e.State & ListViewItemStates.Selected) != 0) + { + e.Graphics.FillRectangle(System.Drawing.Brushes.LightGray, e.Bounds); + e.DrawFocusRectangle(); + } + else + { + e.DrawBackground(); + e.DrawFocusRectangle(); + } + + // draw icon + int newX = e.Bounds.Left; + /* + System.Drawing.Image img = this.imageList.Images[e.Item.ImageKey]; + if (img != null) + { + int x = e.Bounds.Left; + int y = e.Bounds.Top; + e.Graphics.DrawImage(img, x, y); + newX = e.Bounds.Left + img.Width + this.Margin.Right; + img.Dispose(); + } + * */ + + // draw main text + System.Drawing.RectangleF rect = new System.Drawing.RectangleF(newX, e.Bounds.Top, e.Bounds.Right - newX, e.Item.Font.Height); + System.Drawing.StringFormat sf = new System.Drawing.StringFormat(); + sf.Trimming = System.Drawing.StringTrimming.EllipsisCharacter; + sf.FormatFlags = System.Drawing.StringFormatFlags.NoClip; + System.Drawing.SolidBrush foreBrush = new System.Drawing.SolidBrush(e.Item.ForeColor); + using (foreBrush) + { + e.Graphics.DrawString(feed.Name, + e.Item.Font, + foreBrush, + rect, + sf); + } + + // draw subitems + System.Drawing.Color subColor = System.Drawing.Color.FromArgb(System.Drawing.SystemColors.GrayText.ToArgb()); + System.Drawing.SolidBrush subBrush = new System.Drawing.SolidBrush(subColor); + using (subBrush) + { + for (int i = 1; i < this.Columns.Count; i++) + { + if (i < e.Item.SubItems.Count) + { + rect.Offset(0, e.Item.Font.Height); + e.Graphics.DrawString(e.Item.SubItems[i].Text, + e.Item.Font, + subBrush, + rect, + sf); + } + } + } + } + else + { + e.DrawDefault = true; + } + } + + void FeedListView_ItemMouseHover(object sender, ListViewItemMouseHoverEventArgs e) + { + // update tooltip text + Feed feed = e.Item.Tag as Feed; + if (feed != null) + { + e.Item.ToolTipText = String.Format("Updates every {0} minutes", feed.PollInterval); + } + + /* + Feed feed = e.Item.Tag as Feed; + if (feed != null) + { + string text = String.Format("Updates every {0} minutes", feed.PollInterval); + + //System.Drawing.Point position = Cursor.Position; + System.Drawing.Point position = this.PointToClient(Cursor.Position); + position.Offset(0, Cursor.Current.Size.Height - 10); + IntPtr handle = (IntPtr)typeof(ToolTip).GetProperty("Handle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(this.tooltip, null); + this.tooltip.Show(text, this, position, this.tooltip.AutoPopDelay); + User32DLL.SetWindowPos(handle, User32DLL.HWND_TOPMOST, 0, 0, 0, 0, User32DLL.SWP_NOACTIVATE | User32DLL.SWP_NOMOVE | User32DLL.SWP_NOSIZE); + } + * */ + } + + void FeedListView_MouseLeave(object sender, EventArgs e) + { + System.Drawing.Point p = PointToClient(Cursor.Position); + ListViewHitTestInfo info = this.HitTest(p); + if (info.Item == null) + this.tooltip.Hide(this); + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.csproj b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.csproj new file mode 100644 index 0000000..87e1806 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.csproj @@ -0,0 +1,126 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {40C8E85D-CED7-4CB5-8584-EB7E27C516FD} + WinExe + Properties + GrowlExtras.FeedMonitor + GrowlExtras.FeedMonitor + v3.5 + 512 + Resources\feed.ico + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\..\Growl Connectors\NET\libraries\Growl.Connector.dll + + + False + ..\..\..\Growl Connectors\NET\libraries\Growl.CoreLibrary.dll + + + + + 3.5 + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + Component + + + FeedListView.cs + + + Form + + + MainForm.cs + + + + + + MainForm.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.sln b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.sln new file mode 100644 index 0000000..97bbb41 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/GrowlExtras.FeedMonitor.sln @@ -0,0 +1,24 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrowlExtras.FeedMonitor", "GrowlExtras.FeedMonitor.csproj", "{40C8E85D-CED7-4CB5-8584-EB7E27C516FD}" +EndProject +Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Feed Monitor Deployment", "..\Feed Monitor Deployment\Feed Monitor Deployment.vdproj", "{3C42B04C-8B22-4F00-BA68-57F7969404D6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {40C8E85D-CED7-4CB5-8584-EB7E27C516FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40C8E85D-CED7-4CB5-8584-EB7E27C516FD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40C8E85D-CED7-4CB5-8584-EB7E27C516FD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40C8E85D-CED7-4CB5-8584-EB7E27C516FD}.Release|Any CPU.Build.0 = Release|Any CPU + {3C42B04C-8B22-4F00-BA68-57F7969404D6}.Debug|Any CPU.ActiveCfg = Debug + {3C42B04C-8B22-4F00-BA68-57F7969404D6}.Release|Any CPU.ActiveCfg = Release + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs new file mode 100644 index 0000000..9db63f3 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainComponent.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using System.ServiceModel.Syndication; +using Growl.Connector; +using Growl.CoreLibrary; + +namespace GrowlExtras.FeedMonitor +{ + public class MainComponent + { + private delegate void SimpleMethodDelegate(); + + private MainForm mainForm; + private NotifyIcon notifyIcon; + private ContextMenuStrip contextMenu; + private ToolStripMenuItem settingsToolStripMenuItem; + private ToolStripMenuItem exitToolStripMenuItem; + private ToolStripSeparator toolStripSeparator1; + + private GrowlConnector growl; + private Growl.Connector.Application app; + private NotificationType ntNewFeedItem; + private NotificationType ntFeedError; + private List feeds; + private bool loaded = false; + + public MainComponent() + { + System.Windows.Forms.Application.ApplicationExit += new EventHandler(Application_ApplicationExit); + + this.settingsToolStripMenuItem = new ToolStripMenuItem(); + this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem"; + this.settingsToolStripMenuItem.Size = new System.Drawing.Size(132, 22); + this.settingsToolStripMenuItem.Text = "Settings"; + this.settingsToolStripMenuItem.Click += new EventHandler(settingsToolStripMenuItem_Click); + + this.toolStripSeparator1 = new ToolStripSeparator(); + this.toolStripSeparator1.Name = "toolStripSeparator1"; + this.toolStripSeparator1.Size = new System.Drawing.Size(129, 6); + + this.exitToolStripMenuItem = new ToolStripMenuItem(); + this.exitToolStripMenuItem.Name = "exitToolStripMenuItem"; + this.exitToolStripMenuItem.Size = new System.Drawing.Size(132, 22); + this.exitToolStripMenuItem.Text = "Exit"; + this.exitToolStripMenuItem.Click += new EventHandler(exitToolStripMenuItem_Click); + + this.contextMenu = new ContextMenuStrip(); + this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.settingsToolStripMenuItem, + this.toolStripSeparator1, + this.exitToolStripMenuItem}); + this.contextMenu.Name = "contextMenu"; + this.contextMenu.ShowImageMargin = false; + this.contextMenu.Size = new System.Drawing.Size(149, 142); + + this.notifyIcon = new NotifyIcon(); + this.notifyIcon.Icon = global::GrowlExtras.FeedMonitor.Properties.Resources.feed; + this.notifyIcon.ContextMenuStrip = this.contextMenu; + this.notifyIcon.Text = "Feed Monitor"; + this.notifyIcon.DoubleClick += new EventHandler(notifyIcon_DoubleClick); + this.notifyIcon.Visible = true; + + this.mainForm = new MainForm(); + this.mainForm.Load += new EventHandler(mainForm_Load); + this.mainForm.SetComponent(this); + + InitializeGrowl(); + + InitializeFeeds(); + } + + void mainForm_Load(object sender, EventArgs e) + { + this.loaded = true; + foreach (Feed f in this.feeds) + { + f.CheckForUpdates(); + } + } + + void Application_ApplicationExit(object sender, EventArgs e) + { + ExitApp(); + } + + private void InitializeGrowl() + { + this.app = new Growl.Connector.Application("Feed Monitor"); + this.app.Icon = new BinaryData(ImageConverter.ImageToBytes(global::GrowlExtras.FeedMonitor.Properties.Resources.feed.ToBitmap())); + + this.ntNewFeedItem = new NotificationType("New Feed Item", "New Feed Item"); + this.ntFeedError = new NotificationType("Feed Error", "Feed Error"); + + this.growl = new GrowlConnector(); + this.growl.EncryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText; + + this.growl.Register(this.app, new NotificationType[] { this.ntNewFeedItem, this.ntFeedError }); + } + + private void InitializeFeeds() + { + this.feeds = new List(); + + List savedFeeds = SettingsPersister.Read(); + foreach (Feed feed in savedFeeds) + { + AddFeed(feed.Url, feed.PollInterval); + } + + if (this.feeds.Count == 0) + { + //AddFeed("http://rss.news.yahoo.com/rss/topstories", Properties.Settings.Default.DefaultInterval); + AddFeed("http://feedproxy.google.com/TechCrunch", Properties.Settings.Default.DefaultInterval); + AddFeed("http://feeds2.feedburner.com/readwriteweb", Properties.Settings.Default.DefaultInterval); + AddFeed("http://groups.google.com/group/growl-for-windows/feed/atom_v1_0_msgs.xml", Properties.Settings.Default.DefaultInterval); + } + } + + public void AddFeed(string url, int pollInterval) + { + try + { + Feed feed = Feed.Create(url, pollInterval); + feed.FeedRetrieved += new EventHandler(feed_FeedRetrieved); + feed.FeedUpdated += new EventHandler(feed_FeedUpdated); + feed.FeedError += new EventHandler(feed_FeedError); + this.feeds.Add(feed); + feed.CheckForUpdates(); + } + catch + { + // do nothing + } + } + + public void RemoveFeed(Feed feed) + { + feed.FeedRetrieved -= feed_FeedRetrieved; + feed.FeedUpdated -= feed_FeedUpdated; + this.feeds.Remove(feed); + feed = null; + } + + public List Feeds + { + get + { + return this.feeds; + } + } + + void feed_FeedError(object sender, FeedErrorEventArgs e) + { + Feed feed = (Feed)sender; + string name = (feed.Name == Feed.LOADING ? feed.Url : feed.Name); + string text = String.Format("The feed '{0}' was not able to be parsed.", name); + Notification n = new Notification(this.app.Name, this.ntFeedError.Name, "", "Feed Error", text); + this.growl.Notify(n); + } + + void feed_FeedRetrieved(object sender, FeedRetrievedEventArgs e) + { + if (this.loaded) + { + SimpleMethodDelegate del = new SimpleMethodDelegate(this.mainForm.Refresh); + this.mainForm.Invoke(del); + } + } + + void feed_FeedUpdated(object sender, FeedUpdatedEventArgs e) + { + if (e != null && e.NewItems != null) + { + foreach (SyndicationItem item in e.NewItems) + { + //this.notifyIcon.ShowBalloonTip(1000, item.SourceFeed.Title.Text, item.Title.Text, ToolTipIcon.Info); + + Notification n = new Notification(this.app.Name, this.ntNewFeedItem.Name, item.Id, item.SourceFeed.Title.Text, item.Title.Text); + + CallbackContext c = null; + if (item.Links != null && item.Links.Count > 0) + { + c = new CallbackContext(item.Links[0].Uri.ToString()); + } + + this.growl.Notify(n, c); + } + } + } + + private void ExitApp() + { + this.notifyIcon.Dispose(); + SettingsPersister.Persist(this.Feeds); + } + + void exitToolStripMenuItem_Click(object sender, EventArgs e) + { + System.Windows.Forms.Application.Exit(); + } + + void settingsToolStripMenuItem_Click(object sender, EventArgs e) + { + ShowForm(); + } + + void notifyIcon_DoubleClick(object sender, EventArgs e) + { + ShowForm(); + } + + private void ShowForm() + { + this.mainForm.Show(); + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs new file mode 100644 index 0000000..fe0e926 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.Designer.cs @@ -0,0 +1,271 @@ +namespace GrowlExtras.FeedMonitor +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.pictureBoxClose = new System.Windows.Forms.PictureBox(); + this.labelAddFeed = new System.Windows.Forms.Label(); + this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components); + this.checkNowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.setIntervalToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.oneMinuteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.twoMinutesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.fiveMinutesToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); + this.tenMinutesToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.thirtyMinutesToolStripMenuItem3 = new System.Windows.Forms.ToolStripMenuItem(); + this.panel1 = new System.Windows.Forms.Panel(); + this.labelAdd = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.textBoxFeedUrl = new System.Windows.Forms.TextBox(); + this.listViewFeeds = new GrowlExtras.FeedMonitor.FeedListView(this.components); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxClose)).BeginInit(); + this.contextMenu.SuspendLayout(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // pictureBoxClose + // + this.pictureBoxClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBoxClose.BackColor = System.Drawing.Color.Transparent; + this.pictureBoxClose.Location = new System.Drawing.Point(237, 1); + this.pictureBoxClose.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.pictureBoxClose.Name = "pictureBoxClose"; + this.pictureBoxClose.Size = new System.Drawing.Size(42, 17); + this.pictureBoxClose.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pictureBoxClose.TabIndex = 4; + this.pictureBoxClose.TabStop = false; + this.pictureBoxClose.MouseLeave += new System.EventHandler(this.pictureBoxClose_MouseLeave); + this.pictureBoxClose.Click += new System.EventHandler(this.pictureBoxClose_Click); + this.pictureBoxClose.MouseEnter += new System.EventHandler(this.pictureBoxClose_MouseEnter); + // + // labelAddFeed + // + this.labelAddFeed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.labelAddFeed.AutoSize = true; + this.labelAddFeed.BackColor = System.Drawing.Color.Transparent; + this.labelAddFeed.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelAddFeed.ForeColor = System.Drawing.Color.DarkOrange; + this.labelAddFeed.Location = new System.Drawing.Point(12, 72); + this.labelAddFeed.Name = "labelAddFeed"; + this.labelAddFeed.Size = new System.Drawing.Size(70, 16); + this.labelAddFeed.TabIndex = 7; + this.labelAddFeed.Text = "Add feed..."; + this.labelAddFeed.MouseLeave += new System.EventHandler(this.labelAddFeed_MouseLeave); + this.labelAddFeed.Click += new System.EventHandler(this.labelAddFeed_Click); + this.labelAddFeed.MouseEnter += new System.EventHandler(this.labelAddFeed_MouseEnter); + // + // contextMenu + // + this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.checkNowToolStripMenuItem, + this.setIntervalToolStripMenuItem, + this.removeToolStripMenuItem}); + this.contextMenu.Name = "contextMenu"; + this.contextMenu.ShowImageMargin = false; + this.contextMenu.Size = new System.Drawing.Size(128, 92); + // + // checkNowToolStripMenuItem + // + this.checkNowToolStripMenuItem.Name = "checkNowToolStripMenuItem"; + this.checkNowToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.checkNowToolStripMenuItem.Text = "Check Now"; + this.checkNowToolStripMenuItem.Click += new System.EventHandler(this.checkNowToolStripMenuItem_Click); + // + // removeToolStripMenuItem + // + this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; + this.removeToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.removeToolStripMenuItem.Text = "Remove"; + this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeToolStripMenuItem_Click); + // + // setIntervalToolStripMenuItem + // + this.setIntervalToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.oneMinuteToolStripMenuItem, + this.twoMinutesToolStripMenuItem, + this.fiveMinutesToolStripMenuItem1, + this.tenMinutesToolStripMenuItem2, + this.thirtyMinutesToolStripMenuItem3}); + this.setIntervalToolStripMenuItem.Name = "setIntervalToolStripMenuItem"; + this.setIntervalToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.setIntervalToolStripMenuItem.Text = "Set Interval"; + // + // oneMinuteToolStripMenuItem + // + this.oneMinuteToolStripMenuItem.Name = "oneMinuteToolStripMenuItem"; + this.oneMinuteToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.oneMinuteToolStripMenuItem.Tag = "1"; + this.oneMinuteToolStripMenuItem.Text = "1 minute"; + this.oneMinuteToolStripMenuItem.Click += new System.EventHandler(this.oneMinuteToolStripMenuItem_Click); + // + // twoMinutesToolStripMenuItem + // + this.twoMinutesToolStripMenuItem.Name = "twoMinutesToolStripMenuItem"; + this.twoMinutesToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.twoMinutesToolStripMenuItem.Tag = "2"; + this.twoMinutesToolStripMenuItem.Text = "2 minutes"; + this.twoMinutesToolStripMenuItem.Click += new System.EventHandler(this.twoMinutesToolStripMenuItem_Click); + // + // fiveMinutesToolStripMenuItem1 + // + this.fiveMinutesToolStripMenuItem1.Name = "fiveMinutesToolStripMenuItem1"; + this.fiveMinutesToolStripMenuItem1.Size = new System.Drawing.Size(152, 22); + this.fiveMinutesToolStripMenuItem1.Tag = "5"; + this.fiveMinutesToolStripMenuItem1.Text = "5 minutes"; + this.fiveMinutesToolStripMenuItem1.Click += new System.EventHandler(this.fiveMinutesToolStripMenuItem1_Click); + // + // tenMinutesToolStripMenuItem2 + // + this.tenMinutesToolStripMenuItem2.Name = "tenMinutesToolStripMenuItem2"; + this.tenMinutesToolStripMenuItem2.Size = new System.Drawing.Size(152, 22); + this.tenMinutesToolStripMenuItem2.Tag = "10"; + this.tenMinutesToolStripMenuItem2.Text = "10 minutes"; + this.tenMinutesToolStripMenuItem2.Click += new System.EventHandler(this.tenMinutesToolStripMenuItem2_Click); + // + // thirtyMinutesToolStripMenuItem3 + // + this.thirtyMinutesToolStripMenuItem3.Name = "thirtyMinutesToolStripMenuItem3"; + this.thirtyMinutesToolStripMenuItem3.Size = new System.Drawing.Size(152, 22); + this.thirtyMinutesToolStripMenuItem3.Tag = "30"; + this.thirtyMinutesToolStripMenuItem3.Text = "30 minutes"; + this.thirtyMinutesToolStripMenuItem3.Click += new System.EventHandler(this.thirtyMinutesToolStripMenuItem3_Click); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.panel1.Controls.Add(this.labelAdd); + this.panel1.Controls.Add(this.label1); + this.panel1.Controls.Add(this.textBoxFeedUrl); + this.panel1.Location = new System.Drawing.Point(1, 65); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(289, 24); + this.panel1.TabIndex = 8; + this.panel1.Visible = false; + // + // labelAdd + // + this.labelAdd.AutoSize = true; + this.labelAdd.BackColor = System.Drawing.Color.Transparent; + this.labelAdd.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Bold); + this.labelAdd.ForeColor = System.Drawing.Color.DarkOrange; + this.labelAdd.Location = new System.Drawing.Point(239, 4); + this.labelAdd.Name = "labelAdd"; + this.labelAdd.Size = new System.Drawing.Size(28, 16); + this.labelAdd.TabIndex = 2; + this.labelAdd.Text = "add"; + this.labelAdd.MouseLeave += new System.EventHandler(this.labelAdd_MouseLeave); + this.labelAdd.Click += new System.EventHandler(this.labelAdd_Click); + this.labelAdd.MouseEnter += new System.EventHandler(this.labelAdd_MouseEnter); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(4, 4); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(25, 16); + this.label1.TabIndex = 1; + this.label1.Text = "url:"; + // + // textBoxFeedUrl + // + this.textBoxFeedUrl.Location = new System.Drawing.Point(30, 2); + this.textBoxFeedUrl.Name = "textBoxFeedUrl"; + this.textBoxFeedUrl.Size = new System.Drawing.Size(203, 20); + this.textBoxFeedUrl.TabIndex = 0; + // + // listViewFeeds + // + this.listViewFeeds.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listViewFeeds.BackColor = System.Drawing.Color.White; + this.listViewFeeds.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listViewFeeds.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None; + this.listViewFeeds.LabelWrap = false; + this.listViewFeeds.Location = new System.Drawing.Point(1, 22); + this.listViewFeeds.MultiSelect = false; + this.listViewFeeds.Name = "listViewFeeds"; + this.listViewFeeds.OwnerDraw = true; + this.listViewFeeds.Scrollable = false; + this.listViewFeeds.ShowItemToolTips = true; + this.listViewFeeds.Size = new System.Drawing.Size(289, 37); + this.listViewFeeds.TabIndex = 5; + this.listViewFeeds.TileSize = new System.Drawing.Size(290, 37); + this.listViewFeeds.UseCompatibleStateImageBehavior = false; + this.listViewFeeds.View = System.Windows.Forms.View.Tile; + this.listViewFeeds.MouseClick += new System.Windows.Forms.MouseEventHandler(this.listViewFeeds_MouseClick); + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(292, 101); + this.ControlBox = false; + this.Controls.Add(this.panel1); + this.Controls.Add(this.labelAddFeed); + this.Controls.Add(this.listViewFeeds); + this.Controls.Add(this.pictureBoxClose); + this.Font = new System.Drawing.Font("Trebuchet MS", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + this.Name = "MainForm"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Text = "Form1"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxClose)).EndInit(); + this.contextMenu.ResumeLayout(false); + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBoxClose; + private FeedListView listViewFeeds; + private System.Windows.Forms.Label labelAddFeed; + private System.Windows.Forms.ContextMenuStrip contextMenu; + private System.Windows.Forms.ToolStripMenuItem checkNowToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label labelAdd; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBoxFeedUrl; + private System.Windows.Forms.ToolStripMenuItem setIntervalToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem oneMinuteToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem twoMinutesToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem fiveMinutesToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem tenMinutesToolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem thirtyMinutesToolStripMenuItem3; + } +} + diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.cs new file mode 100644 index 0000000..a92a3d6 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.cs @@ -0,0 +1,251 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; + +namespace GrowlExtras.FeedMonitor +{ + public partial class MainForm : Form + { + int borderWidth = 1; + int radius = 16; + Image normal = global::GrowlExtras.FeedMonitor.Properties.Resources.close_blue; + Image hover = global::GrowlExtras.FeedMonitor.Properties.Resources.close_red; + MainComponent mainComponent; + int bottomPadding = 60; + + public MainForm() + { + InitializeComponent(); + this.pictureBoxClose.Image = normal; + + EnsureRegion(); + + this.listViewFeeds.TileSize = this.listViewFeeds.Size; + this.bottomPadding = this.Height - this.listViewFeeds.Bottom; + + HideContextMenuImageMargin(this.contextMenu); + } + + private void HideContextMenuImageMargin(ToolStripDropDownMenu target) + { + target.ShowImageMargin = false; + foreach (ToolStripItem menuItem in target.Items) + { + ToolStripMenuItem item = menuItem as ToolStripMenuItem; + + if (item != null && item.HasDropDownItems) + { + ((ToolStripDropDownMenu)item.DropDown).ShowCheckMargin = true; + HideContextMenuImageMargin((ToolStripDropDownMenu)item.DropDown); + } + } + } + + public void SetComponent(MainComponent component) + { + this.mainComponent = component; + } + + private void pictureBoxClose_Click(object sender, EventArgs e) + { + this.Hide(); + } + + private void pictureBoxClose_MouseEnter(object sender, EventArgs e) + { + this.pictureBoxClose.Image = hover; + } + + private void pictureBoxClose_MouseLeave(object sender, EventArgs e) + { + this.pictureBoxClose.Image = normal; + } + + public new void Show() + { + this.listViewFeeds.Items.Clear(); + foreach (Feed feed in this.mainComponent.Feeds) + { + ListViewItem lvi = new ListViewItem(new string[] {feed.Name, feed.Url}); + lvi.ToolTipText = String.Format("Updates every {0} minutes", feed.PollInterval); + lvi.Tag = feed; + this.listViewFeeds.Items.Add(lvi); + } + this.listViewFeeds.Height = (this.listViewFeeds.Items.Count * this.listViewFeeds.TileSize.Height); + + ResizeForm(); + base.Show(); + } + + private void EnsureRegion() + { + Region r = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(0, 0, this.Width, this.Height, radius, radius)); + this.Region = r; + } + + private void ResizeForm() + { + this.Height = this.listViewFeeds.Top + this.listViewFeeds.Height + this.bottomPadding; + + Screen screen = Screen.PrimaryScreen; + int x = screen.WorkingArea.Right - this.Width; + int y = screen.WorkingArea.Bottom - this.Height; + this.Location = new Point(x, y); + + EnsureRegion(); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + Brush borderBrush = Brushes.Black; + e.Graphics.FillRegion(borderBrush, this.Region); + + Region gradientRegion = System.Drawing.Region.FromHrgn(CreateRoundRectRgn(borderWidth, borderWidth, this.Width - (1 * borderWidth), this.Height - (1 * borderWidth), radius - borderWidth, radius - borderWidth)); + using (gradientRegion) + { + RectangleF rect = gradientRegion.GetBounds(e.Graphics); + LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Gainsboro, Color.White, LinearGradientMode.Vertical); + using (brush) + { + float f1 = ((float)this.listViewFeeds.Top) / ((float)this.Height); + float f2 = ((float)this.listViewFeeds.Bottom) / ((float)this.Height); + Blend blend = new Blend(); + blend.Factors = new float[] { 0.0F, 1.0F, 1.0F, 0.0F }; + blend.Positions = new float[] { 0.0F, f1, f2, 1.0F }; + brush.Blend = blend; + e.Graphics.FillRegion(brush, gradientRegion); + } + } + } + + [DllImport("Gdi32.dll", EntryPoint = "CreateRoundRectRgn")] + private static extern IntPtr CreateRoundRectRgn( + int nLeftRect, // x-coordinate of upper-left corner + int nTopRect, // y-coordinate of upper-left corner + int nRightRect, // x-coordinate of lower-right corner + int nBottomRect, // y-coordinate of lower-right corner + int nWidthEllipse, // height of ellipse + int nHeightEllipse // width of ellipse + ); + + private void labelAddFeed_Click(object sender, EventArgs e) + { + this.panel1.Show(); + this.textBoxFeedUrl.Focus(); + } + + private void listViewFeeds_MouseClick(object sender, MouseEventArgs e) + { + this.contextMenu.Hide(); + + if (e.Button == MouseButtons.Right) + { + ListViewItem item = this.listViewFeeds.GetItemAt(e.X, e.Y); + if (item != null && item.Tag != null) + { + Feed feed = item.Tag as Feed; + if (feed != null) + { + foreach (ToolStripMenuItem tsi in this.setIntervalToolStripMenuItem.DropDown.Items) + { + tsi.Checked = false; + int i = Convert.ToInt32(tsi.Tag); + if (i == feed.PollInterval) tsi.Checked = true; + } + this.contextMenu.Tag = feed; + this.contextMenu.Show(this.listViewFeeds, e.Location); + } + } + } + } + + private void checkNowToolStripMenuItem_Click(object sender, EventArgs e) + { + Feed feed = (Feed)this.contextMenu.Tag; + feed.CheckForUpdates(); + } + + private void removeToolStripMenuItem_Click(object sender, EventArgs e) + { + Feed feed = (Feed)this.contextMenu.Tag; + this.mainComponent.RemoveFeed(feed); + this.Show(); + this.Refresh(); + } + + private void labelAdd_Click(object sender, EventArgs e) + { + if (!String.IsNullOrEmpty(this.textBoxFeedUrl.Text)) + { + this.mainComponent.AddFeed(this.textBoxFeedUrl.Text, Properties.Settings.Default.DefaultInterval); + this.panel1.Hide(); + this.Show(); + this.Refresh(); + } + else + { + this.panel1.Hide(); + } + } + + private void labelAdd_MouseEnter(object sender, EventArgs e) + { + this.Cursor = Cursors.Hand; + } + + private void labelAdd_MouseLeave(object sender, EventArgs e) + { + this.Cursor = Cursors.Default; + } + + private void labelAddFeed_MouseEnter(object sender, EventArgs e) + { + this.Cursor = Cursors.Hand; + } + + private void labelAddFeed_MouseLeave(object sender, EventArgs e) + { + this.Cursor = Cursors.Default; + } + + private void SetFeedInterval(object sender) + { + ToolStripMenuItem item = sender as ToolStripMenuItem; + item.Checked = true; + int i = Convert.ToInt32(item.Tag); + Feed feed = (Feed)this.contextMenu.Tag; + feed.PollInterval = i; + } + + private void oneMinuteToolStripMenuItem_Click(object sender, EventArgs e) + { + SetFeedInterval(sender); + } + + private void twoMinutesToolStripMenuItem_Click(object sender, EventArgs e) + { + SetFeedInterval(sender); + } + + private void fiveMinutesToolStripMenuItem1_Click(object sender, EventArgs e) + { + SetFeedInterval(sender); + } + + private void tenMinutesToolStripMenuItem2_Click(object sender, EventArgs e) + { + SetFeedInterval(sender); + } + + private void thirtyMinutesToolStripMenuItem3_Click(object sender, EventArgs e) + { + SetFeedInterval(sender); + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.resx b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.resx new file mode 100644 index 0000000..a0af97c --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/MainForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Program.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Program.cs new file mode 100644 index 0000000..d0d916a --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace GrowlExtras.FeedMonitor +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + MainComponent mc = new MainComponent(); + Application.Run(); + mc = null; + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..29b7468 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GrowlExtras.FeedMonitor")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("element code project")] +[assembly: AssemblyProduct("GrowlExtras.FeedMonitor")] +[assembly: AssemblyCopyright("Copyright © element code project 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("9cae0c98-5dbe-49e7-9150-8f786a4eaee7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.1.0")] diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.Designer.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.Designer.cs new file mode 100644 index 0000000..724f1f7 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.Designer.cs @@ -0,0 +1,84 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace GrowlExtras.FeedMonitor.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GrowlExtras.FeedMonitor.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static System.Drawing.Bitmap close_blue { + get { + object obj = ResourceManager.GetObject("close_blue", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Bitmap close_red { + get { + object obj = ResourceManager.GetObject("close_red", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + internal static System.Drawing.Icon feed { + get { + object obj = ResourceManager.GetObject("feed", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.resx b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.resx new file mode 100644 index 0000000..9c4779a --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Resources.resx @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\close_blue.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\close_red.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\feed.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.Designer.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.Designer.cs new file mode 100644 index 0000000..63991fc --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.Designer.cs @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.1433 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace GrowlExtras.FeedMonitor.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("5")] + public int DefaultInterval { + get { + return ((int)(this["DefaultInterval"])); + } + set { + this["DefaultInterval"] = value; + } + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.settings b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.settings new file mode 100644 index 0000000..5ab03ba --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Properties/Settings.settings @@ -0,0 +1,9 @@ + + + + + + 5 + + + \ No newline at end of file diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Resources/close_blue.png b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/Resources/close_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..1e5d68b37b2261286fceeb9b180911f4d70e4908 GIT binary patch literal 769 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 FeedRetrieved; + public event EventHandler FeedUpdated; + public event EventHandler FeedError; + + public const string LOADING = "Loading..."; + private const string _nullResultErrorMessage = "The returned stream was null."; + private const string _parseErrorMessage = "Unable to parse feed."; + + private string name; + private Uri url; + private int pollInterval; + private DateTime lastCheckForUpdates; + private DateTimeOffset feedLastUpdated; + private WebClient webclient; + private System.Timers.Timer timer; + + private Feed() { } + + public static Feed Create(string url, int pollInterval) + { + return new Feed(url, pollInterval, DateTime.MaxValue); + } + + private Feed(string url, int pollInterval, DateTime lastCheckForUpdates) + { + this.name = LOADING; + this.url = new Uri(url); + this.pollInterval = pollInterval; + this.lastCheckForUpdates = lastCheckForUpdates; + this.feedLastUpdated = DateTimeOffset.MaxValue; + + this.timer = new System.Timers.Timer(); + this.timer.Interval = this.pollInterval * 60 * 1000; + this.timer.AutoReset = false; + this.timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); + + this.webclient = new WebClient(); + this.webclient.Encoding = Encoding.UTF8; + this.webclient.OpenReadCompleted += new OpenReadCompletedEventHandler(webclient_OpenReadCompleted); + + //CheckForUpdates(); + } + + public string Name + { + get + { + return this.name; + } + } + + public string Url + { + get + { + return this.url.ToString(); + } + } + + public int PollInterval + { + get + { + return this.pollInterval; + } + set + { + this.pollInterval = value; + this.timer.Interval = this.pollInterval * 60 * 1000; + } + } + + void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + this.timer.Stop(); + this.CheckForUpdates(); + } + + public void CheckForUpdates() + { + if (!this.webclient.IsBusy) + { + this.webclient.OpenReadAsync(this.url); + this.lastCheckForUpdates = DateTime.Now; + } + } + + void webclient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) + { + // process the feed + if (e.Error == null && e.Result != null) + { + using (XmlReader reader = XmlReader.Create(e.Result)) + { + try + { + SyndicationFeed feed = null; + try + { + feed = SyndicationFeed.Load(reader); + } + catch + { + // the loader couldn't load the feed, but it might be RSS 1.0, so try that + Rss10FeedFormatter formatter = new Rss10FeedFormatter(); + if (formatter.CanRead(reader)) + { + formatter.ReadFrom(reader); + feed = formatter.Feed; + } + } + OnFeedRetrieved(feed); + } + catch (Exception ex) + { + // the loader couldn't load the feed + FeedErrorEventArgs args = new FeedErrorEventArgs(new FeedException(_parseErrorMessage, ex)); + OnFeedError(args); + } + } + } + else + { + if (e.Error != null) + { + // there was an error returned from the call + FeedErrorEventArgs args = new FeedErrorEventArgs(e.Error); + OnFeedError(args); + } + else + { + // an empty stream. + FeedErrorEventArgs args = new FeedErrorEventArgs(new FeedException(_nullResultErrorMessage)); + OnFeedError(args); + } + } + + // restart the timer + this.timer.Start(); + } + + /// + /// Internal method used to raise the feed event + /// + protected void OnFeedRetrieved(SyndicationFeed feed) + { + this.name = feed.Title.Text; + DateTimeOffset mostRecentItem = this.feedLastUpdated; + if (mostRecentItem == DateTimeOffset.MaxValue) mostRecentItem = DateTimeOffset.MinValue; + + System.Diagnostics.Debug.WriteLine(String.Format("Feed Retrieved: {0} - Most Recent Item: {1}", this.name, mostRecentItem)); + + if (FeedRetrieved != null) + { + FeedRetrievedEventArgs e = new FeedRetrievedEventArgs(feed); + FeedRetrieved(this, e); + } + + if (FeedUpdated != null) + { + List newitems = new List(); + foreach (SyndicationItem item in feed.Items) + { + DateTimeOffset itemDate = item.LastUpdatedTime; + if (itemDate == DateTimeOffset.MinValue) itemDate = item.PublishDate; + + System.Diagnostics.Debug.WriteLine(String.Format("Item Published at: {0} - (last update at: {1})", itemDate, this.feedLastUpdated)); + + if (itemDate > mostRecentItem) + mostRecentItem = itemDate; + + if (itemDate > this.feedLastUpdated) + { + newitems.Add(item); + //item.SourceFeed.Title = feed.Title; // override this value since some feed items specify a different source (and we dont want that) + item.SourceFeed = feed; + } + } + + FeedUpdatedEventArgs args = new FeedUpdatedEventArgs(newitems); + FeedUpdated(this, args); + } + this.feedLastUpdated = mostRecentItem; // feed.LastUpdatedTime is not always set =( + } + + /// + /// Internal method used to raise the error event + /// + protected void OnFeedError(FeedErrorEventArgs args) + { + if (FeedError != null) + FeedError(this, args); + } + } + + public class FeedException : Exception + { + public FeedException() + : base("Exception retrieving or processing feed.") + { + } + + public FeedException(string message) + : base("Exception retrieving or processing feed. " + message) + { + } + + public FeedException(string message, Exception innerException) + : base("Exception retrieving or processing feed. " + message, innerException) + { + } + + } + + public class FeedUpdatedEventArgs : EventArgs + { + private List newitems; + + public FeedUpdatedEventArgs(List newitems) + { + this.newitems = newitems; + } + + public List NewItems + { + get { return this.newitems; } + } + + } + + public class FeedRetrievedEventArgs : EventArgs + { + private SyndicationFeed feed; + + public FeedRetrievedEventArgs(SyndicationFeed feed) + { + this.feed = feed; + } + + public SyndicationFeed Feed + { + get { return this.feed; } + } + + } + + public class FeedErrorEventArgs : EventArgs + { + private Exception exception; + + public FeedErrorEventArgs(Exception exception) + { + this.exception = exception; + } + + public Exception Error + { + get { return this.exception; } + } + + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Rss10FeedFormatter.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Rss10FeedFormatter.cs new file mode 100644 index 0000000..23b5f69 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/Rss10FeedFormatter.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.ObjectModel; +using System.Xml; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.ServiceModel.Syndication; + +namespace GrowlExtras.FeedMonitor +{ + public class Rss10FeedFormatter : SyndicationFeedFormatter + { + #region Constructors + public Rss10FeedFormatter() { } + + public Rss10FeedFormatter(SyndicationFeed feed) : base(feed) { } + #endregion + + #region Properties + public override string Version + { + get { return "Rss10"; } + } + + public virtual string RdfNamespaceUri + { + get { return "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; } + } + + public virtual string NamespaceUri + { + get { return "http://purl.org/rss/1.0/"; } + } + #endregion + + #region Methods + #region Read XML Methods + public override bool CanRead(System.Xml.XmlReader reader) + { + if (reader == null) + throw new ArgumentNullException("reader"); + + return reader.IsStartElement("RDF", this.RdfNamespaceUri); + } + + protected override SyndicationFeed CreateFeedInstance() + { + return new SyndicationFeed(); + } + + public override void ReadFrom(System.Xml.XmlReader reader) + { + if (!this.CanRead(reader)) + throw new XmlException("Unknown RSS 1.0 feed format."); + + this.ReadFeed(reader); + } + + private void ReadFeed(XmlReader reader) + { + this.SetFeed(this.CreateFeedInstance()); + this.ReadXml(reader, base.Feed); + } + + protected virtual void ReadXml(XmlReader reader, SyndicationFeed result) + { + if (result == null) + throw new ArgumentNullException("result"); + else if (reader == null) + throw new ArgumentNullException("reader"); + + reader.ReadStartElement(); // Read in + reader.ReadStartElement("channel"); // Read in + while (reader.IsStartElement()) // Process children + { + if (reader.IsStartElement("title")) + result.Title = new TextSyndicationContent(reader.ReadElementString()); + else if (reader.IsStartElement("link")) + result.Links.Add(new SyndicationLink(new Uri(reader.ReadElementString()))); + else if (reader.IsStartElement("description")) + result.Description = new TextSyndicationContent(reader.ReadElementString()); + else + reader.Skip(); + } + reader.ReadEndElement(); // Read in + + while (reader.IsStartElement()) + { + if (reader.IsStartElement("item")) + { + result.Items = this.ReadItems(reader, result); + + break; + } + else + reader.Skip(); + } + } + + protected virtual IEnumerable ReadItems(XmlReader reader, SyndicationFeed feed) + { + if (feed == null) + throw new ArgumentNullException("feed"); + else if (reader == null) + throw new ArgumentNullException("reader"); + + Collection items = new Collection(); + while (reader.IsStartElement("item")) + { + items.Add(this.ReadItem(reader, feed)); + } + + return items; + } + + protected virtual SyndicationItem ReadItem(XmlReader reader, SyndicationFeed feed) + { + if (feed == null) + throw new ArgumentNullException("feed"); + else if (reader == null) + throw new ArgumentNullException("reader"); + + SyndicationItem result = new SyndicationItem(); + this.ReadItemFrom(reader, result); + + return result; + } + + protected virtual void ReadItemFrom(XmlReader reader, SyndicationItem result) + { + if (result == null) + throw new ArgumentNullException("result"); + else if (reader == null) + throw new ArgumentNullException("reader"); + + reader.ReadStartElement(); + while (reader.IsStartElement()) + { + if (reader.IsStartElement("title")) + result.Title = new TextSyndicationContent(reader.ReadElementString()); + else if (reader.IsStartElement("link")) + result.Links.Add(new SyndicationLink(new Uri(reader.ReadElementString()))); + else if (reader.IsStartElement("description")) + result.Summary = new TextSyndicationContent(reader.ReadElementString()); + else + reader.Skip(); + } + reader.ReadEndElement(); + } + #endregion + + #region Write XML Methods + public override void WriteTo(System.Xml.XmlWriter writer) + { + if (writer == null) + throw new ArgumentNullException("writer"); + + writer.WriteStartElement("rdf", "RDF", this.RdfNamespaceUri); // Write + writer.WriteAttributeString("xmlns", this.NamespaceUri); + this.WriteFeed(writer); + writer.WriteEndElement(); + } + + protected virtual void WriteFeed(XmlWriter writer) + { + if (writer == null) + throw new ArgumentNullException("writer"); + if (base.Feed == null) + throw new InvalidOperationException("Feed formatter does not have a feed."); + + string alternateLink = string.Empty, selfLink = string.Empty; + foreach (SyndicationLink lnk in base.Feed.Links) + { + if (alternateLink.Length == 0 && lnk.RelationshipType == "alternate") + alternateLink = lnk.Uri.IsAbsoluteUri ? lnk.Uri.AbsoluteUri : lnk.Uri.ToString(); + else if (selfLink.Length == 0 && lnk.RelationshipType == "self") + selfLink = lnk.Uri.IsAbsoluteUri ? lnk.Uri.AbsoluteUri : lnk.Uri.ToString(); + } + + if (selfLink.Length == 0 && alternateLink.Length > 0) + selfLink = alternateLink; + else if (alternateLink.Length == 0 && selfLink.Length > 0) + alternateLink = selfLink; + + + writer.WriteStartElement("channel"); // Write + writer.WriteAttributeString("about", this.RdfNamespaceUri, selfLink); + + if (base.Feed.Title == null || string.IsNullOrEmpty(base.Feed.Title.Text)) + throw new ArgumentException("Feed title required for RSS 1.0 feeds."); + writer.WriteElementString("title", base.Feed.Title.Text); // Write + + + if (alternateLink.Length == 0) + throw new ArgumentException("Feed link required for RSS 1.0 feeds."); + writer.WriteElementString("link", alternateLink); // Write <link> + + + if (base.Feed.Description == null || string.IsNullOrEmpty(base.Feed.Description.Text)) + throw new ArgumentException("Feed title required for RSS 1.0 feeds."); + writer.WriteElementString("description", base.Feed.Description.Text); // Write <description> + + + writer.WriteStartElement("items"); // Write <items> + writer.WriteStartElement("Seq", this.RdfNamespaceUri); + foreach (SyndicationItem item in base.Feed.Items) + { + string itemAlternateLink = GetAlternateLinkForItem(item); + + writer.WriteStartElement("li", this.RdfNamespaceUri); + writer.WriteAttributeString("resource", this.RdfNamespaceUri, itemAlternateLink); + writer.WriteEndElement(); + } + writer.WriteEndElement(); + writer.WriteEndElement(); + + writer.WriteEndElement(); // Write </channel> + + // Write the <item> elements + this.WriteItems(writer, base.Feed.Items); + } + + protected virtual void WriteItems(XmlWriter writer, IEnumerable<SyndicationItem> items) + { + if (writer == null) + throw new ArgumentNullException("writer"); + + if (items != null) + foreach (SyndicationItem item in items) + this.WriteItem(writer, item); + } + + protected virtual void WriteItem(XmlWriter writer, SyndicationItem item) + { + if (writer == null) + throw new ArgumentNullException("writer"); + + string alternateLink = GetAlternateLinkForItem(item); + + writer.WriteStartElement("item"); // Write <item> + writer.WriteAttributeString("about", this.RdfNamespaceUri, alternateLink); + this.WriteItemContents(writer, item); + writer.WriteEndElement(); + } + + protected virtual void WriteItemContents(XmlWriter writer, SyndicationItem item) + { + if (writer == null) + throw new ArgumentNullException("writer"); + + if (item.Title == null || string.IsNullOrEmpty(item.Title.Text)) + throw new ArgumentException("Feed title required for RSS 1.0 feeds."); + writer.WriteElementString("title", item.Title.Text); // Write <title> + + + string alternateLink = GetAlternateLinkForItem(item); + if (string.IsNullOrEmpty(alternateLink)) + throw new ArgumentException("Feed link required for RSS 1.0 feeds."); + writer.WriteElementString("link", alternateLink); // Write <link> + + + if (base.Feed.Description != null && string.IsNullOrEmpty(item.Summary.Text) == false) + writer.WriteElementString("description", item.Summary.Text); // Write the optional <description> + } + + private string GetAlternateLinkForItem(SyndicationItem item) + { + foreach (SyndicationLink lnk in item.Links) + if (lnk.RelationshipType == "alternate") + return lnk.Uri.IsAbsoluteUri ? lnk.Uri.AbsoluteUri : lnk.Uri.ToString(); + + // If we reach here, return an empty string + return string.Empty; + } + #endregion + #endregion + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs new file mode 100644 index 0000000..1a28b84 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/SettingsPersister.cs @@ -0,0 +1,195 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; + +namespace GrowlExtras.FeedMonitor +{ + internal static class SettingsPersister + { + private const string FEED_SETTINGS_SECTION_NAME = "feeds"; + + private static string configPath; + + static SettingsPersister() + { + System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly(); + System.Diagnostics.FileVersionInfo fileVersionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(a.Location); + + string root = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + string folder = String.Format(@"Growl Extras\Feed Monitor\{0}", a.GetName().Version.ToString()); + string configFolder = System.IO.Path.Combine(root, folder); + if (!configFolder.EndsWith(@"\")) configFolder += @"\"; + if (!System.IO.Directory.Exists(configFolder)) System.IO.Directory.CreateDirectory(configFolder); + configPath = System.IO.Path.Combine(configFolder, "user.config"); + } + + public static void Persist(List<Feed> feeds) + { + // save feed info + try + { + //Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); + Configuration configuration = OpenConfig(); + FeedsSection section = (FeedsSection) configuration.GetSection(FEED_SETTINGS_SECTION_NAME); + if (section == null) + { + section = new FeedsSection(); + section.LockItem = false; + section.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser; + section.SectionInformation.ForceSave = true; + configuration.Sections.Add(FEED_SETTINGS_SECTION_NAME, section); + } + section.Feeds.Clear(); + + foreach (Feed feed in feeds) + { + FeedElement fe = new FeedElement(); + fe.Name = feed.Name; + fe.Url = feed.Url; + fe.PollInterval = feed.PollInterval; + section.Feeds.Add(fe); + } + + configuration.Save(); + } + catch + { + } + } + + public static List<Feed> Read() + { + // read feed info + List<Feed> feeds = new List<Feed>(); + try + { + //Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal); + Configuration configuration = OpenConfig(); + FeedsSection section = (FeedsSection)configuration.GetSection(FEED_SETTINGS_SECTION_NAME); + if (section != null) + { + foreach (FeedElement fe in section.Feeds) + { + Feed feed = Feed.Create(fe.Url, fe.PollInterval); + feeds.Add(feed); + } + } + } + catch + { + } + return feeds; + } + + private static Configuration OpenConfig() + { + ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); + fileMap.ExeConfigFilename = configPath; + return ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None); + } + + private class FeedsSection : ConfigurationSection + { + private static ConfigurationPropertyCollection s_properties; + private static ConfigurationProperty s_propFeeds; + + public FeedsSection() + { + EnsureStaticPropertyBag(); + } + + [ConfigurationProperty("", IsDefaultCollection=true)] + public FeedsElement Feeds + { + get + { + return (FeedsElement)base[s_propFeeds]; + } + } + + private static ConfigurationPropertyCollection EnsureStaticPropertyBag() + { + if (s_properties == null) + { + s_propFeeds = new ConfigurationProperty(null, typeof(FeedsElement), null, ConfigurationPropertyOptions.IsDefaultCollection); + ConfigurationPropertyCollection propertys = new ConfigurationPropertyCollection(); + propertys.Add(s_propFeeds); + s_properties = propertys; + } + return s_properties; + } + } + + private class FeedsElement : ConfigurationElementCollection + { + protected override ConfigurationElement CreateNewElement() + { + return new FeedElement(); + } + + protected override object GetElementKey(ConfigurationElement element) + { + return ((FeedElement)element).Url; + } + + public void Add(FeedElement feed) + { + this.BaseAdd(feed); + } + + public void Clear() + { + this.BaseClear(); + } + } + + + private class FeedElement : ConfigurationElement + { + public FeedElement() + { + } + + [ConfigurationProperty("name")] + public string Name + { + get + { + return (string)this["name"]; + } + set + { + this["name"] = value; + } + } + + [ConfigurationProperty("url")] + public string Url + { + get + { + return (string)this["url"]; + } + set + { + this["url"] = value; + } + } + + [ConfigurationProperty("pollinterval")] + public int PollInterval + { + get + { + return (int)this["pollinterval"]; + } + set + { + this["pollinterval"] = value; + } + } + } + } +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/User32DLL.cs b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/User32DLL.cs new file mode 100644 index 0000000..4b249e2 --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/_source/User32DLL.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; + +namespace GrowlExtras.FeedMonitor +{ + /// <summary> + /// Provides access to Win32 unmanaged APIs + /// </summary> + public static class User32DLL + { + #region Class Variables + public const int SM_CXSCREEN = 0; + public const int SM_CYSCREEN = 1; + public const int SW_SHOWNOACTIVATE = 4; + public const int SW_SHOW = 5; + public const int SW_RESTORE = 9; + public const int HWND_TOPMOST = -0x1; + public const int SWP_NOACTIVATE = 0x0010; + public const int SWP_NOMOVE = 0x0002; + public const int SWP_NOSIZE = 0x0001; + #endregion + + #region Class Functions + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + + [DllImport("user32.dll")] + public static extern IntPtr SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + #endregion + } + +} diff --git a/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/app.config b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/app.config new file mode 100644 index 0000000..856ee2d --- /dev/null +++ b/Growl Extras/Feed Monitor/GrowlExtras.FeedMonitor/app.config @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8" ?> +<configuration> + <configSections> + <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > + <section name="GrowlExtras.FeedMonitor.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" /> + </sectionGroup> + </configSections> + <userSettings> + <GrowlExtras.FeedMonitor.Properties.Settings> + <setting name="DefaultInterval" serializeAs="String"> + <value>5</value> + </setting> + </GrowlExtras.FeedMonitor.Properties.Settings> + </userSettings> +</configuration> \ No newline at end of file