Compare commits

...

12 Commits

Author SHA1 Message Date
Andy
938042ea9e 2023.6.5.0
YT settings: removed property 'ItemsListLimit', add property 'ReplaceModificationDate'
YT.MediaItem: fix 'Pending'
YT.VideoListForm: add 'Shift' to add without downloading; add 'F5' hot key to start download; remove list items limit; fix item 'Pending', fixed items queue

UserDataBase: add 'IconBannerDownloaded' properties; add 'HOST.Available' check to 'DownloadSingleObject'; update file deletion in 'DownloadContentDefault'; add truncating '_TempPostsList' if number of ids > 1000
Instagram: add authorization headers
Mastodon: implement 'DownloadIconBanner'; update 'ReparseMissing' function
Reddit: implement 'DownloadIconBanner'
Twitter: implement 'DownloadIconBanner'; update parsers to parse posts with two videos; implement gallery-dl for all function; remove headers from settings
Download.DownloadProgress: remove main progress perform when downloading saved posts
VideoDownloaderForm: bind the 'BTT_ADD_URLS_ARR' button to the 'BTT_ADD_KeyClick' function
UsersInfoForm: add folder opening on double click on an item
ListImagesLoader: fix refill bug when the number of filtered profiles = 0
TrayIcon: add standalone downloader to context menu
DownloadableMediaHost: fix a bug when not downloaded videos do not appear in the list when loading the program
2023-06-05 19:36:35 +03:00
Andy
abdef81e5f Update README.md 2023-06-03 11:51:01 +03:00
Andy
e868c2e694 2023.5.12.0
IPluginContentProvider: add 'ProgressPreChanged' and 'ProgressPreMaximumChanged' events
YT.MediaItem: change folder opening on double click
YT.VideoListForm: change the icon for the 'Download' button

Add advanced progress
Add user metrics calculation
UserDataBase: fix GIF hash bug
Instagram: heic to jpg
Mastodon.SiteSettings: add the main domain to the list of domains with saving the settings
Mastodon.UserData: handle 'Forbidden' error; fix bug in parsing non-user posts
Pinterest: remove cookies requirement for saved posts
PornHub: fix resolutions issue; add 'DownloadUHD' option
Reddit: fix missing images bug; fix broken images bug; update container parsing function
MainFrame: fix collection pointing bug
2023-05-12 20:00:32 +03:00
Andy
b2a9b22478 2023.4.28.0
Plugins
IPluginContentProvider: added DownloadSingleObject function; added tokens to GetMedia and Download functions; removed GetSpecialData function
Add IDownloadableMedia interface
Removed 'Channel' option from all functions and enums
ISiteSettings: added GetSingleMediaInstance function
ExchangeOptions: removed 'IsChannel'
UserMediaTypes: added Audio and AudioPre enums
IUserMedia, PluginUserMedia: changed ContentType and DownloadState from integers to their enums

SCrawler
Add YouTube standalone downloader
Add gallery-dl & yt-dlp support
Remove 'UserInfo' requirement from 'ProfilesSaved'
Update 'SiteSettingsBase' to use domains and Netscape cookies
UserDataBase: remove channels; remove old 'Merge' const; standardize SavedPosts file naming; move 'ValidateMD5' function from Twitter to UserDataBase to use it in other UserData classes; add 'DownloadSingleObject' environment for single posts; add validating file extension for m3u8 during download; add reindex of video file during download

Rewritten DomainsContainer
Create a universal settings form and PSettingsArttribute
Gfycat, Imgur: turn these classes into IUserData to download a single object

All plugins: update 'GetInstance' function for saved posts; update domains where implemented; remove 'OptionForm' where it exists; update options where they exist; update unix date providers; reconfigure channels where they exist

LPSG: fix attachments; update converters and regex
Add sites: ThisVid, Mastodon, Pinterest, YouTube, YouTube music
Reddit: standardize container parsing for all data types; new channel environment; fix 'ReparseMissing' function; redirect data downloading to the base download function, saved crossposts support
Twitter: fixed gif path bug; fixed downloading saved posts
PornHub: hide unnecessary errors; photo galleries bug
RedGifs: add 'UserAgent' option

Added icons to download progress

Rename some objects
Completely redesigned standalone downloader form and rewritten its environment
WebClient2: update to use tokens

Labels: update label form (save labels to file only when OK button is clicked); change removing labels.txt from recycle bin to permanent; disable storing label 'NoParsedUser'

UserCreatorForm: remove the 'Channel' checkbox and related functions; ability to extract the user's URL from the buffer and apply parameters if found
Remove temporary 'EncryptCookies' module

MainFrame: added simplified way to create new users (Ctrl+Insert to create a new user with default parameters from clipboard URL); removed SCrawler command line argument "-v" (remove the ability to run SCrawler as video downloader)
PropertyValueHost: update for option forms compatibility
SettingsHost: removed 'GetSpecialData' fork; added 'GetSingleMediaInstance' fork
UserDataHost: update functions with tokens; update events; add 'DownloadSingleObject' function
Settings: add the ability to get environment from 4 destinations; add the ability to set the program environment manually; add CMDEncoding; add cache; remove the old function 'RemoveUnusedPlugins'; add 'STDownloader' properties; add YT compatibility; add new notification options; add deleting user settings file when 'SettingsCLS.Dispose()' if where are no users in SCrawler
UserFinder: remove old 'Merge' const; remove channel option
UserInfo: remove channel option
2023-04-28 10:13:46 +03:00
Andy
db9e2cfb88 2023.3.5.0
Fixed SavedPosts new file naming method
Fixed Twitter MD5 comparison error
Fixed ffmpeg file parts concatenation algorithm
2023-03-05 06:12:08 +03:00
Andy
85d8df96ca 2023.3.1.0
Add 'Path' plugin
UserDataBase: changed file names for saved posts; removed 'Self' property; add 'MyFileSettings' field; added UserSiteName; changed download envir algo
Twitter: added MD5 comparison; duplicate images removal option; UserSiteName parsing; download icon and banner
Instagram: added a new option for token 'www_claim'; removed requirement of token 'www_claim'; UserSiteName parsing; download icon
Reddit: UserSiteName parsing; download icon and banner
PornHub: fixed unicode titles
XHamster: added channels
ffmpeg: fixed max input length error during files combining; fixed encoding issue
Feed: added images centering; added BackColor and ForeColor change
MainFrame: added BackColor, ForeColor, and BackgroungImage change; added 'UpdateLogButton' when load completed
ListImagesLoader: fixed wrong notification when no users found
SettingsCLS: updated users loading algo
2023-03-01 20:35:52 +03:00
Andy
6ca90f0489 Update names 2023-02-25 10:19:18 +03:00
Andy
2a780a3acf Update README.md 2023-02-13 11:44:00 +03:00
Andy
290b5c4586 2023.2.5.0
Update to library environment
GlobalSettings: add UserAgent
Gfycat: fix RedGifs urls issue
2023-02-05 20:58:02 +03:00
Andy
f5e68a7032 Update Changelog.md 2023-01-28 05:50:07 +03:00
Andy
ece573dd40 Update README.md 2023-01-28 05:48:54 +03:00
Andy
1f1148020c 2023.1.27.0
Plugins: added 'Interaction' to 'Provider' attribute; added 'IPropertyProvider' interface
Hosts: update classes to work with new options
Instagram: fixed pinned post reload
Twitter: advanced options for GIFs
UserCreatorForm: change icon based on the selected site
UserSearchForm: change search function
2023-01-27 16:43:57 +03:00
290 changed files with 22148 additions and 3465 deletions

3
.gitattributes vendored
View File

@@ -1,2 +1,5 @@
# Auto detect text files and perform LF normalization
* text=auto
# Declare files that will always have CRLF line endings on checkout.
*.md text eol=crlf

4
.github/FUNDING.yml vendored
View File

@@ -3,11 +3,11 @@
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: andyprogram
ko_fi: #andyprogram
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: ['https://blockchair.com/bitcoin/address/BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET']
custom: ['https://github.com/AAndyProgram/SCrawler/blob/main/HowToSupport.md']

View File

@@ -13,11 +13,16 @@ A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. **Profile URL**:
2. Do something
3. See error
2. **Post URL**:
3. Do something
4. See error
**Log data**
If the program log contains any data.
<details>
<summary>Log data</summary>
<pre>
If the program log contains any data, replace this line with the log data. If the program log does not contain any data, write here about.
</pre>
</details>
**Expected behavior**
A clear and concise description of what you expected to happen.
@@ -26,10 +31,13 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Release information (please complete the following information):**
- OS [e.g. Windows 10, Windows 11]
- Architecture [e.g. x86, x64]
- Version [e.g. 2.0.0.0]
- NET.Framework version
- OS: [e.g. Windows 10, Windows 11]
- Architecture: [e.g. x86, x64]
- Version: [e.g. 2023.3.5.0]
- NET.Framework version:
- ffmpeg version (command `ffmpeg -version`):
- yt-dlp version (command `yt-dlp --version`):
- gallery-dl version (command `gallery-dl --version`):
**Additional context**
Add any other context about the problem here.

6
.gitignore vendored
View File

@@ -9,8 +9,9 @@
*.user
*.userosscache
*.sln.docstates
ffmpeg.exe
.obsidian/
ToDo.txt
ToDo.md
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -33,10 +34,7 @@ bld/
[Oo]bj/
[Ll]og/
[Ll]ogs/
ffmpeg/
cURL/
Info/
Hidden/
# Visual Studio 2015/2017 cache/options directory
.vs/

View File

@@ -8,20 +8,21 @@ I welcome requests! Follow these steps to contribute:
1. If you have a code change suggestion, you can post a replacement code block. I also accept pull requests.
# How to build from source
1. Delete the ```PersonalUtilities``` project from the solution.
1. Delete the ```PersonalUtilities.Notifications``` project from the solution.
1. Delete the ```cURL``` folder from the solution.
1. Delete the ```ffmpeg.exe``` from the solution.
1. Delete the `PersonalUtilities` project from the solution.
1. Delete the `PersonalUtilities.Notifications` project from the solution.
1. The following libraries must be added to project references with the '**Copy to output folder**' option:
- ```PersonalUtilities.dll```
- ```PersonalUtilities.Notifications.dll```
- ```Microsoft.Toolkit.Uwp.Notifications.dll```
- ```System.ValueTuple.dll```
1. Import ```PersonalUtilities.Functions``` for the whole project.
- `PersonalUtilities.dll`
- `PersonalUtilities.Notifications.dll`
- `Microsoft.Toolkit.Uwp.Notifications.dll`
- `System.ValueTuple.dll`
1. Import `PersonalUtilities.Functions` for the whole project.
**Always use the correct libraries. You must download libraries from the same release date as the code commit date.**
# How to request a new site
**I'm currently not accepting requests to develop new sites.**
1. Check [issues](https://github.com/AAndyProgram/SCrawler/issues) (open and [closed](https://github.com/AAndyProgram/SCrawler/issues?q=is%3Aissue+is%3Aclosed)) and [discussions](https://github.com/AAndyProgram/SCrawler/discussions) to find your issue. Perhaps I have already answered your request.
1. If you don't find anything, create a new issue with your request. I usually reply as soon as possible (within the next few hours).

View File

@@ -1,3 +1,138 @@
# 2023.6.5.0
*2023-06-05*
- Added
- **Instagram**: add additional authorization headers
- Setting to prevent user icon and banner from downloading (Request #129)
- Add standalone downloader to tray context menu
- YouTube downloader: added `Replace modification date` property
- Minor improvements
- Fixed
- Fascist **Twitter**: posts not downloading (new API)
- Main window: refill bug when the number of filtered profiles = 0
- Standalone downloader: new items are not added to the queue
- Standalone downloader: bug when not downloaded videos do not appear in the list when loading the program
- Standalone downloader: add videos array not working
- Saved posts: remove main progress perform when downloading saved posts
- Minor bugs
# 2023.5.12.0
*2023-05-12*
- Added
- Advanced progress (make progress bars more informative)
- User metrics calculation
- Reddit: improve parsing function
- PornHub: add `Download UHD` option
- Fixed
- MD5 GIF hash bug
- Mastodon: handle 'Forbidden' error
- Mastodon: bug in parsing non-user posts
- Pinterest: remove cookies requirement for saved posts
- PornHub: resolutions issue
- Reddit: missing & broken images bug
- Main window: collection pointing bug
# 2023.4.28.0
*2023-04-28*
- Added
- **YouTube**
- **YouTube Music**
- **Mastodon**
- **Pinterest**
- **ThisVid**
- **YouTube downloader (standalone app)**
- Redesigned standalone downloader and update environment
- Added icons to download progress
- Added icons to saved posts downloader
- **Cookies**: new ways to add cookies. You can now export cookies using the browser extension and then import them into SCrawler!
- User creation: ability to extract the user's URL from the buffer and apply parameters if found
- User creation: simplified way to create new users (`Ctrl+Insert` to create a new user with default parameters from clipboard URL)
- Ability to customize the placement of ffmpeg (and other) files
- Ability to customize the command line encoding
- New notification options for standalone downloader
- Reddit: now it can download saved crossposts
- RedGifs: added `UserAgent` option
- Other improvements
- Removed
- User creation: remove the 'Channel' checkbox because it confuses people
- Removed an ability to open SCrawler with `-v` argument
- All ways to create users except URL. You can only properly create a user using the user's URL.
- Plugins
- Added `IDownloadableMedia` interface
- Removed `Channel` option from all functions and enums
- ISiteSettings: added `GetSingleMediaInstance` function
- IPluginContentProvider: added `DownloadSingleObject` function
- IPluginContentProvider: added tokens to `GetMedia` and `Download` functions
- IPluginContentProvider: removed `GetSpecialData` function
- UserMediaTypes: added `Audio` and `AudioPre` enums
- Fixed
- LPSG: attachments not downloading (Issue #114)
- Twitter: saved posts not downloading (Issue #119)
- XVIDEOS: saved posts not downloading
- Deleting labels file
- PornHub: hide unnecessary errors (Issue #116)
- PornHub: photo galleries bug (Issue #115)
- Minor bugs
# 2023.3.5.0
*2023-03-05*
- Fixed
- A bug in the new way of naming `SavedPosts` data files.
- An error that could occur during Twitter MD5 comparison.
- A bug in the ffmpeg file parts concatenation algorithm that could occur in some cases.
# 2023.3.1.0
*2023-03-01*
- Added
- **Path plugin.** Now you can add paths. *This may be suitable if you want to add a collection of media data to a specific user collection.*
- MainWindow: setting a background image
- MainWindow: setting background color and font color
- Feed: setting background color and font color
- Feed: (Request #108) center the image in the feed grid
- Users: the ability to use user site name (if it exists) as a friendly name (on supported sites: Reddit, Twitter, Instagram)
- Users: the ability to update user site name every time
- Twitter: ability to download images using MD5 comparison to protect against duplicate downloads *(this may be suitable for the users who post the same image many times)*
- Twitter: one-time duplicate image removal option
- XHamster: (Request #107) added channels downloading
- Updated
- Updated ffmpeg to version [5.1.2](https://github.com/GyanD/codexffmpeg/releases/tag/5.1.2)
- Fixed
- PornHub: (Issue #106) unicode titles
- (Issue #106) problem with non-Latin characters
- ffmpeg: maximum input length error when merging parts of files
# 2023.2.5.0
*2023-02-05*
- Added
- The ability to configure UserAgent
- Fixed
- (Issue #101) Failed download Gfycat video in some cases
# 2023.1.27.0
*2023-01-27*
- Added
- Advanced Twitter options for GIFs
- Changing the icon of the user creation form based on the selected site
- Fixed
- Pinned Instagram posts reload every time
- Plugins
- Added
- `Interaction` option to the `Provider` attribute
- `IPropertyProvider` interface
# 2023.1.24.1
*2023-01-24*

21
FAQ.md
View File

@@ -14,11 +14,7 @@ Any other questions I will keep in this file.
A: https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-set-up-cookies
----
#### Q: **I can't copy cookies.**
A: Use the mouse. Don't use ```Ctrl+A```!
<!---**ATTENTION! If you need to use cookies but cannot import them, I highly recommend that you don't use SCrawler and use another program. Don't create issues, discussions, or write to me on Discord. Any issue or discussion about cookies will be deleted immediately without a response. Any user who asks me about cookies on Discord will be banned.**--->
----
@@ -30,21 +26,22 @@ A: This is a GUI program.
#### Q: **Will CLI be added in the future?**
A: I do not think so.
A: NO.
----
#### Q: **I want to add "...." site. How to request.**
A: How to request a new site you can read [here](CONTRIBUTING.md#how-to-request-a-new-site)
<!---A: How to request a new site you can read [here](CONTRIBUTING.md#how-to-request-a-new-site)--->
**I'm currently not accepting requests to develop new sites.**
----
#### Q: **Twitter/Instagram download failed.**
#### Q: **Site download failed.**
A: Check your credentials. Both of these sites require cookies. Check your [Twitter tokens](https://github.com/AAndyProgram/SCrawler/wiki/Settings#how-to-find-twitter-tokens) and [Instagram settings](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram). If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
A: Check your credentials and **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**. If all settings are set, but nothing works, go to [create a new issue](https://github.com/AAndyProgram/SCrawler/issues). Don't forget to attach the LOG.
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
**ATTENTION! Issues without URLs will be closed without a response!**
----
@@ -80,7 +77,7 @@ A: The program stored posts IDs in users' folders. For the first time, the progr
#### Q: **How to redownload all data**
A: Double-click on the user you want to redownload. In the opened window open folder setting. Delete the files ending with ```_Data.xml``` and ```_Posts.txt```. Download this user again.
A: Double-click on the user you want to redownload. In the opened window open folder setting. Delete the files ending with ```_Data.xml``` and ```_Posts.txt```. Restart SCrawler. Download this user again.
----
@@ -116,4 +113,4 @@ A: I can only [suggest](#q-you-lost-me-your-program-is-too-complicated) you find
#### Q: **Can you add a step-by-step guide or video on how to use the program?**
A: **NO**! I will not do it. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.
A: **NO! NEVER!** The guide fully covers all the functionality of SCrawler! If you don't respect my work, I don't waste my time. If you want, you can create a video tutorial and send it to me. Then I add it. All options and what each option does described on the wiki. The wiki also contains a description of all settings and how-to configure them. For complex settings, there is a steep-by-steep guide. Read the [main](README.md) information and [GUIDE](https://github.com/AAndyProgram/SCrawler/wiki/) and you won't have any problems. I have developed a program with an intuitive interface. There is a Settings button, download buttons, a context menu that drops down when a user is clicked, and other controls. Anyone can use it.

View File

@@ -2,7 +2,6 @@ Your support is very valuable to me. Any support is greatly appreciated. Your su
You can support the program by:
- **Bitcoin**: BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
- :heavy_dollar_sign: make a donation on this site: https://ko-fi.com/andyprogram
- :repeat: make a post about my program on your profile (Reddit, Twitter, Instagram and any other social networks)
- :speech_balloon: tell your friends about the program
- :heart: like the program on this site: https://alternativeto.net/software/scrawler/about/
@@ -10,3 +9,4 @@ You can support the program by:
- suggest my program as an alternative ([on this site](https://alternativeto.net/software/scrawler/about/)) to any program you have used before
I would be very grateful for any support! :blush:
<!---:heavy_dollar_sign: make a donation on this site: https://ko-fi.com/andyprogram--->

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,6 +1,55 @@
# yt-dlp
https://github.com/yt-dlp/yt-dlp/
**Great powerful CLI tool that supports hundreds of sites.**
SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare.
# 4K Video Downloader
https://www.4kdownload.com/-plbrz/video-downloader
| Option | SCrawler | 4K Stogram |
| ---- | ---- | ---- |
| User managament | **Advanced** | No |
| Automatic downloads | **Yes** | No |
| Downloading groups | **Yes** | No |
| Labeling users | **Yes** | No |
| Filtering | **Yes** | No |
| Collections | **Yes** | No |
| Specific user folders | **Yes** | No |
| Favorite / Temporary user options | **Yes** | No |
| Plugins support | **Yes** | No |
| Download single video | **Unlimited** | 30 videos per day *(unlimited starts from 12 EUR)* |
| Download videos per channel | **Unlimited** | 5 free *(unlimited starts from 12 EUR)* |
| Download videos per playlist | **Unlimited** | 10 free *(unlimited starts from 12 EUR)* |
| Download video subtitles | **Any for free**: single video, playlist, user/channel, album, etc| Free for single video |
| The number of subtitles you can download for a video | **All of them** | Up to 10 |
| Convert subtitles to additional formats | **Yes** | No |
| Support LRC format | **Yes** | No |
| Select audio codec for audio/video | **Yes** | No |
| Extract and convert additional audio tracks for video | **Yes** | No |
| Simultaneous downloads | **Unlimited** | 1 free, 3 for 12 EUR, 7 for 43 EUR|
| Private YouTube content download | **Free** | Only in paid plans *starts from 12 EUR* |
| **Paid** | **No** | Yes |
| **Free options** | **The program is completely free** | Only **30** videos per day, 5 from a channel, 10 from a playlist |
| Permitted Commercial Use | **Yes** | Starting from 43 EUR |
| Automatic Subscriptions Update | **Free** | Paid (43 EUR) |
| Posts and Captions Export | No | Paid (43 EUR) |
| Advertisements free | **No ADs at all for free** | Paid (43 EUR) |
| Operating Systems | Windows 10+ | Windows 7+, MacOS 10.13+, Ubuntu x64 |
| Select want content type to download | **Yes** | No |
| Instagram support | **Yes** | No |
| Twitter support | **Yes** | No |
| Reddit support | **Yes** | No |
| Other sites support | **Yes** | No |
| Still supported | Yes | Yes |
# 4K Stogram
https://www.4kdownload.com/products/product-stogram
<!---https://www.4kdownload.com/products/product-stogram--->
https://www.4kdownload.com/-ad0p9/stogram
| Option | SCrawler | 4K Stogram |
| ---- | ---- | ---- |
@@ -27,10 +76,10 @@ https://www.4kdownload.com/products/product-stogram
| Export and import subscriptions | No | **Yes** |
| **Paid** | **No** | Yes |
| **Free options** | **The program is completely free** | Only **ONE** profile downloading and only **200 posts** per day |
| Permitted Commercial Use | **Yes** | Starting from 43.56 EUR |
| Automatic Subscriptions Update | **Free** | Paid (43.56 EUR) |
| Posts and Captions Export | No | Paid (43.56 EUR) |
| Advertisements free | **No ADs at all for free** | Paid (14.52) |
| Permitted Commercial Use | **Yes** | Starting from 43 EUR |
| Automatic Subscriptions Update | **Free** | Paid (43 EUR) |
| Posts and Captions Export | No | Paid (43 EUR) |
| Advertisements free | **No ADs at all for free** | Paid (18 EUR) |
| Operating Systems | Windows 10+ | Windows 7+, MacOS 10.13+, Ubuntu x64 |
| Select want content type to download | **Yes** | No |
| Instagram support | Yes | Yes |
@@ -68,7 +117,7 @@ https://github.com/RipMeApp/ripme
| **Free options** | The program is completely free | The program is completely free, but site limits are not declared |
| Operating Systems | Windows 10+ | Windows, MacOS, Linux |
| Select want content type to download | Yes | Yes |
| Suported sites | 9 internal and any site using plugins | 86+ sites (declared) |
| Suported sites | 15 internal and any site using plugins | 86+ sites (declared) |
| Other sites support | **Yes** | No |
| Still supported | **Yes** | **No (last release date May 4, 2021)** |
@@ -76,7 +125,6 @@ https://github.com/RipMeApp/ripme
https://github.com/mikf/gallery-dl
**CLI tool**! Configured with JSON files only. Users need to learn complex configuration options, JSON, commands to use that tool. Very difficult to configure.
**CLI tool**
SCrawler has advanced user management, collections, labels, groups, automatic downloads, a beautiful view, GUI, the ability to add plugins for other sites and much more. Just try it and compare.

View File

@@ -1,3 +1,5 @@
# :rainbow_flag: Happy LGBT Pride Month :tada:
# :rainbow_flag: Social networks crawler :rainbow_flag:
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/AAndyProgram/SCrawler)](https://github.com/AAndyProgram/SCrawler/releases/latest)
@@ -6,32 +8,39 @@
[![FAQ](https://img.shields.io/badge/FAQ-green)](FAQ.md)
[![GUIDE](https://img.shields.io/badge/GUIDE-green)](https://github.com/AAndyProgram/SCrawler/wiki)
[![How to support](https://img.shields.io/badge/HowToSupport-green)](HowToSupport.md)
:eu:
:greece:
A program to download photo and video from [any site](#supported-sites) (e.g. Reddit, Twitter, Instagram, TikTok, RedGifs, PornHub, XHamster, XVIDEOS, LPSG).
**If you like SCrawler, please like the program on [this site]( https://alternativeto.net/software/scrawler/about/)**
Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/andyprogram)
A program to download photo and video from [any site](#supported-sites) (e.g. YouTube, YouTube Music, Reddit, Twitter, Mastodon, Instagram, TikTok, RedGifs, PornHub, XHamster, XVIDEOS, ThisVid, LPSG, Pinterest).
**If you like SCrawler, please like the program on [this site](https://alternativeto.net/software/scrawler/about/) and/or [this](https://www.softpedia.com/get/Internet/Download-Managers/Social-networks-crawler.shtml)**
<!---Do you like this program? Consider adding to my coffee fund by making a donation to show your support. :blush:
[![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/andyprogram)--->
**Bitcoin**: BC1Q0NH839FT5TA44DD7L7RLR97XDQAG9V8D6N7XET
![Main window](ProgramScreenshots/MainWindow.png)
![Channels window](ProgramScreenshots/Channels.png)
[**YouTube standalone application:**](https://github.com/AAndyProgram/SCrawler/wiki/YouTube-downloader)
![YouTube application](ProgramScreenshots/AppYouTube.png)
# What can program do:
- Download pictures and videos from users' profiles and subreddits:
- Reddit images, galleries of images, videos (downloading Reddit hosted video is going through ffmpeg (**ffmpeg only works with the x64 program**)), saved posts;
- YouTube videos, shorts, users, artists, playlists, music, tracks;
- Reddit images, galleries of images, videos, saved posts;
- Redgifs videos (https://www.redgifs.com/);
- Twitter images and videos, saved (bookmarked) posts;
- Mastodon images and videos, saved (bookmarked) posts;
- Instagram images and videos, tagged posts, stories, saved posts;
- TikTok videos ([limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits));
- TikTok videos (*currently broken*; [limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits));
- Pinterest boards, users, saved posts;
- Imgur images, galleries and videos;
- Gfycat videos;
- PornHub images, videos, save (liked) posts;
- XHamster images, videos, saved posts;
- XVIDEOS videos;
- XVIDEOS videos, saved posts;
- ThisVid images, videos, saved posts;
- [Other](#supported-sites) supported sites
- Parse [channel and view data](https://github.com/AAndyProgram/SCrawler/wiki/Channels)
- Download [saved Reddit, Twitter and Instagram posts](https://github.com/AAndyProgram/SCrawler/wiki/Home#saved-posts)
@@ -52,18 +61,22 @@ Do you like this program? Consider adding to my coffee fund by making a donation
- ...and many others...
# Supported sites
- **YouTube**
- **YouTube Music**
- **Reddit**
- **Twitter**
- **Mastodon**
- **Instagram**
- **TikTok** ([limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits))
- TikTok (*currently broken*; [limited](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok-limits))
- RedGifs
- Pinterest
- Imgur
- Gfycat
- LPSG
- **PornHub**
- **XHamster**
- **XVIDEOS**
- **ThisVid**
- [Other sites](Plugins.md)
**[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
@@ -82,7 +95,8 @@ The program parses user posts and compares file names with existing ones to remo
## How to request a new site
Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
<!---Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about--->
**I'm currently not accepting requests to develop new sites.**
# Requirements
@@ -108,12 +122,16 @@ Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
- **[SITES REQUIREMENTS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#sites-requirements)**
- [Reddit](https://github.com/AAndyProgram/SCrawler/wiki/Settings#reddit)
- [Twitter](https://github.com/AAndyProgram/SCrawler/wiki/Settings#twitter)
- [Mastodon](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Mastodon)
- [Instagram](https://github.com/AAndyProgram/SCrawler/wiki/Settings#instagram)
- [TikTok](https://github.com/AAndyProgram/SCrawler/wiki/Settings#tiktok)
- [RedGifs](https://github.com/AAndyProgram/SCrawler/wiki/Settings#redgifs)
- [YouTube](https://github.com/AAndyProgram/SCrawler/wiki/Settings#YouTube)
- [Pinterest](https://github.com/AAndyProgram/SCrawler/wiki/Settings#Pinterest)
- [PornHub](https://github.com/AAndyProgram/SCrawler/wiki/Settings#pornhub)
- [XHamster](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xhamster)
- [XVIDEOS](https://github.com/AAndyProgram/SCrawler/wiki/Settings#xvideos)
- [ThisVid](https://github.com/AAndyProgram/SCrawler/wiki/Settings#ThisVid)
- [LPSG](https://github.com/AAndyProgram/SCrawler/wiki/Settings#lpsg)
**Full guide you can find [here](https://github.com/AAndyProgram/SCrawler/wiki)**
@@ -128,17 +146,11 @@ Read [here](CONTRIBUTING.md#how-to-request-a-new-site) about
Just download [latest](https://github.com/AAndyProgram/SCrawler/releases/latest) version and unpack it into the program folder. **Before starting a new version, I recommend making a backup copy of the program settings folder.**
# How to build from source
# [How to build from source](CONTRIBUTING.md#how-to-build-from-source)
Read about how to build from source [here](CONTRIBUTING.md#how-to-build-from-source)
# [How to make a plugin](https://github.com/AAndyProgram/SCrawler/wiki/Plugins)
# How to make a plugin
Read about how to make plugin [here](https://github.com/AAndyProgram/SCrawler/wiki/Plugins).
# How to support
Read about how to support the program [here](HowToSupport.md).
# [How to support](HowToSupport.md)
# Settings and usage
@@ -148,14 +160,34 @@ The program has an intuitive interface.
Just add a user profile and **click the ```Download``` button**.
Read more about adding users and subreddits [here](https://github.com/AAndyProgram/SCrawler/wiki/Users)
```mermaid
stateDiagram
Start: Add site credentials
What: What would I like to do
DownUser: Download user
DownVideo: Download video
AUser: Add user (1)
OVIF: Open standalone downloader (2)
AVideo: Add video url
F5: Press 'F5' or click the download button
[*]-->Start
Start-->What
What-->DownUser
What-->DownVideo
DownUser-->AUser
DownVideo-->OVIF
OVIF-->AVideo
AVideo-->F5
AUser-->F5
F5-->[*]
```
1. Press `Insert` or click the `Download` button ([read more here](https://github.com/AAndyProgram/SCrawler/wiki#users-list), [hot keys](https://github.com/AAndyProgram/SCrawler/wiki#hot-keys))
2. Click the `Download` button, then `Standalone downloader` ([read more here](https://github.com/AAndyProgram/SCrawler/wiki#download-separate-video))
![Add user](ProgramScreenshots/CreateUserClear.png)
# Using program as just video downloader
# Contact me
Create a shortcut for the program. Open shortcut properties. In the ```Shortcut``` tab, in the ```Target``` field, just add the letter ```v``` at the end across the space.
Matrix (Element): https://matrix.to/#/@andyprogram:matrix.org
Example: ```D:\Programs\SCrawler\SCrawler.exe v```
![Separate video downloader](ProgramScreenshots/SeparateVideoDownloader.png)
Discord: AndyProgram#3804

View File

@@ -100,6 +100,8 @@ Namespace Plugin.Attributes
''' <see langword="False"/> - only for conversion
''' </summary>
Public FieldsChecker As Boolean = False
''' <summary>Interaction with changing text field. Default: <see langword="False"/></summary>
Public Interaction As Boolean = False
''' <summary>Initialize a new Provider attribute. <see cref="IFormatProvider"/> is only allowed</summary>
''' <param name="PropertyName">The name of the property for which this provider is used</param>
Public Sub New(ByVal PropertyName As String)

View File

@@ -0,0 +1,34 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace Plugin
Public Interface IDownloadableMedia : Inherits IUserMedia, IDisposable
Event CheckedChange As EventHandler
Event ThumbnailChanged As EventHandler
Event StateChanged As EventHandler
ReadOnly Property SiteIcon As Drawing.Image
ReadOnly Property Site As String
ReadOnly Property SiteKey As String
Property ThumbnailUrl As String
Property ThumbnailFile As String
Property Title As String
Property Size As Integer
Property Duration As TimeSpan
Property Progress As Object
ReadOnly Property HasError As Boolean
ReadOnly Property Exists As Boolean
Property Checked As Boolean
Property Instance As IPluginContentProvider
Sub Download(ByVal UseCookies As Boolean, ByVal Token As Threading.CancellationToken)
Sub Delete(ByVal RemoveFiles As Boolean)
Sub Load(ByVal File As String)
Sub Save()
Overloads Function ToString() As String
Overloads Function ToString(ByVal ForMediaItem As Boolean) As String
End Interface
End Namespace

View File

@@ -8,8 +8,10 @@
' but WITHOUT ANY WARRANTY
Namespace Plugin
Public Interface IPluginContentProvider : Inherits IDisposable
Event ProgressChanged(ByVal Count As Integer)
Event TotalCountChanged(ByVal Count As Integer)
Event ProgressChanged(ByVal Value As Integer)
Event ProgressMaximumChanged(ByVal Value As Integer, ByVal Add As Boolean)
Event ProgressPreChanged As ProgressChangedEventHandler
Event ProgressPreMaximumChanged As ProgressMaximumChangedEventHandler
Property Thrower As IThrower
Property LogProvider As ILogProvider
Property Settings As ISiteSettings
@@ -32,7 +34,8 @@ Namespace Plugin
Sub ExchangeOptionsSet(ByVal Obj As Object)
Sub XmlFieldsSet(ByVal Fields As List(Of KeyValuePair(Of String, String)))
Function XmlFieldsGet() As List(Of KeyValuePair(Of String, String))
Sub GetMedia()
Sub Download()
Sub GetMedia(ByVal Token As Threading.CancellationToken)
Sub Download(ByVal Token As Threading.CancellationToken)
Sub DownloadSingleObject(ByVal Data As IDownloadableMedia, ByVal Token As Threading.CancellationToken)
End Interface
End Namespace

View File

@@ -12,17 +12,17 @@ Namespace Plugin
Enum Download As Integer
Main = 0
SavedPosts = 1
Channel = 2
SingleObject = 2
End Enum
ReadOnly Property Icon As Icon
ReadOnly Property Image As Image
ReadOnly Property Site As String
Property Logger As ILogProvider
Function GetUserUrl(ByVal User As IPluginContentProvider, ByVal Channel As Boolean) As String
Function GetUserUrl(ByVal User As IPluginContentProvider) As String
Function IsMyUser(ByVal UserURL As String) As ExchangeOptions
Function IsMyImageVideo(ByVal URL As String) As ExchangeOptions
Function GetSpecialData(ByVal URL As String, ByVal Path As String, ByVal AskForPath As Boolean) As IEnumerable
Function GetInstance(ByVal What As Download) As IPluginContentProvider
Function GetSingleMediaInstance(ByVal URL As String, ByVal OutputFile As String) As IDownloadableMedia
Function GetUserPostUrl(ByVal User As IPluginContentProvider, ByVal Media As IUserMedia) As String
#Region "XML Support"
Sub Load(ByVal XMLValues As IEnumerable(Of KeyValuePair(Of String, String)))

View File

@@ -32,6 +32,6 @@ Imports System.Runtime.InteropServices
' by using the '*' as shown below:
' <Assembly: AssemblyVersion("1.0.*")>
<Assembly: AssemblyVersion("2022.12.26.0")>
<Assembly: AssemblyFileVersion("2022.12.26.0")>
<Assembly: AssemblyVersion("2023.5.12.0")>
<Assembly: AssemblyFileVersion("2023.5.12.0")>
<Assembly: NeutralResourcesLanguage("en")>

View File

@@ -0,0 +1,13 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace Plugin
Public Interface IPropertyProvider : Inherits IFormatProvider
Property PropertyName As String
End Interface
End Namespace

View File

@@ -11,15 +11,11 @@ Namespace Plugin
Public UserName As String
Public SiteName As String
Public HostKey As String
Public IsChannel As Boolean
Public Exists As Boolean
Public Sub New(ByVal Site As String, ByVal Name As String)
UserName = Name
SiteName = Site
End Sub
Public Sub New(ByVal Site As String, ByVal Name As String, ByVal IsChannel As Boolean)
Me.New(Site, Name)
Me.IsChannel = IsChannel
Exists = Not String.IsNullOrEmpty(Name) And Not String.IsNullOrWhiteSpace(Name)
End Sub
End Structure
End Namespace

View File

@@ -7,12 +7,15 @@
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace Plugin
Public Delegate Sub ProgressChange(ByVal Value As Double?, ByVal Maximum As Double?, ByVal Information As String)
Public Enum UserMediaTypes As Integer
Undefined = 0
[Picture] = 1
[Video] = 2
[Text] = 3
Picture = 1
Video = 2
Audio = 200
Text = 4
VideoPre = 10
AudioPre = 215
GIF = 50
m3u8 = 100
End Enum
@@ -24,12 +27,12 @@ Namespace Plugin
Missing = 4
End Enum
Public Structure PluginUserMedia : Implements IUserMedia
Public Property ContentType As Integer Implements IUserMedia.ContentType
Public Property ContentType As UserMediaTypes Implements IUserMedia.ContentType
Public Property URL As String Implements IUserMedia.URL
Public Property URL_BASE As String Implements IUserMedia.URL_BASE
Public Property MD5 As String Implements IUserMedia.MD5
Public Property File As String Implements IUserMedia.File
Public Property DownloadState As Integer Implements IUserMedia.DownloadState
Public Property DownloadState As UserMediaStates Implements IUserMedia.DownloadState
Public Property PostID As String Implements IUserMedia.PostID
Public Property PostDate As Date? Implements IUserMedia.PostDate
Public Property SpecialFolder As String Implements IUserMedia.SpecialFolder
@@ -37,12 +40,12 @@ Namespace Plugin
Public Property [Object] As Object Implements IUserMedia.Object
End Structure
Public Interface IUserMedia
Property ContentType As Integer
Property ContentType As UserMediaTypes
Property URL As String
Property URL_BASE As String
Property MD5 As String
Property File As String
Property DownloadState As Integer
Property DownloadState As UserMediaStates
Property PostID As String
Property PostDate As Date?
Property SpecialFolder As String

View File

@@ -102,6 +102,8 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Attributes\Attributes.vb" />
<Compile Include="Interfaces\IDownloadableMedia.vb" />
<Compile Include="ObjectInterfaces\IPropertyProvider.vb" />
<Compile Include="Objects\ExchangeOptions.vb" />
<Compile Include="ObjectInterfaces\ILogProvider.vb" />
<Compile Include="Interfaces\IPluginContentProvider.vb" />

View File

@@ -0,0 +1,3 @@
[*.vb]
# Modifier preferences
file_header_template = Copyright (C) 2023 Andy https://github.com/AAndyProgram\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program. If not, see <https://www.gnu.org/licenses/>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

View File

@@ -0,0 +1,30 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Attributes
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class GridVisibleAttribute : Inherits Attribute
Private ReadOnly NonAppMode As Boolean = True
Public Sub New()
End Sub
Public Sub New(ByVal NonAppMode As Boolean)
Me.NonAppMode = NonAppMode
End Sub
Public Overrides Function Equals(ByVal Obj As Object) As Boolean
If Not Obj Is Nothing AndAlso TypeOf Obj Is GridVisibleAttribute Then
If NonAppMode Then
Return DirectCast(Obj, GridVisibleAttribute).NonAppMode
Else
Return True
End If
Else
Return False
End If
End Function
End Class
End Namespace

View File

@@ -0,0 +1,81 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Base
Public Structure Thumbnail : Implements IIndexable, IComparable(Of Thumbnail)
Public ID As String
Public Width As Integer
Public Height As Integer
Public URL As String
Public Property Index As Integer Implements IIndexable.Index
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
Dim t As Thumbnail = Obj
t.Index = Index
Return t
End Function
Private Function CompareTo(ByVal Other As Thumbnail) As Integer Implements IComparable(Of Thumbnail).CompareTo
Return Width.CompareTo(Other.Width) * -1
End Function
End Structure
Public Structure Subtitles : Implements IIndexable, IComparable(Of Subtitles)
Public ID As String
Public Name As String
Public Formats As String
Public ReadOnly Property FullID As String
Get
Return IIf(ID = "en", "en.*", ID)
End Get
End Property
Public Property Index As Integer Implements IIndexable.Index
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
Dim s As Subtitles = Obj
s.Index = Index
Return s
End Function
Private Function CompareTo(ByVal Other As Subtitles) As Integer Implements IComparable(Of Subtitles).CompareTo
Return Name.CompareTo(Other.Name)
End Function
End Structure
Public Enum YouTubeMediaType As Integer
Undefined = 0
[Single] = 1
Channel = 2
PlayList = 3
End Enum
Public Structure MediaObject : Implements IIndexable, IComparable(Of MediaObject)
Public Type As Plugin.UserMediaTypes
Public ID As String
Public Extension As String
Public Width As Integer
Public Height As Integer
Public FPS As Integer
Public Bitrate As Integer
''' <summary>Kb</summary>
Public Size As Double
Public Codec As String
Public Info As String
Public URL As String
Public Property Index As Integer Implements IIndexable.Index
Private Function SetIndex(ByVal Obj As Object, ByVal Index As Integer) As Object Implements IIndexable.SetIndex
Dim m As MediaObject = Obj
m.Index = Index
Return m
End Function
Private Function CompareTo(ByVal Other As MediaObject) As Integer Implements IComparable(Of MediaObject).CompareTo
If Type = Other.Type Then
If Width.CompareTo(Other.Width) = 0 Then
Return Size.CompareTo(Other.Size) * -1
Else
Return Width.CompareTo(Other.Width) * -1
End If
Else
Return CInt(Type).CompareTo(CInt(Other.Type))
End If
End Function
End Structure
End Namespace

View File

@@ -0,0 +1,38 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Controls
Friend Class TableControlsProcessor
Private ReadOnly Property TP_CONTROLS As TableLayoutPanel
Friend Sub New(ByRef TP As TableLayoutPanel)
TP_CONTROLS = TP
End Sub
Private _LatestSelected As Integer = -1
Friend Sub MediaItem_Click(ByVal Sender As Object, ByVal e As EventArgs)
Try
_LatestSelected = TP_CONTROLS.GetPositionFromControl(Sender).Row
DirectCast(Sender, Control).Focus()
Catch ex As Exception
_LatestSelected = -1
End Try
End Sub
Friend Sub MediaItem_KeyDown(ByVal Sender As Object, ByVal e As KeyEventArgs)
Try
If e.KeyCode = Keys.Down Or e.KeyCode = Keys.Up Then
Dim newPosition% = _LatestSelected + IIf(e.KeyCode = Keys.Down, 1, -1)
If newPosition < 0 Then newPosition = 0
If newPosition <> _LatestSelected Then
Dim cnt As DownloadObjects.STDownloader.MediaItem = TP_CONTROLS.GetControlFromPosition(0, newPosition)
If Not cnt Is Nothing Then cnt.PerformClick()
End If
End If
Catch
End Try
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,165 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.RegularExpressions
Imports SCrawler.API.YouTube.Objects
Namespace API.YouTube.Base
Public NotInheritable Class YouTubeFunctions
Public Const YouTubeCachePathRoot As String = "_CacheYouTube\"
Public Const UserChannelOption As String = "channel"
Public Const TrueUrlPattern As String = "https?://[^/]*?youtube.com/[^\?/&]+((\??[^\?/&]+|/[^\?/&]+))"
'2 - type; 5 - id
Public Const UrlTypePattern As String = "(?<=https?://[^/]*?youtube.com/)((@|[^\?/&]+))([/\?]{0,1}(list=|v=|)([^\?/&]*))(?=(\S+|\Z|))"
Private Sub New()
End Sub
Public Shared Function IsMyUrl(ByVal URL As String) As Boolean
Return Not Info_GetUrlType(URL) = YouTubeMediaType.Undefined
End Function
Public Shared Function Info_GetUrlType(ByVal URL As String, Optional ByRef IsMusic As Boolean = False,
Optional ByRef IsChannelUser As Boolean = False, Optional ByRef Id As String = Nothing) As YouTubeMediaType
If Not URL.IsEmptyString Then
IsMusic = URL.Contains("music.youtube.com")
IsChannelUser = False
Dim data As List(Of String) = RegexReplace(URL, RParams.DMS(UrlTypePattern, 0, RegexReturn.ListByMatch, EDP.ReturnValue))
If data.ListExists Then
If data.Count >= 6 Then Id = data(5)
If data.Count >= 3 And Not data(2).IsEmptyString Then
Select Case data(2).ToLower
Case "watch" : Return YouTubeMediaType.Single
Case "playlist" : Return YouTubeMediaType.PlayList
Case UserChannelOption, "@" : IsChannelUser = data(2).ToLower = UserChannelOption : Return YouTubeMediaType.Channel
End Select
End If
End If
End If
Return YouTubeMediaType.Undefined
End Function
''' <summary>'--no-cookies-from-browser --cookies CookiesFile'</summary>
Public Shared Function GetCookiesCommand(ByVal UseCookies As Boolean, ByVal CookiesFile As SFile) As String
If UseCookies And CookiesFile.Exists Then
Return $"--no-cookies-from-browser --cookies ""{CookiesFile}"""
Else
Return String.Empty
End If
End Function
''' <param name="DateAfter">Data with upload date 'more than or equal to' date will be downloaded</param>
''' <param name="DateBefore">Data with upload date 'less than or equal to' date will be downloaded</param>
''' <exception cref="ArgumentNullException"></exception>
''' <exception cref="IO.FileNotFoundException"></exception>
''' <exception cref="InvalidOperationException"></exception>
Public Shared Function Parse(ByVal URL As String, Optional ByVal UseCookies As Boolean? = Nothing,
Optional ByVal Token As Threading.CancellationToken = Nothing, Optional ByVal Progress As IMyProgress = Nothing,
Optional ByVal GetDefault As Boolean? = Nothing, Optional ByVal GetShorts As Boolean? = Nothing,
Optional ByVal DateAfter As Date? = Nothing, Optional ByVal DateBefore As Date? = Nothing) As IYouTubeMediaContainer
If URL.IsEmptyString Then Throw New ArgumentNullException("URL", "URL cannot be null")
If Not MyYouTubeSettings.YTDLP.Value.Exists Then Throw New IO.FileNotFoundException("Path to 'yt-dlp.exe' not set or program not found at destination", MyYouTubeSettings.YTDLP.Value.ToString)
Dim urlOrig$ = URL
URL = RegexReplace(URL, TrueUrlRegEx)
If URL.IsEmptyString Then Throw New ArgumentNullException("URL", $"Can't get true URL from [{urlOrig}]")
Dim isMusic As Boolean = False
Dim objType As YouTubeMediaType = Info_GetUrlType(URL, isMusic)
If Not objType = YouTubeMediaType.Undefined Then
Dim __GetDefault As Boolean = If(GetDefault, True)
Dim __GetShorts As Boolean = If(GetShorts, True)
If isMusic Then __GetShorts = False
Dim container As IYouTubeMediaContainer
Dim pattern$ = "%(channel_id)s_%(id)s_%(playlist_index)s"
Select Case objType
Case YouTubeMediaType.Single
__GetShorts = False
If isMusic Then container = New Track Else container = New Video
Case YouTubeMediaType.PlayList : container = New PlayList : pattern = "%(playlist_index)s_%(id)s" : __GetShorts = False
Case YouTubeMediaType.Channel
container = New Channel
If isMusic Then pattern = "%(playlist_id)s/%(channel_id)s_%(id)s_%(playlist_index)s"
Case Else : Throw New InvalidOperationException($"Type '{objType}' is not supported by YouTubeDownloader")
End Select
If UseCookies.HasValue Then container.UseCookies = UseCookies.Value
Dim result As Boolean = False
Dim cookiesExists As Boolean = YouTubeCookieNetscapeFile.Exists
Dim _CachePathDefault As SFile = MyCache.NewPath(, EDP.ReturnValue)
If _CachePathDefault.IsEmptyString Then _CachePathDefault = $"{YouTubeCachePathRoot}{SFile.GetDirectories(YouTubeCachePathRoot,,, EDP.ReturnValue).Count + 1}"
_CachePathDefault.Exists(SFO.Path, True, EDP.ThrowException)
pattern = $"{_CachePathDefault.PathWithSeparator}{pattern}"
Dim withCookieRequested As Boolean = False
Dim useCookiesForce As Boolean = UseCookies.HasValue AndAlso UseCookies.Value AndAlso cookiesExists
If UseCookies.HasValue AndAlso UseCookies.Value Then
withCookieRequested = True
result = Parse_Internal(URL, pattern, _CachePathDefault, True, YouTubeCookieNetscapeFile, DateAfter, DateBefore, __GetDefault, __GetShorts)
End If
If Not result And Not withCookieRequested Then
If Not UseCookies.HasValue OrElse Not UseCookies.Value Then result = Parse_Internal(URL, pattern, _CachePathDefault, False, YouTubeCookieNetscapeFile, DateAfter, DateBefore, __GetDefault, __GetShorts)
If Not result And Not UseCookies.HasValue And cookiesExists Then result = Parse_Internal(URL, pattern, _CachePathDefault, True, YouTubeCookieNetscapeFile, DateAfter, DateBefore, __GetDefault, __GetShorts)
End If
If result Then
container.Parse(Nothing, _CachePathDefault, isMusic, Token, Progress)
If Not container.HasError Then container.URL = URL : Return container
End If
container.Dispose()
End If
Return Nothing
End Function
Private Shared Function Parse_Internal(ByVal URL As String, ByVal OutputPattern As String, ByVal OutputPath As SFile,
ByVal UseCookies As Boolean, ByVal CookiesFile As SFile,
ByVal DateAfter As Date?, ByVal DateBefore As Date?,
ByVal GetDefault As Boolean, ByVal GetShorts As Boolean) As Boolean
Try
Dim command$ = "yt-dlp --write-info-json --skip-download"
command.StringAppend(GetCookiesCommand(UseCookies, CookiesFile), " ")
If DateAfter.HasValue Then command.StringAppend($"--dateafter {DateAfter.Value:yyyyMMdd}", " ")
If DateBefore.HasValue Then command.StringAppend($"--datebefore {DateBefore.Value:yyyyMMdd}", " ")
command.StringAppend("{0}" & $" -o ""{OutputPattern}""", " ")
#If DEBUG Then
Debug.WriteLine(String.Format(command, URL))
#End If
Using batch As New BatchExecutor(True)
With batch
.CommandPermanent = BatchExecutor.GetDirectoryCommand(MyYouTubeSettings.YTDLP.Value)
If GetDefault Then .Execute(String.Format(command, URL))
If GetShorts Then .Execute(String.Format(command, $"{URL.StringTrimEnd("/")}/shorts"))
End With
End Using
Return SFile.GetFiles(OutputPath,, IO.SearchOption.AllDirectories, EDP.ReturnValue).Count > 0
Catch ex As Exception
Return ErrorsDescriber.Execute(EDP.SendToLog + EDP.ReturnValue, ex,
$"[API.YouTube.Base.YouTubeFunctions.Parse_Internal({URL}, {UseCookies})]", False)
End Try
End Function
Friend Shared Function CreateContainer(ByVal f As SFile) As IYouTubeMediaContainer
Dim c As IYouTubeMediaContainer = Nothing
If f.Exists(SFO.File, False) Then
Using x As New XmlFile(f, Protector.Modes.All, False) With {.AllowSameNames = True, .XmlReadOnly = True}
x.LoadData()
If x.Value(YouTubeMediaContainerBase.Name_SiteKey) = YouTubeSiteKey Then
Select Case x.Value(YouTubeMediaContainerBase.Name_ObjectType).FromXML(Of Integer)(YouTubeMediaType.Undefined)
Case YouTubeMediaType.Channel : c = New Channel
Case YouTubeMediaType.PlayList : c = New PlayList
Case YouTubeMediaType.Single
If x.Value(YouTubeMediaContainerBase.Name_IsMusic).FromXML(Of Boolean)(False) Then
c = New Track
Else
c = New Video
End If
Case Else : Throw New ArgumentException($"Object type '{x.Value(YouTubeMediaContainerBase.Name_ObjectType)}' is not identified",
"ObjectType") With {.HelpLink = NameOf(CreateContainer)}
End Select
End If
End Using
If Not c Is Nothing Then c.Load(f)
End If
Return c
End Function
End Class
End Namespace

View File

@@ -0,0 +1,337 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.Globalization
Imports System.Drawing.Design
Imports System.ComponentModel
Imports SCrawler.API.YouTube.Attributes
Imports SCrawler.DownloadObjects.STDownloader
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.XML.Objects
Imports PersonalUtilities.Functions.XML.Attributes.Specialized
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Tools.Grid.Base
Imports PersonalUtilities.Tools.Grid.Attributes
Imports PersonalUtilities.Tools.Grid.Collections
Imports PersonalUtilities.Tools.Grid.Specialized
Imports PersonalUtilities.Tools.Web.Cookies
Namespace API.YouTube.Base
<TypeDescriptionProvider(GetType(FieldsTypeDescriptorProvider))>
Public Class YouTubeSettings : Implements IXMLValuesContainer, IGridValuesContainer, IDownloaderSettings
#Region "Events"
Private Event OnBeginUpdate As EventHandler Implements IXMLValuesContainer.OnBeginUpdate
Private Event OnEndUpdate As EventHandler Implements IXMLValuesContainer.OnEndUpdate
#End Region
#Region "Declarations"
<Browsable(False)> Private ReadOnly Property XML As XmlFile Implements IXMLValuesContainer.XML
<Browsable(False)> Friend ReadOnly Property DesignXml As XmlFile
<Browsable(False)> Private Property Mode As GridUpdateModes = GridUpdateModes.OnConfirm Implements IGridValuesContainer.Mode
<Browsable(False), XMLVV(-1)> Friend ReadOnly Property PlaylistFormSplitterDistance As XMLValue(Of Integer)
#Region "Environment"
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment"), DisplayName("Path to yt-dlp.exe"),
Description("Path to yt-dlp.exe file")>
Public ReadOnly Property YTDLP As XMLValue(Of SFile)
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment"), DisplayName("Path to ffmpeg.exe"),
Description("Path to ffmpeg.exe file")>
Public ReadOnly Property FFMPEG As XMLValue(Of SFile)
<Browsable(True), GridVisible(False), Category("Environment"), Description("YouTube cookies"), GridCollectionForm(GetType(CookieListForm2)),
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
Public ReadOnly Property Cookies As CookieKeeper
Private Function ShouldSerializeCookies() As Boolean
Return Cookies.Count > 0
End Function
Private Sub ResetCookies()
Cookies.Clear()
End Sub
Private Class CookieListForm2 : Inherits CookieListForm
Public Sub New()
ShowGrid = False
End Sub
End Class
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, Provider:=GetType(XMLToFilePathProvider)), Category("Environment"), DisplayName("Output path"),
Description("The default output path where files should be downloaded."),
Editor(GetType(GridSFileTypeEditorPath), GetType(UITypeEditor))>
Public ReadOnly Property OutputPath As XMLValue(Of SFile)
<Browsable(True), GridVisible(False), XMLVN({"Environment"}), Category("Environment"), DisplayName("Output path auto change"),
Description("Automatically change the output path when a new destination is selected in the opening forms.")>
Public ReadOnly Property OutputPathAutoChange As XMLValue(Of Boolean)
<Browsable(True), GridVisible(False), XMLVN({"Environment"}, DoubleClickBehavior.Folder), Category("Environment"), DisplayName("On item double click"),
Description("What should program open when you double-click on an item...")>
Public ReadOnly Property OnItemDoubleClick As XMLValue(Of DoubleClickBehavior)
Private ReadOnly Property IDownloaderSettings_OnItemDoubleClick As DoubleClickBehavior Implements IDownloaderSettings.OnItemDoubleClick
Get
Return OnItemDoubleClick
End Get
End Property
<Browsable(False), GridVisible(False), XMLVN({"Environment"}), Category("Environment"), DisplayName("Open folders in another program"),
Description("The command to open a folder.")>
Public ReadOnly Property OpenFolderInOtherProgram As XMLValueUse(Of String)
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program"), DefaultValue(False)>
Private Property IDownloaderSettings_OpenFolderInOtherProgram As Boolean Implements IDownloaderSettings.OpenFolderInOtherProgram
Get
Return OpenFolderInOtherProgram.Use
End Get
Set(ByVal use As Boolean)
OpenFolderInOtherProgram.Use = use
End Set
End Property
<Browsable(True), GridVisible(False), Category("EnvironmentFolder"), DisplayName("Open folders in another program (command)"),
Description("The command to open a folder."), DefaultValue("")>
Private Property IDownloaderSettings_OpenFolderInOtherProgram_Command As String Implements IDownloaderSettings.OpenFolderInOtherProgram_Command
Get
Return OpenFolderInOtherProgram
End Get
Set(ByVal command As String)
OpenFolderInOtherProgram.Value = command
End Set
End Property
#End Region
#Region "Defaults"
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Replace modification date"),
Description("Set the file date to the date the video was added (website) (if available). Default: false.")>
Public ReadOnly Property ReplaceModificationDate As XMLValue(Of Boolean)
<Browsable(True), GridVisible, XMLVN({"Defaults"}), Category("Defaults"), DisplayName("Use cookies"),
Description("By default, use cookies when downloading from YouTube.")>
Public ReadOnly Property DefaultUseCookies As XMLValue(Of Boolean)
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}), Category("Defaults"),
DisplayName("Auto remove"), Description("Automatically remove downloaded items from the list.")>
Public ReadOnly Property RemoveDownloadedAutomatically As XMLValue(Of Boolean)
Private ReadOnly Property IDownloaderSettings_RemoveDownloadedAutomatically As Boolean Implements IDownloaderSettings.RemoveDownloadedAutomatically
Get
Return RemoveDownloadedAutomatically
End Get
End Property
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Download Automatically"),
Description("Download automatically when a new item is added.")>
Public ReadOnly Property DownloadAutomatically As XMLValue(Of Boolean)
Private ReadOnly Property IDownloaderSettings_DownloadAutomatically As Boolean Implements IDownloaderSettings.DownloadAutomatically
Get
Return DownloadAutomatically
End Get
End Property
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, 1), Category("Defaults"), DisplayName("Max downloads"),
Description("Maximum active downloads.")>
Public ReadOnly Property MaxJobsCount As XMLValue(Of Integer)
Private ReadOnly Property IDownloaderSettings_MaxJobsCount As Integer Implements IDownloaderSettings.MaxJobsCount
Get
Return MaxJobsCount
End Get
End Property
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Show notifications"),
Description("Show a notification when the download is complete. The default value is true.")>
Public ReadOnly Property ShowNotifications As XMLValue(Of Boolean)
Private ReadOnly Property IDownloaderSettings_ShowNotifications As Boolean Implements IDownloaderSettings.ShowNotifications
Get
Return ShowNotifications
End Get
End Property
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, True), Category("Defaults"), DisplayName("Show notifications every time"),
Description("If true, notifications will be shown every time a file download is complete; " &
"otherwise, the notification will only be shown when all downloads are completed. " &
"Only works if 'Show notifications' is true." &
"The default value is true.")>
Public ReadOnly Property ShowNotificationsEveryDownload As XMLValue(Of Boolean)
Private ReadOnly Property IDownloaderSettings_ShowNotificationsEveryDownload As Boolean Implements IDownloaderSettings.ShowNotificationsEveryDownload
Get
Return ShowNotifications And ShowNotificationsEveryDownload
End Get
End Property
Private Sub ShowNotificationsEveryDownload_TempValueChanged(ByVal Sender As Object, ByVal e As EventArgs)
If ShowNotificationsEveryDownload.ValueTemp Then ShowNotifications.ValueTemp = True
End Sub
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, False), Category("Defaults"), DisplayName("Close to tray"),
Description("Close the program to tray.")>
Public ReadOnly Property CloseToTray As XMLValue(Of Boolean)
<Browsable(True), GridVisible(False), XMLVN({"Defaults"}, False), Category("Defaults"), DisplayName("Confirm exit"),
Description("Exit confirmation when closing the program.")>
Public ReadOnly Property ExitConfirm As XMLValue(Of Boolean)
#End Region
#Region "Defaults Video"
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, "MKV"), Category("Defaults Video"), DisplayName("Default format"),
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableVideoFormats_Impl)),
Description("The default video format for downloading videos.")>
Public ReadOnly Property DefaultVideoFormat As XMLValue(Of String)
Private Function AvailableVideoFormats_Impl() As String()
Return AvailableVideoFormats
End Function
<Browsable(True), GridVisible, XMLVN({"DefaultsVideo"}, 1080), Category("Defaults Video"), DisplayName("Default definition"),
Description("The default maximum video resolution. -1 for max definition")>
Public ReadOnly Property DefaultVideoDefinition As XMLValue(Of Integer)
#End Region
#Region "Defaults Audio"
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, "AAC"), Category("Defaults Audio"), DisplayName("Default codec"),
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableAudioFormats_Impl)),
Description("The default audio format for downloading videos.")>
Public ReadOnly Property DefaultAudioCodec As XMLValue(Of String)
Private Function AvailableAudioFormats_Impl() As String()
Return AvailableAudioFormats
End Function
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}, "MP3"), Category("Defaults Audio"), DisplayName("Default codec for music"),
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableAudioFormats_Impl)),
Description("The default audio format for downloading music.")>
Public ReadOnly Property DefaultAudioCodecMusic As XMLValue(Of String)
<Browsable(True), GridVisible, XMLVN({"DefaultsAudio"}), Category("Defaults Audio"), DisplayName("Additional codec"),
Bindable(True), Editor(GetType(ValueCollectionEditor), GetType(UITypeEditor)),
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
TypeConverter(GetType(ValueCollectionConverter)),
Description("Additional audio format for downloading videos. This means that the audio will be extracted and saved as a separate file in these formats.")>
Public ReadOnly Property DefaultAudioCodecAddit As XMLValuesCollection(Of String)
#End Region
#Region "Defaults Subtitles"
<XMLVN({"DefaultsSubtitles"}, {"en"}, CollectionMode:=IXMLValuesCollection.Modes.String)>
Public ReadOnly Property DefaultSubtitles As XMLValuesCollection(Of String)
<Browsable(True), GridVisible, Category("Defaults Subtitles"), DisplayName("Default subtitles"),
Description("The default subtitles that should be downloaded with the video. The comma is the separator.")>
Private Property DefaultSubtitles_Impl As String
Get
If DefaultSubtitles.ValueTemp.Count > 0 Then
Return DefaultSubtitles.ValueTemp.ListToString(",")
Else
Return String.Empty
End If
End Get
Set(ByVal s As String)
If s.IsEmptyString Then
DefaultSubtitles.ValueTemp = Nothing
Else
DefaultSubtitles.ValueTemp = ListAddList(Nothing, s.Split(","), LAP.NotContainsOnly,
CType(Function(Input$) Input.StringTrim, Func(Of Object, Object)))
End If
End Set
End Property
Private Function ShouldSerializeDefaultSubtitles_Impl() As Boolean
Return DirectCast(DefaultSubtitles, IGridValue).ShouldSerializeValue
End Function
Private Sub ResetDefaultSubtitles_Impl()
DirectCast(DefaultSubtitles, IGridValue).ResetValue()
End Sub
<Browsable(True), GridVisible, XMLVN({"DefaultsSubtitles"}, "SRT"), Category("Defaults Subtitles"), DisplayName("Default format"),
TypeConverter(GetType(FieldsTypeConverter)), GridStandardValuesProvider(NameOf(AvailableSubtitlesFormats_Impl)),
Description("The default format for downloading subtitles.")>
Public ReadOnly Property DefaultSubtitlesFormat As XMLValue(Of String)
Private Function AvailableSubtitlesFormats_Impl() As String()
Return AvailableSubtitlesFormats
End Function
<Browsable(True), GridVisible, XMLVN({"DefaultsSubtitles"}, CollectionMode:=IXMLValuesCollection.Modes.String),
Category("Defaults Subtitles"), DisplayName("Additional format"),
Bindable(True), Editor(GetType(ValueCollectionEditor), GetType(UITypeEditor)),
EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
TypeConverter(GetType(ValueCollectionConverter)),
Description("Additional format for downloading subtitles. This means that all subtitles will be converted to the formats you choose and saved as separate files.")>
Public ReadOnly Property DefaultSubtitlesFormatAddit As XMLValuesCollection(Of String)
#End Region
#End Region
#Region "Initializer"
Public Sub New()
XML = New XmlFile(YouTubeSettingsFile,, False) With {.AutoUpdateFile = True}
XML.LoadData(EDP.None)
DesignXml = New XmlFile("Settings\DesignDownloader.xml", Protector.Modes.All, False)
DesignXml.LoadData(EDP.None)
InitializeXMLValueProperties(Me)
AddHandler ShowNotificationsEveryDownload.TempValueChanged, AddressOf ShowNotificationsEveryDownload_TempValueChanged
Cookies = New CookieKeeper
Grid.Abstract.DesignerXmlSource.Add(New Grid.Abstract.DesignerXmlData(GetType(CookieListForm2), DesignXml, "CookiesListForm"))
If YouTubeCookieNetscapeFile.Exists Then Cookies.AddRange(CookieKeeper.ParseNetscapeText(YouTubeCookieNetscapeFile.GetText(EDP.ReturnValue), EDP.None),, EDP.None)
If Not YTDLP.Value.Exists Then YTDLP.Value = ProgramPath("yt-dlp.exe")
If Not FFMPEG.Value.Exists Then FFMPEG.Value = ProgramPath("ffmpeg.exe")
If Not OutputPath.Value.Exists(SFO.Path, False) Then OutputPath.Value = YouTubeDownloadPathDefault
If XML.ChangesDetected Then XML.UpdateData()
End Sub
Private Function ProgramPath(ByVal Program As String) As SFile
If Program.CSFile.Exists Then
Return Program.CSFile
ElseIf $"Environment\{Program}".CSFile.Exists Then
Return $"Environment\{Program}"
Else
Return SystemEnvironment.FindFileInPaths(Program).ListIfNothing.FirstOrDefault
End If
End Function
#End Region
#Region "Edit, Update"
Protected Overridable Sub BeginUpdate() Implements IXMLValuesContainer.BeginUpdate, IGridValuesContainer.BeginUpdate
XML.BeginUpdate()
End Sub
Protected Overridable Sub EndUpdate() Implements IXMLValuesContainer.EndUpdate, IGridValuesContainer.EndUpdate
XML.EndUpdate()
If XML.ChangesDetected Then XML.UpdateData()
End Sub
Protected Overridable Sub Apply() Implements IGridValuesContainer.Apply
XMLValuesApply(Me)
ApplyCookies()
End Sub
Protected Sub ApplyCookies()
If Cookies.Count > 0 Then Cookies.SaveNetscapeFile(YouTubeCookieNetscapeFile) Else YouTubeCookieNetscapeFile.Delete(,, EDP.None)
End Sub
Private Sub BeginEdit() Implements IGridValuesContainer.BeginEdit
XMLValuesBeginEdit(Me)
End Sub
Protected Overridable Sub EndEdit() Implements IGridValuesContainer.EndEdit
XMLValuesEndEdit(Me)
Cookies.Clear()
If YouTubeCookieNetscapeFile.Exists Then Cookies.AddRange(CookieKeeper.ParseNetscapeText(YouTubeCookieNetscapeFile.GetText(EDP.ReturnValue), EDP.None),, EDP.None)
End Sub
Public Sub ShowForm(ByVal AppMode As Boolean)
Using f As New SimpleGridForm(Me) With {
.GridShowToolbar = False,
.InitialOkValue = True,
.ShowIcon = True,
.Icon = My.Resources.SiteYouTube.YouTubeIcon_32,
.Text = "YouTube Settings",
.DesignXML = DesignXml,
.DesignXMLNodeName = "YouTubeSettingsForm"
}
f.GridBrowsableAttributes = New AttributeCollection(New BrowsableAttribute(True), New GridVisibleAttribute(Not AppMode))
f.ShowDialog()
End Using
End Sub
#End Region
#Region "Close"
Friend Sub Close()
DesignXml.Dispose()
XML.Dispose()
Cookies.Dispose()
End Sub
#End Region
#Region "Grid Support"
Private Class ValueCollectionConverter : Inherits TypeConverter
Public Overrides Function ConvertTo(ByVal Context As ITypeDescriptorContext, ByVal Culture As CultureInfo, ByVal Value As Object, ByVal DestinationType As Type) As Object
If TypeOf Value Is IEnumerable Then
Return DirectCast(Value, IEnumerable).ToObjectsList(Of String).ListToString
Else
Return String.Empty
End If
End Function
End Class
Private Class ValueCollectionEditor : Inherits GridStructureCollectionEditor
Public Overrides Function EditValue(ByVal Context As ITypeDescriptorContext, ByVal Provider As IServiceProvider, ByVal Value As Object) As Object
Dim eObj As IEnumerable(Of String) = Nothing
Select Case Context.PropertyDescriptor.Name
Case NameOf(DefaultSubtitlesFormatAddit) : eObj = AvailableSubtitlesFormats
Case NameOf(DefaultAudioCodecAddit) : eObj = AvailableAudioFormats
End Select
Using f As New SimpleListForm(Of String)(eObj) With {
.Mode = SimpleListFormModes.CheckedItems,
.DesignXML = MyYouTubeSettings.DesignXml,
.DesignXMLNodeName = "YouTubeSettingsFormList",
.FormText = DirectCast(Context.PropertyDescriptor.Attributes.Cast(Of Attribute).First(Function(a) a.GetType Is GetType(DisplayNameAttribute)), DisplayNameAttribute).DisplayName,
.Icon = My.Resources.SiteYouTube.YouTubeIcon_32
}
f.DataSelected.ListAddList(Value)
If f.ShowDialog() = DialogResult.OK Then
eObj = f.DataResult.ToList
With DirectCast(Value, List(Of String)) : .Clear() : .ListAddList(eObj) : End With
End If
End Using
Return Value
End Function
End Class
#End Region
End Class
End Namespace

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 569 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,469 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Controls
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class MusicPlaylistsForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Dim TP_BUTTONS As System.Windows.Forms.TableLayoutPanel
Dim TP_PLS As System.Windows.Forms.TableLayoutPanel
Dim TP_PLS_BUTTONS As System.Windows.Forms.TableLayoutPanel
Dim TP_PLS_ITEMS As System.Windows.Forms.TableLayoutPanel
Dim TP_SETTINGS As System.Windows.Forms.TableLayoutPanel
Dim TP_FORMATS As System.Windows.Forms.TableLayoutPanel
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MusicPlaylistsForm))
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim LBL_FORMAT As System.Windows.Forms.Label
Dim TP_LYRICS As System.Windows.Forms.TableLayoutPanel
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim TT_MAIN As System.Windows.Forms.ToolTip
Me.BTT_DOWN = New System.Windows.Forms.Button()
Me.BTT_CANCEL = New System.Windows.Forms.Button()
Me.SPLITTER_MAIN = New System.Windows.Forms.SplitContainer()
Me.LIST_PLAYLISTS = New System.Windows.Forms.CheckedListBox()
Me.BTT_PLS_ALL = New System.Windows.Forms.Button()
Me.BTT_PLS_NONE = New System.Windows.Forms.Button()
Me.LIST_ITEMS = New System.Windows.Forms.CheckedListBox()
Me.TXT_FORMATS_ADDIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CMB_FORMATS = New System.Windows.Forms.ComboBox()
Me.TXT_SUBS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CH_DOWN_LYRICS = New System.Windows.Forms.CheckBox()
Me.TXT_OUTPUT_PATH = New PersonalUtilities.Forms.Controls.TextBoxExtended()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
TP_PLS = New System.Windows.Forms.TableLayoutPanel()
TP_PLS_BUTTONS = New System.Windows.Forms.TableLayoutPanel()
TP_PLS_ITEMS = New System.Windows.Forms.TableLayoutPanel()
TP_SETTINGS = New System.Windows.Forms.TableLayoutPanel()
TP_FORMATS = New System.Windows.Forms.TableLayoutPanel()
LBL_FORMAT = New System.Windows.Forms.Label()
TP_LYRICS = New System.Windows.Forms.TableLayoutPanel()
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
TP_MAIN.SuspendLayout()
TP_BUTTONS.SuspendLayout()
CType(Me.SPLITTER_MAIN, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SPLITTER_MAIN.Panel1.SuspendLayout()
Me.SPLITTER_MAIN.Panel2.SuspendLayout()
Me.SPLITTER_MAIN.SuspendLayout()
TP_PLS.SuspendLayout()
TP_PLS_BUTTONS.SuspendLayout()
TP_PLS_ITEMS.SuspendLayout()
TP_SETTINGS.SuspendLayout()
TP_FORMATS.SuspendLayout()
CType(Me.TXT_FORMATS_ADDIT, System.ComponentModel.ISupportInitialize).BeginInit()
TP_LYRICS.SuspendLayout()
CType(Me.TXT_SUBS, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_OUTPUT_PATH, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'TP_MAIN
'
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Controls.Add(TP_BUTTONS, 0, 2)
TP_MAIN.Controls.Add(Me.SPLITTER_MAIN, 0, 1)
TP_MAIN.Controls.Add(TP_SETTINGS, 0, 0)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 3
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 84.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.Size = New System.Drawing.Size(434, 261)
TP_MAIN.TabIndex = 0
'
'TP_BUTTONS
'
TP_BUTTONS.ColumnCount = 3
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100.0!))
TP_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100.0!))
TP_BUTTONS.Controls.Add(Me.BTT_DOWN, 1, 0)
TP_BUTTONS.Controls.Add(Me.BTT_CANCEL, 2, 0)
TP_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
TP_BUTTONS.Location = New System.Drawing.Point(0, 236)
TP_BUTTONS.Margin = New System.Windows.Forms.Padding(0)
TP_BUTTONS.Name = "TP_BUTTONS"
TP_BUTTONS.RowCount = 1
TP_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_BUTTONS.Size = New System.Drawing.Size(434, 25)
TP_BUTTONS.TabIndex = 2
'
'BTT_DOWN
'
Me.BTT_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_DOWN.Location = New System.Drawing.Point(236, 2)
Me.BTT_DOWN.Margin = New System.Windows.Forms.Padding(2)
Me.BTT_DOWN.Name = "BTT_DOWN"
Me.BTT_DOWN.Size = New System.Drawing.Size(96, 21)
Me.BTT_DOWN.TabIndex = 0
Me.BTT_DOWN.Text = "Download"
Me.BTT_DOWN.UseVisualStyleBackColor = True
'
'BTT_CANCEL
'
Me.BTT_CANCEL.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.BTT_CANCEL.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_CANCEL.Location = New System.Drawing.Point(336, 2)
Me.BTT_CANCEL.Margin = New System.Windows.Forms.Padding(2)
Me.BTT_CANCEL.Name = "BTT_CANCEL"
Me.BTT_CANCEL.Size = New System.Drawing.Size(96, 21)
Me.BTT_CANCEL.TabIndex = 1
Me.BTT_CANCEL.Text = "Cancel"
Me.BTT_CANCEL.UseVisualStyleBackColor = True
'
'SPLITTER_MAIN
'
Me.SPLITTER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.SPLITTER_MAIN.Location = New System.Drawing.Point(3, 87)
Me.SPLITTER_MAIN.Name = "SPLITTER_MAIN"
'
'SPLITTER_MAIN.Panel1
'
Me.SPLITTER_MAIN.Panel1.Controls.Add(TP_PLS)
Me.SPLITTER_MAIN.Panel1MinSize = 110
'
'SPLITTER_MAIN.Panel2
'
Me.SPLITTER_MAIN.Panel2.Controls.Add(TP_PLS_ITEMS)
Me.SPLITTER_MAIN.Size = New System.Drawing.Size(428, 146)
Me.SPLITTER_MAIN.SplitterDistance = 142
Me.SPLITTER_MAIN.TabIndex = 0
'
'TP_PLS
'
TP_PLS.ColumnCount = 1
TP_PLS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_PLS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_PLS.Controls.Add(Me.LIST_PLAYLISTS, 0, 0)
TP_PLS.Controls.Add(TP_PLS_BUTTONS, 0, 1)
TP_PLS.Dock = System.Windows.Forms.DockStyle.Fill
TP_PLS.Location = New System.Drawing.Point(0, 0)
TP_PLS.Margin = New System.Windows.Forms.Padding(0)
TP_PLS.Name = "TP_PLS"
TP_PLS.RowCount = 2
TP_PLS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_PLS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_PLS.Size = New System.Drawing.Size(142, 146)
TP_PLS.TabIndex = 0
'
'LIST_PLAYLISTS
'
Me.LIST_PLAYLISTS.Dock = System.Windows.Forms.DockStyle.Fill
Me.LIST_PLAYLISTS.FormattingEnabled = True
Me.LIST_PLAYLISTS.Location = New System.Drawing.Point(3, 3)
Me.LIST_PLAYLISTS.Name = "LIST_PLAYLISTS"
Me.LIST_PLAYLISTS.Size = New System.Drawing.Size(136, 115)
Me.LIST_PLAYLISTS.TabIndex = 0
Me.LIST_PLAYLISTS.ThreeDCheckBoxes = True
'
'TP_PLS_BUTTONS
'
TP_PLS_BUTTONS.ColumnCount = 3
TP_PLS_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50.0!))
TP_PLS_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50.0!))
TP_PLS_BUTTONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_PLS_BUTTONS.Controls.Add(Me.BTT_PLS_ALL, 0, 0)
TP_PLS_BUTTONS.Controls.Add(Me.BTT_PLS_NONE, 1, 0)
TP_PLS_BUTTONS.Dock = System.Windows.Forms.DockStyle.Fill
TP_PLS_BUTTONS.Location = New System.Drawing.Point(0, 121)
TP_PLS_BUTTONS.Margin = New System.Windows.Forms.Padding(0)
TP_PLS_BUTTONS.Name = "TP_PLS_BUTTONS"
TP_PLS_BUTTONS.RowCount = 1
TP_PLS_BUTTONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_PLS_BUTTONS.Size = New System.Drawing.Size(142, 25)
TP_PLS_BUTTONS.TabIndex = 1
'
'BTT_PLS_ALL
'
Me.BTT_PLS_ALL.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_PLS_ALL.Location = New System.Drawing.Point(2, 2)
Me.BTT_PLS_ALL.Margin = New System.Windows.Forms.Padding(2)
Me.BTT_PLS_ALL.Name = "BTT_PLS_ALL"
Me.BTT_PLS_ALL.Size = New System.Drawing.Size(46, 21)
Me.BTT_PLS_ALL.TabIndex = 0
Me.BTT_PLS_ALL.Tag = "a"
Me.BTT_PLS_ALL.Text = "All"
TT_MAIN.SetToolTip(Me.BTT_PLS_ALL, "Select all")
Me.BTT_PLS_ALL.UseVisualStyleBackColor = True
'
'BTT_PLS_NONE
'
Me.BTT_PLS_NONE.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_PLS_NONE.Location = New System.Drawing.Point(52, 2)
Me.BTT_PLS_NONE.Margin = New System.Windows.Forms.Padding(2)
Me.BTT_PLS_NONE.Name = "BTT_PLS_NONE"
Me.BTT_PLS_NONE.Size = New System.Drawing.Size(46, 21)
Me.BTT_PLS_NONE.TabIndex = 1
Me.BTT_PLS_NONE.Tag = "n"
Me.BTT_PLS_NONE.Text = "None"
TT_MAIN.SetToolTip(Me.BTT_PLS_NONE, "Select none")
Me.BTT_PLS_NONE.UseVisualStyleBackColor = True
'
'TP_PLS_ITEMS
'
TP_PLS_ITEMS.ColumnCount = 1
TP_PLS_ITEMS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_PLS_ITEMS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_PLS_ITEMS.Controls.Add(Me.LIST_ITEMS, 0, 0)
TP_PLS_ITEMS.Dock = System.Windows.Forms.DockStyle.Fill
TP_PLS_ITEMS.Location = New System.Drawing.Point(0, 0)
TP_PLS_ITEMS.Margin = New System.Windows.Forms.Padding(0)
TP_PLS_ITEMS.Name = "TP_PLS_ITEMS"
TP_PLS_ITEMS.RowCount = 2
TP_PLS_ITEMS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_PLS_ITEMS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_PLS_ITEMS.Size = New System.Drawing.Size(282, 146)
TP_PLS_ITEMS.TabIndex = 1
'
'LIST_ITEMS
'
Me.LIST_ITEMS.Dock = System.Windows.Forms.DockStyle.Fill
Me.LIST_ITEMS.FormattingEnabled = True
Me.LIST_ITEMS.Location = New System.Drawing.Point(3, 3)
Me.LIST_ITEMS.Name = "LIST_ITEMS"
Me.LIST_ITEMS.Size = New System.Drawing.Size(276, 115)
Me.LIST_ITEMS.TabIndex = 0
'
'TP_SETTINGS
'
TP_SETTINGS.ColumnCount = 1
TP_SETTINGS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_SETTINGS.Controls.Add(TP_FORMATS, 0, 1)
TP_SETTINGS.Controls.Add(TP_LYRICS, 0, 0)
TP_SETTINGS.Controls.Add(Me.TXT_OUTPUT_PATH, 0, 2)
TP_SETTINGS.Dock = System.Windows.Forms.DockStyle.Fill
TP_SETTINGS.Location = New System.Drawing.Point(0, 0)
TP_SETTINGS.Margin = New System.Windows.Forms.Padding(0)
TP_SETTINGS.Name = "TP_SETTINGS"
TP_SETTINGS.RowCount = 3
TP_SETTINGS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
TP_SETTINGS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
TP_SETTINGS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333!))
TP_SETTINGS.Size = New System.Drawing.Size(434, 84)
TP_SETTINGS.TabIndex = 1
'
'TP_FORMATS
'
TP_FORMATS.ColumnCount = 3
TP_FORMATS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50.0!))
TP_FORMATS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 65.0!))
TP_FORMATS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FORMATS.Controls.Add(Me.TXT_FORMATS_ADDIT, 2, 0)
TP_FORMATS.Controls.Add(LBL_FORMAT, 0, 0)
TP_FORMATS.Controls.Add(Me.CMB_FORMATS, 1, 0)
TP_FORMATS.Dock = System.Windows.Forms.DockStyle.Fill
TP_FORMATS.Location = New System.Drawing.Point(0, 28)
TP_FORMATS.Margin = New System.Windows.Forms.Padding(0)
TP_FORMATS.Name = "TP_FORMATS"
TP_FORMATS.RowCount = 1
TP_FORMATS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FORMATS.Size = New System.Drawing.Size(434, 28)
TP_FORMATS.TabIndex = 1
'
'TXT_FORMATS_ADDIT
'
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Enabled = False
ActionButton1.Name = "Open"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Enabled = False
ActionButton2.Name = "Refresh"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Enabled = False
ActionButton3.Name = "Clear"
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_FORMATS_ADDIT.Buttons.Add(ActionButton1)
Me.TXT_FORMATS_ADDIT.Buttons.Add(ActionButton2)
Me.TXT_FORMATS_ADDIT.Buttons.Add(ActionButton3)
Me.TXT_FORMATS_ADDIT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_FORMATS_ADDIT.CaptionText = "Additional formats"
Me.TXT_FORMATS_ADDIT.CaptionToolTipEnabled = True
Me.TXT_FORMATS_ADDIT.CaptionToolTipText = "Convert every downloaded track to the formats you choose."
Me.TXT_FORMATS_ADDIT.CaptionWidth = 115.0R
Me.TXT_FORMATS_ADDIT.ClearTextByButtonClear = False
Me.TXT_FORMATS_ADDIT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FORMATS_ADDIT.Location = New System.Drawing.Point(118, 3)
Me.TXT_FORMATS_ADDIT.Name = "TXT_FORMATS_ADDIT"
Me.TXT_FORMATS_ADDIT.Size = New System.Drawing.Size(313, 22)
Me.TXT_FORMATS_ADDIT.TabIndex = 2
Me.TXT_FORMATS_ADDIT.Tag = "a"
Me.TXT_FORMATS_ADDIT.TextBoxReadOnly = True
'
'LBL_FORMAT
'
LBL_FORMAT.Dock = System.Windows.Forms.DockStyle.Fill
LBL_FORMAT.Location = New System.Drawing.Point(3, 0)
LBL_FORMAT.Margin = New System.Windows.Forms.Padding(3, 0, 0, 0)
LBL_FORMAT.Name = "LBL_FORMAT"
LBL_FORMAT.Size = New System.Drawing.Size(47, 28)
LBL_FORMAT.TabIndex = 0
LBL_FORMAT.Text = "Format:"
LBL_FORMAT.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(LBL_FORMAT, "Output files format")
'
'CMB_FORMATS
'
Me.CMB_FORMATS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_FORMATS.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.CMB_FORMATS.FormattingEnabled = True
Me.CMB_FORMATS.Location = New System.Drawing.Point(53, 3)
Me.CMB_FORMATS.Name = "CMB_FORMATS"
Me.CMB_FORMATS.Size = New System.Drawing.Size(59, 21)
Me.CMB_FORMATS.TabIndex = 1
'
'TP_LYRICS
'
TP_LYRICS.ColumnCount = 2
TP_LYRICS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 115.0!))
TP_LYRICS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_LYRICS.Controls.Add(Me.TXT_SUBS, 1, 0)
TP_LYRICS.Controls.Add(Me.CH_DOWN_LYRICS, 0, 0)
TP_LYRICS.Dock = System.Windows.Forms.DockStyle.Fill
TP_LYRICS.Location = New System.Drawing.Point(0, 0)
TP_LYRICS.Margin = New System.Windows.Forms.Padding(0)
TP_LYRICS.Name = "TP_LYRICS"
TP_LYRICS.RowCount = 1
TP_LYRICS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_LYRICS.Size = New System.Drawing.Size(434, 28)
TP_LYRICS.TabIndex = 0
'
'TXT_SUBS
'
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
ActionButton4.Enabled = False
ActionButton4.Name = "Open"
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
ActionButton5.Enabled = False
ActionButton5.Name = "Refresh"
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
ActionButton6.Enabled = False
ActionButton6.Name = "Clear"
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_SUBS.Buttons.Add(ActionButton4)
Me.TXT_SUBS.Buttons.Add(ActionButton5)
Me.TXT_SUBS.Buttons.Add(ActionButton6)
Me.TXT_SUBS.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SUBS.CaptionText = "Additional lyrics"
Me.TXT_SUBS.CaptionToolTipEnabled = True
Me.TXT_SUBS.CaptionToolTipText = "Convert all downloaded lyrics to the formats you choose."
Me.TXT_SUBS.CaptionWidth = 115.0R
Me.TXT_SUBS.ClearTextByButtonClear = False
Me.TXT_SUBS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SUBS.Location = New System.Drawing.Point(118, 3)
Me.TXT_SUBS.Name = "TXT_SUBS"
Me.TXT_SUBS.Size = New System.Drawing.Size(313, 22)
Me.TXT_SUBS.TabIndex = 1
Me.TXT_SUBS.Tag = "s"
Me.TXT_SUBS.TextBoxReadOnly = True
'
'CH_DOWN_LYRICS
'
Me.CH_DOWN_LYRICS.AutoSize = True
Me.CH_DOWN_LYRICS.CheckAlign = System.Drawing.ContentAlignment.MiddleRight
Me.CH_DOWN_LYRICS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_LYRICS.Location = New System.Drawing.Point(3, 3)
Me.CH_DOWN_LYRICS.Name = "CH_DOWN_LYRICS"
Me.CH_DOWN_LYRICS.Size = New System.Drawing.Size(109, 22)
Me.CH_DOWN_LYRICS.TabIndex = 0
Me.CH_DOWN_LYRICS.Text = "Download lyrics"
Me.CH_DOWN_LYRICS.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(Me.CH_DOWN_LYRICS, "Download lyrics if available")
Me.CH_DOWN_LYRICS.UseVisualStyleBackColor = True
'
'TXT_OUTPUT_PATH
'
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Name = "Open"
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Name = "Clear"
ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_OUTPUT_PATH.Buttons.Add(ActionButton7)
Me.TXT_OUTPUT_PATH.Buttons.Add(ActionButton8)
Me.TXT_OUTPUT_PATH.CaptionText = "Output path"
Me.TXT_OUTPUT_PATH.CaptionWidth = 112.0R
Me.TXT_OUTPUT_PATH.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_OUTPUT_PATH.Location = New System.Drawing.Point(3, 59)
Me.TXT_OUTPUT_PATH.Name = "TXT_OUTPUT_PATH"
Me.TXT_OUTPUT_PATH.Size = New System.Drawing.Size(428, 22)
Me.TXT_OUTPUT_PATH.TabIndex = 2
'
'MusicPlaylistsForm
'
Me.AcceptButton = Me.BTT_DOWN
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.BTT_CANCEL
Me.ClientSize = New System.Drawing.Size(434, 261)
Me.Controls.Add(TP_MAIN)
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeMusicIcon_32
Me.KeyPreview = True
Me.MinimumSize = New System.Drawing.Size(450, 300)
Me.Name = "MusicPlaylistsForm"
Me.Text = "Albums"
TP_MAIN.ResumeLayout(False)
TP_BUTTONS.ResumeLayout(False)
Me.SPLITTER_MAIN.Panel1.ResumeLayout(False)
Me.SPLITTER_MAIN.Panel2.ResumeLayout(False)
CType(Me.SPLITTER_MAIN, System.ComponentModel.ISupportInitialize).EndInit()
Me.SPLITTER_MAIN.ResumeLayout(False)
TP_PLS.ResumeLayout(False)
TP_PLS_BUTTONS.ResumeLayout(False)
TP_PLS_ITEMS.ResumeLayout(False)
TP_SETTINGS.ResumeLayout(False)
TP_FORMATS.ResumeLayout(False)
CType(Me.TXT_FORMATS_ADDIT, System.ComponentModel.ISupportInitialize).EndInit()
TP_LYRICS.ResumeLayout(False)
TP_LYRICS.PerformLayout()
CType(Me.TXT_SUBS, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_OUTPUT_PATH, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Private WithEvents BTT_DOWN As Button
Private WithEvents BTT_CANCEL As Button
Private WithEvents LIST_PLAYLISTS As CheckedListBox
Private WithEvents LIST_ITEMS As CheckedListBox
Private WithEvents TXT_SUBS As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents BTT_PLS_ALL As Button
Private WithEvents BTT_PLS_NONE As Button
Private WithEvents TXT_FORMATS_ADDIT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CMB_FORMATS As ComboBox
Private WithEvents SPLITTER_MAIN As SplitContainer
Private WithEvents CH_DOWN_LYRICS As CheckBox
Private WithEvents TXT_OUTPUT_PATH As PersonalUtilities.Forms.Controls.TextBoxExtended
End Class
End Namespace

View File

@@ -0,0 +1,243 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_PLS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_PLS_BUTTONS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="TP_PLS_ITEMS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_SETTINGS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_FORMATS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="LBL_FORMAT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_LYRICS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,262 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports SCrawler.API.YouTube.Objects
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls
Imports PersonalUtilities.Forms.Controls.Base
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace API.YouTube.Controls
Friend Class MusicPlaylistsForm : Implements IDesignXMLContainer
#Region "Declarations"
Private MyView As FormView
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
Private ReadOnly MyContainer As IYouTubeMediaContainer
Private Initializing As Boolean = True
Private ReadOnly Property Current As IYouTubeMediaContainer
Get
With MyContainer
If .ObjectType = Base.YouTubeMediaType.Channel Then
If _LatestSelected.ValueBetween(0, .Count - 1) Then Return .Elements(_LatestSelected)
Else
Return .Self
End If
End With
Return Nothing
End Get
End Property
#End Region
#Region "Initializer"
Friend Sub New(ByVal Container As IYouTubeMediaContainer)
InitializeComponent()
MyContainer = Container
End Sub
#End Region
#Region "Form handlers"
Private Sub MusicPlaylistsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not DesignXML Is Nothing Then
MyView = New FormView(Me)
MyView.Import()
MyView.SetFormSize()
End If
CMB_FORMATS.Items.AddRange(AvailableAudioFormats)
If MyYouTubeSettings.PlaylistFormSplitterDistance > 0 Then SPLITTER_MAIN.SplitterDistancePercentageSet(MyYouTubeSettings.PlaylistFormSplitterDistance)
With MyContainer
CH_DOWN_LYRICS.Checked = Not .OutputSubtitlesFormat.IsEmptyString
Dim i%
If Not .OutputAudioCodec.IsEmptyString Then
i = AvailableAudioFormats.ListIndexOf(Function(ff) ff.StringToLower = .OutputAudioCodec.StringToLower)
If i >= 0 Then CMB_FORMATS.SelectedIndex = i
End If
If CMB_FORMATS.SelectedIndex = -1 Then
Dim oac$ = MyYouTubeSettings.DefaultAudioCodecMusic.Value.IfNullOrEmpty("mp3").StringToLower
i = AvailableAudioFormats.ListIndexOf(Function(ff) ff.StringToLower = oac)
If i >= 0 Then CMB_FORMATS.SelectedIndex = i Else CMB_FORMATS.SelectedIndex = 0
End If
If .ObjectType = Base.YouTubeMediaType.Channel Then
If .HasElements Then
For Each elem In .Elements : LIST_PLAYLISTS.Items.Add(elem, elem.CheckState) : Next
End If
ElseIf .ObjectType = Base.YouTubeMediaType.PlayList Then
LIST_PLAYLISTS.Items.Add(.Self, .CheckState)
Else
Throw New InvalidOperationException($"The object type '{ .ObjectType}' is incompatible with 'MusicPlaylistsForm'.")
End If
LIST_PLAYLISTS.SelectedIndex = 0
TXT_OUTPUT_PATH.Text = MyYouTubeSettings.OutputPath.Value
If Not .UserTitle.IsEmptyString Then
Text = .UserTitle
ElseIf Not .PlaylistTitle.IsEmptyString Then
Text = .PlaylistTitle
End If
UpdateSizeText()
End With
RefillAddit()
Initializing = False
End Sub
Private Sub MusicPlaylistsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
MyYouTubeSettings.PlaylistFormSplitterDistance.Value = SPLITTER_MAIN.SplitterDistancePercentageGet
MyView.DisposeIfReady()
End Sub
#End Region
#Region "Form text"
Private _InitialFormText As String = String.Empty
Private Sub UpdateSizeText()
If _InitialFormText.IsEmptyString Then _InitialFormText = Text
Text = $"{_InitialFormText} ({MyContainer.SizeStr})"
End Sub
#End Region
#Region "Settings"
Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick, TXT_FORMATS_ADDIT.ActionOnButtonClick
Dim isLyrics As Boolean = DirectCast(e.AssociatedControl, Control).Tag = "s"
With DirectCast(MyContainer, YouTubeMediaContainerBase)
Select Case Sender.DefaultButton
Case ADB.Open
Using f As New SimpleListForm(Of String)(IIf(isLyrics, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
.DesignXML = DesignXML,
.DesignXMLNodeName = SimpleArraysFormNode,
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText,
.Icon = My.Resources.SiteYouTube.YouTubeMusicIcon_32,
.Mode = SimpleListFormModes.CheckedItems
}
f.DataSelected.ListAddList(IIf(isLyrics, .PostProcessing_OutputSubtitlesFormats, .PostProcessing_OutputAudioFormats))
If f.ShowDialog = DialogResult.OK Then
If isLyrics Then
.PostProcessing_OutputSubtitlesFormats.Clear()
.PostProcessing_OutputSubtitlesFormats.ListAddList(f.DataResult)
Else
.PostProcessing_OutputAudioFormats.Clear()
.PostProcessing_OutputAudioFormats.ListAddList(f.DataResult)
End If
RefillAddit()
End If
End Using
Case ADB.Refresh
If isLyrics Then
.PostProcessing_OutputSubtitlesFormats_Reset()
Else
.PostProcessing_OutputAudioFormats_Reset()
End If
RefillAddit()
Case ADB.Clear
If isLyrics Then
.PostProcessing_OutputSubtitlesFormats.Clear()
Else
.PostProcessing_OutputAudioFormats.Clear()
End If
RefillAddit()
End Select
End With
End Sub
Private Sub RefillAddit()
With DirectCast(MyContainer, YouTubeMediaContainerBase)
TXT_SUBS.Text = .PostProcessing_OutputSubtitlesFormats.ListToString
TXT_FORMATS_ADDIT.Text = .PostProcessing_OutputAudioFormats.ListToString
End With
End Sub
Private Sub TXT_OUTPUT_PATH_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_OUTPUT_PATH.ActionOnButtonClick
If Sender.DefaultButton = ADB.Open Then
Dim f As SFile = SFile.SelectPath(TXT_OUTPUT_PATH.Text, "Select files destination", EDP.ReturnValue)
If Not f.IsEmptyString Then TXT_OUTPUT_PATH.Text = f
End If
End Sub
#End Region
#Region "Lists' handlers"
Private _LatestSelected As Integer = -1
Private Sub LIST_PLAYLISTS_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LIST_PLAYLISTS.SelectedIndexChanged
Dim i% = LIST_PLAYLISTS.SelectedIndex
If i >= 0 Then
_LatestSelected = i
LIST_ITEMS.Items.Clear()
With DirectCast(LIST_PLAYLISTS.SelectedItem, IYouTubeMediaContainer)
If .HasElements Then
For Each elem In .Elements : LIST_ITEMS.Items.Add(elem, elem.Checked) : Next
End If
End With
End If
End Sub
Private _CheckHandlersSuspended As Boolean = False
Private Sub LIST_PLAYLISTS_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles LIST_PLAYLISTS.ItemCheck
If Not Initializing And Not _CheckHandlersSuspended Then
_CheckHandlersSuspended = True
Dim checked As Boolean = Not e.NewValue = CheckState.Unchecked
Dim current As IYouTubeMediaContainer = Me.Current
If Not current Is Nothing Then
With current
.Checked = checked
If LIST_ITEMS.Items.Count > 0 Then
_ListCheckHandlersSuspended = True
For i% = 0 To .Count - 1
If i.ValueBetween(0, LIST_ITEMS.Items.Count - 1) Then LIST_ITEMS.SetItemChecked(i, checked)
Next
_ListCheckHandlersSuspended = False
End If
If LIST_PLAYLISTS.Items.Count.ValueBetween(0, _LatestSelected) Then LIST_PLAYLISTS.SetItemChecked(_LatestSelected, checked)
End With
UpdateSizeText()
End If
_CheckHandlersSuspended = False
End If
End Sub
Private _ListCheckHandlersSuspended As Boolean = False
Private Sub LIST_ITEMS_ItemCheck(sender As Object, e As ItemCheckEventArgs) Handles LIST_ITEMS.ItemCheck
If Not Initializing Then
Dim current As IYouTubeMediaContainer = Me.Current
If Not current Is Nothing Then
With current
If e.Index.ValueBetween(0, .Count - 1) Then
.Elements(e.Index).Checked = e.NewValue
If Not _ListCheckHandlersSuspended And _LatestSelected.ValueBetween(0, LIST_PLAYLISTS.Items.Count - 1) Then
Dim checked As Boolean = .Elements(e.Index).Checked
_CheckHandlersSuspended = True
If .Elements.All(Function(ee) ee.Checked = checked) Then
LIST_PLAYLISTS.SetItemChecked(_LatestSelected, checked)
Else
LIST_PLAYLISTS.SetItemCheckState(_LatestSelected, CheckState.Indeterminate)
End If
_CheckHandlersSuspended = False
LIST_PLAYLISTS.Refresh()
UpdateSizeText()
End If
End If
End With
End If
End If
End Sub
#End Region
#Region "Selection buttons"
Private Sub BTT_PLS_Click(sender As Object, e As EventArgs) Handles BTT_PLS_ALL.Click, BTT_PLS_NONE.Click
Dim checked As Boolean = DirectCast(sender, Button).Tag = "a"
_CheckHandlersSuspended = True
If LIST_PLAYLISTS.Items.Count > 0 Then
For i% = 0 To LIST_PLAYLISTS.Items.Count - 1 : LIST_PLAYLISTS.SetItemChecked(i, checked) : Next
End If
MyContainer.Checked = checked
If MyContainer.Count > 1 Then MyContainer.Elements.ForEach(Sub(ee) ee.Checked = checked)
_CheckHandlersSuspended = False
UpdateSizeText()
End Sub
#End Region
#Region "Ok, Cancel"
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
If TXT_OUTPUT_PATH.IsEmptyString Then
MsgBoxE({"The output path cannot be null.", "Download music"}, vbCritical)
Else
With DirectCast(MyContainer, YouTubeMediaContainerBase)
.OutputSubtitlesFormat = IIf(CH_DOWN_LYRICS.Checked, "LRC", String.Empty)
If Not TXT_SUBS.Checked Then .PostProcessing_OutputSubtitlesFormats.Clear()
.OutputAudioCodec = CMB_FORMATS.Text
If Not TXT_FORMATS_ADDIT.Checked Then .PostProcessing_OutputAudioFormats.Clear()
.File = TXT_OUTPUT_PATH.Text.CSFileP
If MyYouTubeSettings.OutputPathAutoChange Then MyYouTubeSettings.OutputPath.Value = .File
End With
DialogResult = DialogResult.OK
Close()
End If
End Sub
Private Sub BTT_CANCEL_Click(sender As Object, e As EventArgs) Handles BTT_CANCEL.Click
DialogResult = DialogResult.Cancel
Close()
End Sub
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,94 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Controls
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Public Class ParsingProgressForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Me.PR_MAIN = New System.Windows.Forms.ProgressBar()
Me.LBL_MAIN = New System.Windows.Forms.Label()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_MAIN.SuspendLayout()
Me.SuspendLayout()
'
'TP_MAIN
'
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Controls.Add(Me.PR_MAIN, 0, 0)
TP_MAIN.Controls.Add(Me.LBL_MAIN, 0, 1)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 2
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.Size = New System.Drawing.Size(334, 56)
TP_MAIN.TabIndex = 0
'
'PR_MAIN
'
Me.PR_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.PR_MAIN.Location = New System.Drawing.Point(3, 3)
Me.PR_MAIN.Name = "PR_MAIN"
Me.PR_MAIN.Size = New System.Drawing.Size(328, 25)
Me.PR_MAIN.TabIndex = 0
'
'LBL_MAIN
'
Me.LBL_MAIN.AutoSize = True
Me.LBL_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_MAIN.Location = New System.Drawing.Point(3, 31)
Me.LBL_MAIN.Name = "LBL_MAIN"
Me.LBL_MAIN.Size = New System.Drawing.Size(328, 25)
Me.LBL_MAIN.TabIndex = 1
Me.LBL_MAIN.TextAlign = System.Drawing.ContentAlignment.TopCenter
'
'ParsingProgressForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(334, 56)
Me.ControlBox = False
Me.Controls.Add(TP_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(350, 95)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(350, 95)
Me.Name = "ParsingProgressForm"
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent
Me.Text = "Parsing progress"
Me.TopMost = True
TP_MAIN.ResumeLayout(False)
TP_MAIN.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents PR_MAIN As ProgressBar
Private WithEvents LBL_MAIN As Label
End Class
End Namespace

View File

@@ -117,9 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>

View File

@@ -0,0 +1,48 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.Threading
Imports PersonalUtilities.Forms.Toolbars
Namespace API.YouTube.Controls
Public Class ParsingProgressForm
Public ReadOnly Property MyProgress As MyProgress
Private ReadOnly TokenSource As CancellationTokenSource
Public ReadOnly Property Token As CancellationToken
Get
Return TokenSource.Token
End Get
End Property
Public Sub New()
InitializeComponent()
MyProgress = New MyProgress(PR_MAIN, LBL_MAIN, "Data parsing in progress") With {.ResetProgressOnMaximumChanges = False}
TokenSource = New CancellationTokenSource
End Sub
Public Sub SetInitialValues(ByVal Count As Integer, ByVal Info As String)
With MyProgress
.Maximum = Count
.Visible = True
.Perform(0.5)
.Value = 0
.InformationTemporary = Info
End With
End Sub
Private _KeyDownDisabled As Boolean = False
Private Sub ParsingProgressForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Escape AndAlso Not _KeyDownDisabled AndAlso MsgBoxE({"Data parsing in progress." & vbCr &
"Are you sure you want to stop parsing and cancel the operation?",
"Stop parsing"}, vbExclamation + vbYesNo) = vbYes Then
_KeyDownDisabled = True
TokenSource.Cancel()
End If
End Sub
Private Sub ParsingProgressForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
MyProgress.Dispose()
TokenSource.Dispose()
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,171 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Controls
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class PlayListParserForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Dim FRM_IN As System.Windows.Forms.GroupBox
Dim FRM_OUT As System.Windows.Forms.GroupBox
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(PlayListParserForm))
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
Dim TT_MAIN As System.Windows.Forms.ToolTip
Me.TXT_IN = New System.Windows.Forms.RichTextBox()
Me.TXT_OUT = New System.Windows.Forms.RichTextBox()
Me.TXT_LIMIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
FRM_IN = New System.Windows.Forms.GroupBox()
FRM_OUT = New System.Windows.Forms.GroupBox()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
TP_MAIN.SuspendLayout()
FRM_IN.SuspendLayout()
FRM_OUT.SuspendLayout()
CType(Me.TXT_LIMIT, System.ComponentModel.ISupportInitialize).BeginInit()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
Me.SuspendLayout()
'
'TP_MAIN
'
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Controls.Add(FRM_IN, 0, 1)
TP_MAIN.Controls.Add(FRM_OUT, 0, 2)
TP_MAIN.Controls.Add(Me.TXT_LIMIT, 0, 0)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 3
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_MAIN.Size = New System.Drawing.Size(384, 261)
TP_MAIN.TabIndex = 0
'
'FRM_IN
'
FRM_IN.Controls.Add(Me.TXT_IN)
FRM_IN.Dock = System.Windows.Forms.DockStyle.Fill
FRM_IN.Location = New System.Drawing.Point(3, 31)
FRM_IN.Name = "FRM_IN"
FRM_IN.Size = New System.Drawing.Size(378, 110)
FRM_IN.TabIndex = 0
FRM_IN.TabStop = False
FRM_IN.Text = "In"
TT_MAIN.SetToolTip(FRM_IN, "In your browser's DevTools, find the page starting with the following URL and cop" &
"y the response text into this window." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "https://music.youtube.com/youtubei/v1/bro" &
"wse?key=")
'
'TXT_IN
'
Me.TXT_IN.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_IN.Location = New System.Drawing.Point(3, 16)
Me.TXT_IN.Name = "TXT_IN"
Me.TXT_IN.Size = New System.Drawing.Size(372, 91)
Me.TXT_IN.TabIndex = 0
Me.TXT_IN.Text = ""
'
'FRM_OUT
'
FRM_OUT.Controls.Add(Me.TXT_OUT)
FRM_OUT.Dock = System.Windows.Forms.DockStyle.Fill
FRM_OUT.Location = New System.Drawing.Point(3, 147)
FRM_OUT.Name = "FRM_OUT"
FRM_OUT.Size = New System.Drawing.Size(378, 111)
FRM_OUT.TabIndex = 1
FRM_OUT.TabStop = False
FRM_OUT.Text = "Out"
'
'TXT_OUT
'
Me.TXT_OUT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_OUT.Location = New System.Drawing.Point(3, 16)
Me.TXT_OUT.Name = "TXT_OUT"
Me.TXT_OUT.Size = New System.Drawing.Size(372, 92)
Me.TXT_OUT.TabIndex = 0
Me.TXT_OUT.Text = ""
'
'TXT_LIMIT
'
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "Clear"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
Me.TXT_LIMIT.Buttons.Add(ActionButton1)
Me.TXT_LIMIT.CaptionText = "Remove"
Me.TXT_LIMIT.CaptionToolTipEnabled = True
Me.TXT_LIMIT.CaptionToolTipText = "Remove playlists starts with..."
Me.TXT_LIMIT.CaptionWidth = 50.0R
Me.TXT_LIMIT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_LIMIT.Location = New System.Drawing.Point(3, 3)
Me.TXT_LIMIT.Name = "TXT_LIMIT"
Me.TXT_LIMIT.PlaceholderEnabled = True
Me.TXT_LIMIT.PlaceholderText = "e.g. ABCDE"
Me.TXT_LIMIT.Size = New System.Drawing.Size(378, 22)
Me.TXT_LIMIT.TabIndex = 2
'
'CONTAINER_MAIN
'
'
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 261)
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
CONTAINER_MAIN.LeftToolStripPanelVisible = False
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
CONTAINER_MAIN.RightToolStripPanelVisible = False
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 261)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'PlayListParserForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(384, 261)
Me.Controls.Add(CONTAINER_MAIN)
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeMusicIcon_32
Me.KeyPreview = True
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(400, 300)
Me.Name = "PlayListParserForm"
Me.ShowInTaskbar = False
Me.Text = "Playlist parser"
TP_MAIN.ResumeLayout(False)
FRM_IN.ResumeLayout(False)
FRM_OUT.ResumeLayout(False)
CType(Me.TXT_LIMIT, System.ComponentModel.ISupportInitialize).EndInit()
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents TXT_IN As RichTextBox
Private WithEvents TXT_OUT As RichTextBox
Private WithEvents TXT_LIMIT As PersonalUtilities.Forms.Controls.TextBoxExtended
End Class
End Namespace

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="FRM_IN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="FRM_OUT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="CONTAINER_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -0,0 +1,60 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.YouTube.Controls
Friend Class PlayListParserForm : Implements IDesignXMLContainer
Private WithEvents MyDefs As DefaultFormOptions
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
Friend ReadOnly Property PlayLists As List(Of String)
Get
If Not TXT_OUT.Text.IsEmptyString Then
Return TXT_OUT.Lines.ToList
Else
Return New List(Of String)
End If
End Get
End Property
Friend Sub New()
InitializeComponent()
MyDefs = New DefaultFormOptions(Me)
End Sub
Private Sub MyForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddOkCancelToolbar()
.EndLoaderOperations()
End With
End Sub
Private Sub UpdatePlaylists(sender As Object, e As EventArgs) Handles TXT_IN.TextChanged, TXT_LIMIT.ActionOnTextChanged
Try
If Not TXT_IN.Text.IsEmptyString Then
Dim l As List(Of String) = ListAddList(Of String)(Nothing, RegexReplace(TXT_IN.Text, RParams.DMS("playlistId"": ""([^""]+)""", 1,
RegexReturn.List, EDP.ReturnValue)),
LAP.NotContainsOnly, EDP.ReturnValue)
If Not TXT_LIMIT.Text.IsEmptyString And l.ListExists Then l.RemoveAll(Function(id) id.StringToLower.StartsWith(TXT_LIMIT.Text.ToLower))
If l.ListExists Then
TXT_OUT.Text = l.Select(Function(id) $"https://music.youtube.com/playlist?list={id}").ListToString(vbNewLine, EDP.ReturnValue)
Else
TXT_OUT.Text = String.Empty
End If
Else
TXT_OUT.Text = String.Empty
End If
Catch ex As Exception
TXT_OUT.Text = String.Empty
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "[PlayListParserForm.UpdatePlaylists]")
End Try
End Sub
End Class
End Namespace

View File

@@ -6,9 +6,9 @@
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.PornHub
Namespace API.YouTube.Controls
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class OptionsForm : Inherits System.Windows.Forms.Form
Partial Friend Class PlaylistArrayForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
@@ -24,13 +24,16 @@ Namespace API.PornHub
Private Sub InitializeComponent()
Dim CONTAINER_MAIN As System.Windows.Forms.ToolStripContainer
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Me.CH_DOWN_GIFS = New System.Windows.Forms.CheckBox()
Me.CH_DOWN_PHOTO_MODELHUB = New System.Windows.Forms.CheckBox()
Dim FRM_PLS As System.Windows.Forms.GroupBox
Me.CH_PLS_ONE = New System.Windows.Forms.CheckBox()
Me.TXT_URLS = New System.Windows.Forms.RichTextBox()
CONTAINER_MAIN = New System.Windows.Forms.ToolStripContainer()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
FRM_PLS = New System.Windows.Forms.GroupBox()
CONTAINER_MAIN.ContentPanel.SuspendLayout()
CONTAINER_MAIN.SuspendLayout()
TP_MAIN.SuspendLayout()
FRM_PLS.SuspendLayout()
Me.SuspendLayout()
'
'CONTAINER_MAIN
@@ -39,80 +42,87 @@ Namespace API.PornHub
'CONTAINER_MAIN.ContentPanel
'
CONTAINER_MAIN.ContentPanel.Controls.Add(TP_MAIN)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(278, 52)
CONTAINER_MAIN.ContentPanel.Size = New System.Drawing.Size(384, 311)
CONTAINER_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
CONTAINER_MAIN.LeftToolStripPanelVisible = False
CONTAINER_MAIN.Location = New System.Drawing.Point(0, 0)
CONTAINER_MAIN.Name = "CONTAINER_MAIN"
CONTAINER_MAIN.RightToolStripPanelVisible = False
CONTAINER_MAIN.Size = New System.Drawing.Size(278, 77)
CONTAINER_MAIN.Size = New System.Drawing.Size(384, 311)
CONTAINER_MAIN.TabIndex = 0
CONTAINER_MAIN.TopToolStripPanelVisible = False
'
'TP_MAIN
'
TP_MAIN.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
TP_MAIN.ColumnCount = 1
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Controls.Add(Me.CH_DOWN_GIFS, 0, 0)
TP_MAIN.Controls.Add(Me.CH_DOWN_PHOTO_MODELHUB, 0, 1)
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_MAIN.Controls.Add(Me.CH_PLS_ONE, 0, 0)
TP_MAIN.Controls.Add(FRM_PLS, 0, 1)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 3
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowCount = 2
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Size = New System.Drawing.Size(278, 52)
TP_MAIN.Size = New System.Drawing.Size(384, 311)
TP_MAIN.TabIndex = 0
'
'CH_DOWN_GIFS
'CH_PLS_ONE
'
Me.CH_DOWN_GIFS.AutoSize = True
Me.CH_DOWN_GIFS.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_GIFS.Location = New System.Drawing.Point(4, 4)
Me.CH_DOWN_GIFS.Name = "CH_DOWN_GIFS"
Me.CH_DOWN_GIFS.Size = New System.Drawing.Size(270, 19)
Me.CH_DOWN_GIFS.TabIndex = 0
Me.CH_DOWN_GIFS.Text = "Download gifs"
Me.CH_DOWN_GIFS.UseVisualStyleBackColor = True
Me.CH_PLS_ONE.AutoSize = True
Me.CH_PLS_ONE.Checked = True
Me.CH_PLS_ONE.CheckState = System.Windows.Forms.CheckState.Checked
Me.CH_PLS_ONE.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_PLS_ONE.Location = New System.Drawing.Point(3, 3)
Me.CH_PLS_ONE.Name = "CH_PLS_ONE"
Me.CH_PLS_ONE.Size = New System.Drawing.Size(378, 19)
Me.CH_PLS_ONE.TabIndex = 1
Me.CH_PLS_ONE.Text = "Playlists / Albums by one artist"
Me.CH_PLS_ONE.UseVisualStyleBackColor = True
'
'CH_DOWN_PHOTO_MODELHUB
'FRM_PLS
'
Me.CH_DOWN_PHOTO_MODELHUB.AutoSize = True
Me.CH_DOWN_PHOTO_MODELHUB.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_DOWN_PHOTO_MODELHUB.Location = New System.Drawing.Point(4, 30)
Me.CH_DOWN_PHOTO_MODELHUB.Name = "CH_DOWN_PHOTO_MODELHUB"
Me.CH_DOWN_PHOTO_MODELHUB.Size = New System.Drawing.Size(270, 19)
Me.CH_DOWN_PHOTO_MODELHUB.TabIndex = 1
Me.CH_DOWN_PHOTO_MODELHUB.Text = "Download photo only from ModelHub"
Me.CH_DOWN_PHOTO_MODELHUB.UseVisualStyleBackColor = True
FRM_PLS.Controls.Add(Me.TXT_URLS)
FRM_PLS.Dock = System.Windows.Forms.DockStyle.Fill
FRM_PLS.Location = New System.Drawing.Point(3, 28)
FRM_PLS.Name = "FRM_PLS"
FRM_PLS.Size = New System.Drawing.Size(378, 280)
FRM_PLS.TabIndex = 0
FRM_PLS.TabStop = False
FRM_PLS.Text = "URLs (new line as delimiter); Ctrl+O to parse playlists from response"
'
'OptionsForm
'TXT_URLS
'
Me.TXT_URLS.DetectUrls = False
Me.TXT_URLS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_URLS.Location = New System.Drawing.Point(3, 16)
Me.TXT_URLS.Name = "TXT_URLS"
Me.TXT_URLS.Size = New System.Drawing.Size(372, 261)
Me.TXT_URLS.TabIndex = 0
Me.TXT_URLS.Text = ""
'
'PlaylistArrayForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(278, 77)
Me.ClientSize = New System.Drawing.Size(384, 311)
Me.Controls.Add(CONTAINER_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.SiteResources.InstagramIcon_32
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeMusicIcon_32
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MaximumSize = New System.Drawing.Size(294, 116)
Me.MinimizeBox = False
Me.MinimumSize = New System.Drawing.Size(294, 116)
Me.Name = "OptionsForm"
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.Text = "Options"
Me.MinimumSize = New System.Drawing.Size(400, 350)
Me.Name = "PlaylistArrayForm"
Me.Text = "Playlists / Albums"
CONTAINER_MAIN.ContentPanel.ResumeLayout(False)
CONTAINER_MAIN.ResumeLayout(False)
CONTAINER_MAIN.PerformLayout()
TP_MAIN.ResumeLayout(False)
TP_MAIN.PerformLayout()
FRM_PLS.ResumeLayout(False)
Me.ResumeLayout(False)
End Sub
Private WithEvents CH_DOWN_GIFS As CheckBox
Private WithEvents CH_DOWN_PHOTO_MODELHUB As CheckBox
Private WithEvents CH_PLS_ONE As CheckBox
Private WithEvents TXT_URLS As RichTextBox
End Class
End Namespace

View File

@@ -123,4 +123,7 @@
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="FRM_PLS.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -0,0 +1,54 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Namespace API.YouTube.Controls
Friend Class PlaylistArrayForm : Implements IDesignXMLContainer
Private WithEvents MyDefs As DefaultFormOptions
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
Friend ReadOnly Property URLs As List(Of String)
Get
If Not TXT_URLS.Text.IsEmptyString Then
Return ListAddList(Nothing, TXT_URLS.Text.StringFormatLines.StringToList(Of String)(vbNewLine),
LAP.NotContainsOnly, EDP.ReturnValue, CType(Function(Input$) Input.StringTrim, Func(Of Object, Object))).ListIfNothing
Else
Return New List(Of String)
End If
End Get
End Property
Friend ReadOnly Property IsOneArtist As Boolean
Get
Return CH_PLS_ONE.Checked
End Get
End Property
Friend Sub New()
InitializeComponent()
MyDefs = New DefaultFormOptions(Me)
End Sub
Private Sub PlaylistArrayForm_Load(sender As Object, e As EventArgs) Handles Me.Load
With MyDefs
.MyViewInitialize()
.AddOkCancelToolbar()
.EndLoaderOperations()
End With
End Sub
Private Sub PlaylistArrayForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.O And e.Control Then
Using f As New PlayListParserForm With {.DesignXML = DesignXML}
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then TXT_URLS.Text = f.PlayLists.ListToString(vbNewLine, EDP.ReturnValue)
End Using
e.Handled = True
End If
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,132 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Controls
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class VideoOption : Inherits System.Windows.Forms.UserControl
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Me.OPT_CHECKED = New System.Windows.Forms.RadioButton()
Me.LBL_DEFINITION_INFO = New System.Windows.Forms.Label()
Me.LBL_DEFINITION = New System.Windows.Forms.Label()
Me.LBL_CODECS = New System.Windows.Forms.Label()
Me.LBL_SIZE = New System.Windows.Forms.Label()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_MAIN.SuspendLayout()
Me.SuspendLayout()
'
'TP_MAIN
'
TP_MAIN.ColumnCount = 5
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 36.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 110.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 58.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 71.0!))
TP_MAIN.Controls.Add(Me.OPT_CHECKED, 0, 0)
TP_MAIN.Controls.Add(Me.LBL_DEFINITION_INFO, 1, 0)
TP_MAIN.Controls.Add(Me.LBL_DEFINITION, 2, 0)
TP_MAIN.Controls.Add(Me.LBL_CODECS, 3, 0)
TP_MAIN.Controls.Add(Me.LBL_SIZE, 4, 0)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 1
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Size = New System.Drawing.Size(459, 30)
TP_MAIN.TabIndex = 0
'
'OPT_CHECKED
'
Me.OPT_CHECKED.AutoSize = True
Me.OPT_CHECKED.CheckAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.OPT_CHECKED.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_CHECKED.Location = New System.Drawing.Point(3, 3)
Me.OPT_CHECKED.Name = "OPT_CHECKED"
Me.OPT_CHECKED.Size = New System.Drawing.Size(30, 24)
Me.OPT_CHECKED.TabIndex = 0
Me.OPT_CHECKED.TabStop = True
Me.OPT_CHECKED.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
Me.OPT_CHECKED.UseVisualStyleBackColor = True
'
'LBL_DEFINITION_INFO
'
Me.LBL_DEFINITION_INFO.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_DEFINITION_INFO.Font = New System.Drawing.Font("Arial", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_DEFINITION_INFO.Location = New System.Drawing.Point(39, 0)
Me.LBL_DEFINITION_INFO.Name = "LBL_DEFINITION_INFO"
Me.LBL_DEFINITION_INFO.Size = New System.Drawing.Size(104, 30)
Me.LBL_DEFINITION_INFO.TabIndex = 1
Me.LBL_DEFINITION_INFO.Text = "Ultra High Definition"
Me.LBL_DEFINITION_INFO.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'LBL_DEFINITION
'
Me.LBL_DEFINITION.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_DEFINITION.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_DEFINITION.Location = New System.Drawing.Point(149, 0)
Me.LBL_DEFINITION.Name = "LBL_DEFINITION"
Me.LBL_DEFINITION.Size = New System.Drawing.Size(52, 30)
Me.LBL_DEFINITION.TabIndex = 2
Me.LBL_DEFINITION.Text = "1080p"
Me.LBL_DEFINITION.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'LBL_CODECS
'
Me.LBL_CODECS.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_CODECS.Font = New System.Drawing.Font("Arial", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_CODECS.Location = New System.Drawing.Point(207, 0)
Me.LBL_CODECS.Name = "LBL_CODECS"
Me.LBL_CODECS.Size = New System.Drawing.Size(178, 30)
Me.LBL_CODECS.TabIndex = 3
Me.LBL_CODECS.Text = "MKV - VP9 - Opus"
Me.LBL_CODECS.TextAlign = System.Drawing.ContentAlignment.MiddleRight
'
'LBL_SIZE
'
Me.LBL_SIZE.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_SIZE.Font = New System.Drawing.Font("Arial", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_SIZE.Location = New System.Drawing.Point(391, 0)
Me.LBL_SIZE.Name = "LBL_SIZE"
Me.LBL_SIZE.Size = New System.Drawing.Size(65, 30)
Me.LBL_SIZE.TabIndex = 4
Me.LBL_SIZE.Text = "1 062 MB"
Me.LBL_SIZE.TextAlign = System.Drawing.ContentAlignment.MiddleRight
'
'VideoOption
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(TP_MAIN)
Me.Name = "VideoOption"
Me.Size = New System.Drawing.Size(459, 30)
TP_MAIN.ResumeLayout(False)
TP_MAIN.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents OPT_CHECKED As RadioButton
Private WithEvents LBL_DEFINITION_INFO As Label
Private WithEvents LBL_DEFINITION As Label
Private WithEvents LBL_CODECS As Label
Private WithEvents LBL_SIZE As Label
End Class
End Namespace

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View File

@@ -0,0 +1,87 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports SCrawler.API.YouTube.Base
Namespace API.YouTube.Controls
<DefaultEvent("CheckedChanged"), DesignTimeVisible(False), ToolboxItem(False)>
Friend Class VideoOption : Implements ISupportInitialize
Friend Event CheckedChanged As EventHandler
<Browsable(False)> Friend Property MyMedia As MediaObject
<Browsable(False)> Friend Property Checked As Boolean
Get
Return OPT_CHECKED.Checked
End Get
Set(ByVal _Checked As Boolean)
OPT_CHECKED.Checked = _Checked
End Set
End Property
Friend Sub New()
InitializeComponent()
End Sub
Friend Sub New(ByVal m As MediaObject, Optional ByVal SelectedAudio As MediaObject = Nothing)
Me.New
Const d$ = " " & ChrW(183) & " "
MyMedia = m
If m.Type = Plugin.UserMediaTypes.Audio Then
If m.Bitrate >= 320 Then
LBL_DEFINITION_INFO.Text = "High Quality"
ElseIf m.Bitrate >= 190 Then
LBL_DEFINITION_INFO.Text = "Medium Quality"
Else
LBL_DEFINITION_INFO.Text = "Low Quality"
End If
LBL_DEFINITION.Text = $"{m.Bitrate}k"
LBL_CODECS.Text = $"{m.Extension} {d} {m.Codec} {d} {m.Bitrate}k"
Else
If m.Height >= 1440 Then
LBL_DEFINITION_INFO.Text = "Ultra High Definition"
ElseIf m.Height >= 720 Then
LBL_DEFINITION_INFO.Text = "High Definition"
ElseIf m.Height >= 480 Then
LBL_DEFINITION_INFO.Text = "Medium Definition"
ElseIf m.Height >= 360 Then
LBL_DEFINITION_INFO.Text = "Normal Definition"
Else
LBL_DEFINITION_INFO.Text = "Low Definition"
End If
LBL_DEFINITION.Text = $"{m.Height}p"
LBL_CODECS.Text = $"{m.Extension.StringToUpper}{d}{m.Codec.StringToUpper}{d}{m.FPS}fps{d}{m.Bitrate}k"
If Not SelectedAudio.ID.IsEmptyString Then LBL_CODECS.Text &= $" / {SelectedAudio.Extension}{d}{SelectedAudio.Codec}{d}{SelectedAudio.Bitrate}k"
End If
Dim sv% = m.Size / 1024
If sv >= 1000 Then
LBL_SIZE.Text = AConvert(Of String)(sv / 1024, VideoSizeProvider)
LBL_SIZE.Text &= " GB"
Else
LBL_SIZE.Text = AConvert(Of String)(sv, VideoSizeProvider)
LBL_SIZE.Text &= " MB"
End If
End Sub
Private Sub OPT_CHECKED_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_CHECKED.CheckedChanged
RaiseEvent CheckedChanged(Me, e)
End Sub
Private Sub Labels_Click(sender As Object, e As EventArgs) Handles LBL_DEFINITION_INFO.Click, LBL_DEFINITION.Click, LBL_CODECS.Click, LBL_SIZE.Click
OPT_CHECKED.Checked = True
End Sub
Private Sub BindedControl_CheckedChanged(sender As Object, e As EventArgs)
If Not sender Is Nothing AndAlso Not sender Is Me AndAlso DirectCast(sender, VideoOption).Checked Then Checked = False
End Sub
Private Sub BeginInit() Implements ISupportInitialize.BeginInit
End Sub
Private Sub EndInit() Implements ISupportInitialize.EndInit
If Not Parent Is Nothing AndAlso Parent.Controls.Count > 0 Then
For Each cnt As Control In Parent.Controls
If TypeOf cnt Is VideoOption And Not cnt Is Me Then _
AddHandler DirectCast(cnt, VideoOption).CheckedChanged, AddressOf BindedControl_CheckedChanged
Next
End If
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,749 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace API.YouTube.Controls
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Friend Class VideoOptionsForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim TP_HEADER As System.Windows.Forms.TableLayoutPanel
Dim TP_HEADER_INFO As System.Windows.Forms.TableLayoutPanel
Dim ICON_CLOCK As System.Windows.Forms.PictureBox
Dim ICON_LINK As System.Windows.Forms.PictureBox
Dim TP_FOOTER As System.Windows.Forms.TableLayoutPanel
Dim TP_DESTINATION As System.Windows.Forms.TableLayoutPanel
Dim TP_OK_CANCEL As System.Windows.Forms.TableLayoutPanel
Dim LB_SEP_1 As System.Windows.Forms.Label
Dim LB_SEP_2 As System.Windows.Forms.Label
Dim TP_WHAT As System.Windows.Forms.TableLayoutPanel
Dim LBL_WHAT As System.Windows.Forms.Label
Dim LBL_FORMAT As System.Windows.Forms.Label
Dim LBL_SUBS_FORMAT As System.Windows.Forms.Label
Dim TT_MAIN As System.Windows.Forms.ToolTip
Dim ActionButton1 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(VideoOptionsForm))
Dim ActionButton2 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton3 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton4 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton5 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton6 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton7 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton8 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Dim ActionButton9 As PersonalUtilities.Forms.Controls.Base.ActionButton = New PersonalUtilities.Forms.Controls.Base.ActionButton()
Me.ICON_VIDEO = New System.Windows.Forms.PictureBox()
Me.LBL_TITLE = New System.Windows.Forms.Label()
Me.TP_HEADER_INFO_2 = New System.Windows.Forms.TableLayoutPanel()
Me.LBL_TIME = New System.Windows.Forms.Label()
Me.LBL_URL = New System.Windows.Forms.LinkLabel()
Me.TXT_FILE = New System.Windows.Forms.TextBox()
Me.BTT_BROWSE = New System.Windows.Forms.Button()
Me.BTT_DOWN = New System.Windows.Forms.Button()
Me.BTT_CANCEL = New System.Windows.Forms.Button()
Me.OPT_VIDEO = New System.Windows.Forms.RadioButton()
Me.OPT_AUDIO = New System.Windows.Forms.RadioButton()
Me.LBL_AUDIO_CODEC = New System.Windows.Forms.Label()
Me.TP_HEADER_BASE = New System.Windows.Forms.TableLayoutPanel()
Me.TP_SUBS = New System.Windows.Forms.TableLayoutPanel()
Me.TXT_SUBS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.CMB_SUBS_FORMAT = New System.Windows.Forms.ComboBox()
Me.TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
Me.TP_OPTIONS = New System.Windows.Forms.TableLayoutPanel()
Me.CMB_FORMAT = New System.Windows.Forms.ComboBox()
Me.CMB_AUDIO_CODEC = New System.Windows.Forms.ComboBox()
Me.NUM_RES = New System.Windows.Forms.NumericUpDown()
Me.TP_CONTROLS = New System.Windows.Forms.TableLayoutPanel()
Me.TXT_SUBS_ADDIT = New PersonalUtilities.Forms.Controls.TextBoxExtended()
Me.TXT_EXTRA_AUDIO_FORMATS = New PersonalUtilities.Forms.Controls.TextBoxExtended()
TP_HEADER = New System.Windows.Forms.TableLayoutPanel()
TP_HEADER_INFO = New System.Windows.Forms.TableLayoutPanel()
ICON_CLOCK = New System.Windows.Forms.PictureBox()
ICON_LINK = New System.Windows.Forms.PictureBox()
TP_FOOTER = New System.Windows.Forms.TableLayoutPanel()
TP_DESTINATION = New System.Windows.Forms.TableLayoutPanel()
TP_OK_CANCEL = New System.Windows.Forms.TableLayoutPanel()
LB_SEP_1 = New System.Windows.Forms.Label()
LB_SEP_2 = New System.Windows.Forms.Label()
TP_WHAT = New System.Windows.Forms.TableLayoutPanel()
LBL_WHAT = New System.Windows.Forms.Label()
LBL_FORMAT = New System.Windows.Forms.Label()
LBL_SUBS_FORMAT = New System.Windows.Forms.Label()
TT_MAIN = New System.Windows.Forms.ToolTip(Me.components)
TP_HEADER.SuspendLayout()
CType(Me.ICON_VIDEO, System.ComponentModel.ISupportInitialize).BeginInit()
TP_HEADER_INFO.SuspendLayout()
Me.TP_HEADER_INFO_2.SuspendLayout()
CType(ICON_CLOCK, System.ComponentModel.ISupportInitialize).BeginInit()
CType(ICON_LINK, System.ComponentModel.ISupportInitialize).BeginInit()
TP_FOOTER.SuspendLayout()
TP_DESTINATION.SuspendLayout()
TP_OK_CANCEL.SuspendLayout()
TP_WHAT.SuspendLayout()
Me.TP_HEADER_BASE.SuspendLayout()
Me.TP_SUBS.SuspendLayout()
CType(Me.TXT_SUBS, System.ComponentModel.ISupportInitialize).BeginInit()
Me.TP_MAIN.SuspendLayout()
Me.TP_OPTIONS.SuspendLayout()
CType(Me.NUM_RES, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_SUBS_ADDIT, System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.TXT_EXTRA_AUDIO_FORMATS, System.ComponentModel.ISupportInitialize).BeginInit()
Me.SuspendLayout()
'
'TP_HEADER
'
TP_HEADER.BackColor = System.Drawing.SystemColors.Window
TP_HEADER.ColumnCount = 2
TP_HEADER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 130.0!))
TP_HEADER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_HEADER.Controls.Add(Me.ICON_VIDEO, 0, 0)
TP_HEADER.Controls.Add(TP_HEADER_INFO, 1, 0)
TP_HEADER.Dock = System.Windows.Forms.DockStyle.Fill
TP_HEADER.Location = New System.Drawing.Point(1, 1)
TP_HEADER.Margin = New System.Windows.Forms.Padding(0)
TP_HEADER.Name = "TP_HEADER"
TP_HEADER.RowCount = 1
TP_HEADER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_HEADER.Size = New System.Drawing.Size(599, 63)
TP_HEADER.TabIndex = 0
'
'ICON_VIDEO
'
Me.ICON_VIDEO.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
Me.ICON_VIDEO.Dock = System.Windows.Forms.DockStyle.Fill
Me.ICON_VIDEO.Location = New System.Drawing.Point(1, 1)
Me.ICON_VIDEO.Margin = New System.Windows.Forms.Padding(1)
Me.ICON_VIDEO.Name = "ICON_VIDEO"
Me.ICON_VIDEO.Size = New System.Drawing.Size(128, 61)
Me.ICON_VIDEO.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom
Me.ICON_VIDEO.TabIndex = 0
Me.ICON_VIDEO.TabStop = False
'
'TP_HEADER_INFO
'
TP_HEADER_INFO.ColumnCount = 1
TP_HEADER_INFO.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_HEADER_INFO.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_HEADER_INFO.Controls.Add(Me.LBL_TITLE, 0, 0)
TP_HEADER_INFO.Controls.Add(Me.TP_HEADER_INFO_2, 0, 1)
TP_HEADER_INFO.Dock = System.Windows.Forms.DockStyle.Fill
TP_HEADER_INFO.Location = New System.Drawing.Point(130, 0)
TP_HEADER_INFO.Margin = New System.Windows.Forms.Padding(0)
TP_HEADER_INFO.Name = "TP_HEADER_INFO"
TP_HEADER_INFO.RowCount = 2
TP_HEADER_INFO.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_HEADER_INFO.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_HEADER_INFO.Size = New System.Drawing.Size(469, 63)
TP_HEADER_INFO.TabIndex = 0
'
'LBL_TITLE
'
Me.LBL_TITLE.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_TITLE.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_TITLE.Location = New System.Drawing.Point(3, 0)
Me.LBL_TITLE.Name = "LBL_TITLE"
Me.LBL_TITLE.Size = New System.Drawing.Size(463, 31)
Me.LBL_TITLE.TabIndex = 0
Me.LBL_TITLE.Text = "Video title"
Me.LBL_TITLE.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'TP_HEADER_INFO_2
'
Me.TP_HEADER_INFO_2.ColumnCount = 4
Me.TP_HEADER_INFO_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.TP_HEADER_INFO_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 62.0!))
Me.TP_HEADER_INFO_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.TP_HEADER_INFO_2.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_HEADER_INFO_2.Controls.Add(ICON_CLOCK, 0, 0)
Me.TP_HEADER_INFO_2.Controls.Add(Me.LBL_TIME, 1, 0)
Me.TP_HEADER_INFO_2.Controls.Add(ICON_LINK, 2, 0)
Me.TP_HEADER_INFO_2.Controls.Add(Me.LBL_URL, 3, 0)
Me.TP_HEADER_INFO_2.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_HEADER_INFO_2.Location = New System.Drawing.Point(0, 31)
Me.TP_HEADER_INFO_2.Margin = New System.Windows.Forms.Padding(0)
Me.TP_HEADER_INFO_2.Name = "TP_HEADER_INFO_2"
Me.TP_HEADER_INFO_2.RowCount = 1
Me.TP_HEADER_INFO_2.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_HEADER_INFO_2.Size = New System.Drawing.Size(469, 32)
Me.TP_HEADER_INFO_2.TabIndex = 1
'
'ICON_CLOCK
'
ICON_CLOCK.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
ICON_CLOCK.Dock = System.Windows.Forms.DockStyle.Fill
ICON_CLOCK.Image = Global.SCrawler.My.Resources.Resources.ClockPic_16
ICON_CLOCK.Location = New System.Drawing.Point(3, 3)
ICON_CLOCK.Name = "ICON_CLOCK"
ICON_CLOCK.Size = New System.Drawing.Size(19, 26)
ICON_CLOCK.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom
ICON_CLOCK.TabIndex = 0
ICON_CLOCK.TabStop = False
'
'LBL_TIME
'
Me.LBL_TIME.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_TIME.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_TIME.ForeColor = System.Drawing.SystemColors.ControlDarkDark
Me.LBL_TIME.Location = New System.Drawing.Point(28, 0)
Me.LBL_TIME.Name = "LBL_TIME"
Me.LBL_TIME.Size = New System.Drawing.Size(56, 32)
Me.LBL_TIME.TabIndex = 0
Me.LBL_TIME.Text = "00:00:00"
Me.LBL_TIME.TextAlign = System.Drawing.ContentAlignment.MiddleCenter
'
'ICON_LINK
'
ICON_LINK.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
ICON_LINK.Dock = System.Windows.Forms.DockStyle.Fill
ICON_LINK.Image = Global.SCrawler.My.Resources.Resources.LinkPic_32
ICON_LINK.Location = New System.Drawing.Point(90, 3)
ICON_LINK.Name = "ICON_LINK"
ICON_LINK.Size = New System.Drawing.Size(19, 26)
ICON_LINK.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom
ICON_LINK.TabIndex = 2
ICON_LINK.TabStop = False
'
'LBL_URL
'
Me.LBL_URL.AutoSize = True
Me.LBL_URL.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_URL.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_URL.LinkColor = System.Drawing.Color.FromArgb(CType(CType(0, Byte), Integer), CType(CType(0, Byte), Integer), CType(CType(192, Byte), Integer))
Me.LBL_URL.Location = New System.Drawing.Point(115, 0)
Me.LBL_URL.Name = "LBL_URL"
Me.LBL_URL.Size = New System.Drawing.Size(351, 32)
Me.LBL_URL.TabIndex = 1
Me.LBL_URL.TabStop = True
Me.LBL_URL.Text = "https://www.youtube.com/watch?v=abcdefghijk"
Me.LBL_URL.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'TP_FOOTER
'
TP_FOOTER.ColumnCount = 1
TP_FOOTER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_FOOTER.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
TP_FOOTER.Controls.Add(TP_DESTINATION, 0, 0)
TP_FOOTER.Controls.Add(TP_OK_CANCEL, 0, 1)
TP_FOOTER.Dock = System.Windows.Forms.DockStyle.Fill
TP_FOOTER.Location = New System.Drawing.Point(6, 215)
TP_FOOTER.Margin = New System.Windows.Forms.Padding(6, 3, 6, 3)
TP_FOOTER.Name = "TP_FOOTER"
TP_FOOTER.RowCount = 2
TP_FOOTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_FOOTER.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_FOOTER.Size = New System.Drawing.Size(589, 52)
TP_FOOTER.TabIndex = 5
'
'TP_DESTINATION
'
TP_DESTINATION.ColumnCount = 2
TP_DESTINATION.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DESTINATION.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
TP_DESTINATION.Controls.Add(Me.TXT_FILE, 0, 0)
TP_DESTINATION.Controls.Add(Me.BTT_BROWSE, 1, 0)
TP_DESTINATION.Dock = System.Windows.Forms.DockStyle.Fill
TP_DESTINATION.Location = New System.Drawing.Point(0, 0)
TP_DESTINATION.Margin = New System.Windows.Forms.Padding(0)
TP_DESTINATION.Name = "TP_DESTINATION"
TP_DESTINATION.RowCount = 1
TP_DESTINATION.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_DESTINATION.Size = New System.Drawing.Size(589, 26)
TP_DESTINATION.TabIndex = 0
'
'TXT_FILE
'
Me.TXT_FILE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_FILE.Location = New System.Drawing.Point(3, 3)
Me.TXT_FILE.Name = "TXT_FILE"
Me.TXT_FILE.Size = New System.Drawing.Size(503, 20)
Me.TXT_FILE.TabIndex = 0
Me.TXT_FILE.WordWrap = False
'
'BTT_BROWSE
'
Me.BTT_BROWSE.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_BROWSE.Location = New System.Drawing.Point(512, 2)
Me.BTT_BROWSE.Margin = New System.Windows.Forms.Padding(3, 2, 3, 2)
Me.BTT_BROWSE.Name = "BTT_BROWSE"
Me.BTT_BROWSE.Size = New System.Drawing.Size(74, 22)
Me.BTT_BROWSE.TabIndex = 1
Me.BTT_BROWSE.Text = "Browse"
TT_MAIN.SetToolTip(Me.BTT_BROWSE, "Choose an output file")
Me.BTT_BROWSE.UseVisualStyleBackColor = True
'
'TP_OK_CANCEL
'
TP_OK_CANCEL.ColumnCount = 3
TP_OK_CANCEL.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_OK_CANCEL.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
TP_OK_CANCEL.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
TP_OK_CANCEL.Controls.Add(Me.BTT_DOWN, 1, 0)
TP_OK_CANCEL.Controls.Add(Me.BTT_CANCEL, 2, 0)
TP_OK_CANCEL.Dock = System.Windows.Forms.DockStyle.Fill
TP_OK_CANCEL.Location = New System.Drawing.Point(0, 26)
TP_OK_CANCEL.Margin = New System.Windows.Forms.Padding(0)
TP_OK_CANCEL.Name = "TP_OK_CANCEL"
TP_OK_CANCEL.RowCount = 1
TP_OK_CANCEL.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_OK_CANCEL.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 26.0!))
TP_OK_CANCEL.Size = New System.Drawing.Size(589, 26)
TP_OK_CANCEL.TabIndex = 1
'
'BTT_DOWN
'
Me.BTT_DOWN.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_DOWN.Location = New System.Drawing.Point(432, 2)
Me.BTT_DOWN.Margin = New System.Windows.Forms.Padding(3, 2, 3, 2)
Me.BTT_DOWN.Name = "BTT_DOWN"
Me.BTT_DOWN.Size = New System.Drawing.Size(74, 22)
Me.BTT_DOWN.TabIndex = 0
Me.BTT_DOWN.Text = "Download"
Me.BTT_DOWN.UseVisualStyleBackColor = True
'
'BTT_CANCEL
'
Me.BTT_CANCEL.DialogResult = System.Windows.Forms.DialogResult.Cancel
Me.BTT_CANCEL.Dock = System.Windows.Forms.DockStyle.Fill
Me.BTT_CANCEL.Location = New System.Drawing.Point(512, 2)
Me.BTT_CANCEL.Margin = New System.Windows.Forms.Padding(3, 2, 3, 2)
Me.BTT_CANCEL.Name = "BTT_CANCEL"
Me.BTT_CANCEL.Size = New System.Drawing.Size(74, 22)
Me.BTT_CANCEL.TabIndex = 1
Me.BTT_CANCEL.Text = "Cancel"
Me.BTT_CANCEL.UseVisualStyleBackColor = True
'
'LB_SEP_1
'
LB_SEP_1.Anchor = CType((System.Windows.Forms.AnchorStyles.Left Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
LB_SEP_1.BackColor = System.Drawing.SystemColors.ControlDark
LB_SEP_1.Location = New System.Drawing.Point(6, 179)
LB_SEP_1.Margin = New System.Windows.Forms.Padding(6, 0, 6, 0)
LB_SEP_1.Name = "LB_SEP_1"
LB_SEP_1.Size = New System.Drawing.Size(589, 1)
LB_SEP_1.TabIndex = 3
'
'LB_SEP_2
'
LB_SEP_2.Anchor = CType((System.Windows.Forms.AnchorStyles.Left Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
LB_SEP_2.BackColor = System.Drawing.SystemColors.ControlDark
LB_SEP_2.Location = New System.Drawing.Point(6, 209)
LB_SEP_2.Margin = New System.Windows.Forms.Padding(6, 0, 6, 0)
LB_SEP_2.Name = "LB_SEP_2"
LB_SEP_2.Size = New System.Drawing.Size(589, 1)
LB_SEP_2.TabIndex = 5
'
'TP_WHAT
'
TP_WHAT.ColumnCount = 3
TP_WHAT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 65.0!))
TP_WHAT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_WHAT.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
TP_WHAT.Controls.Add(LBL_WHAT, 0, 0)
TP_WHAT.Controls.Add(Me.OPT_VIDEO, 1, 0)
TP_WHAT.Controls.Add(Me.OPT_AUDIO, 2, 0)
TP_WHAT.Dock = System.Windows.Forms.DockStyle.Fill
TP_WHAT.Location = New System.Drawing.Point(0, 0)
TP_WHAT.Margin = New System.Windows.Forms.Padding(0)
TP_WHAT.Name = "TP_WHAT"
TP_WHAT.RowCount = 1
TP_WHAT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_WHAT.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
TP_WHAT.Size = New System.Drawing.Size(189, 28)
TP_WHAT.TabIndex = 0
'
'LBL_WHAT
'
LBL_WHAT.AutoSize = True
LBL_WHAT.Dock = System.Windows.Forms.DockStyle.Fill
LBL_WHAT.Location = New System.Drawing.Point(3, 0)
LBL_WHAT.Name = "LBL_WHAT"
LBL_WHAT.Size = New System.Drawing.Size(59, 28)
LBL_WHAT.TabIndex = 4
LBL_WHAT.Text = "Download"
LBL_WHAT.TextAlign = System.Drawing.ContentAlignment.MiddleRight
'
'OPT_VIDEO
'
Me.OPT_VIDEO.AutoSize = True
Me.OPT_VIDEO.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_VIDEO.Location = New System.Drawing.Point(68, 3)
Me.OPT_VIDEO.Name = "OPT_VIDEO"
Me.OPT_VIDEO.Size = New System.Drawing.Size(56, 22)
Me.OPT_VIDEO.TabIndex = 0
Me.OPT_VIDEO.TabStop = True
Me.OPT_VIDEO.Text = "Video"
Me.OPT_VIDEO.UseVisualStyleBackColor = True
'
'OPT_AUDIO
'
Me.OPT_AUDIO.AutoSize = True
Me.OPT_AUDIO.Dock = System.Windows.Forms.DockStyle.Fill
Me.OPT_AUDIO.Location = New System.Drawing.Point(130, 3)
Me.OPT_AUDIO.Name = "OPT_AUDIO"
Me.OPT_AUDIO.Size = New System.Drawing.Size(56, 22)
Me.OPT_AUDIO.TabIndex = 1
Me.OPT_AUDIO.TabStop = True
Me.OPT_AUDIO.Text = "Audio"
Me.OPT_AUDIO.UseVisualStyleBackColor = True
'
'LBL_FORMAT
'
LBL_FORMAT.Dock = System.Windows.Forms.DockStyle.Fill
LBL_FORMAT.Location = New System.Drawing.Point(192, 0)
LBL_FORMAT.Name = "LBL_FORMAT"
LBL_FORMAT.Size = New System.Drawing.Size(74, 28)
LBL_FORMAT.TabIndex = 4
LBL_FORMAT.Text = "Format:"
LBL_FORMAT.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(LBL_FORMAT, "Output Video Format")
'
'LBL_SUBS_FORMAT
'
LBL_SUBS_FORMAT.AutoSize = True
LBL_SUBS_FORMAT.Dock = System.Windows.Forms.DockStyle.Fill
LBL_SUBS_FORMAT.Location = New System.Drawing.Point(432, 0)
LBL_SUBS_FORMAT.Name = "LBL_SUBS_FORMAT"
LBL_SUBS_FORMAT.Size = New System.Drawing.Size(74, 28)
LBL_SUBS_FORMAT.TabIndex = 2
LBL_SUBS_FORMAT.Text = "Format:"
LBL_SUBS_FORMAT.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(LBL_SUBS_FORMAT, "Output Subtitles Format")
'
'LBL_AUDIO_CODEC
'
Me.LBL_AUDIO_CODEC.AutoSize = True
Me.LBL_AUDIO_CODEC.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_AUDIO_CODEC.Location = New System.Drawing.Point(432, 0)
Me.LBL_AUDIO_CODEC.Name = "LBL_AUDIO_CODEC"
Me.LBL_AUDIO_CODEC.Size = New System.Drawing.Size(74, 28)
Me.LBL_AUDIO_CODEC.TabIndex = 5
Me.LBL_AUDIO_CODEC.Text = "Audio Codec"
Me.LBL_AUDIO_CODEC.TextAlign = System.Drawing.ContentAlignment.MiddleRight
TT_MAIN.SetToolTip(Me.LBL_AUDIO_CODEC, "Output Audio Codec")
'
'TP_HEADER_BASE
'
Me.TP_HEADER_BASE.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.[Single]
Me.TP_HEADER_BASE.ColumnCount = 1
Me.TP_HEADER_BASE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_HEADER_BASE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
Me.TP_HEADER_BASE.Controls.Add(TP_HEADER, 0, 0)
Me.TP_HEADER_BASE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_HEADER_BASE.Location = New System.Drawing.Point(0, 0)
Me.TP_HEADER_BASE.Margin = New System.Windows.Forms.Padding(0)
Me.TP_HEADER_BASE.Name = "TP_HEADER_BASE"
Me.TP_HEADER_BASE.RowCount = 1
Me.TP_HEADER_BASE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_HEADER_BASE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 64.0!))
Me.TP_HEADER_BASE.Size = New System.Drawing.Size(601, 65)
Me.TP_HEADER_BASE.TabIndex = 6
'
'TP_SUBS
'
Me.TP_SUBS.ColumnCount = 3
Me.TP_SUBS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_SUBS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_SUBS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_SUBS.Controls.Add(Me.TXT_SUBS, 0, 0)
Me.TP_SUBS.Controls.Add(LBL_SUBS_FORMAT, 1, 0)
Me.TP_SUBS.Controls.Add(Me.CMB_SUBS_FORMAT, 2, 0)
Me.TP_SUBS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_SUBS.Location = New System.Drawing.Point(6, 93)
Me.TP_SUBS.Margin = New System.Windows.Forms.Padding(6, 0, 6, 0)
Me.TP_SUBS.Name = "TP_SUBS"
Me.TP_SUBS.RowCount = 1
Me.TP_SUBS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_SUBS.Size = New System.Drawing.Size(589, 28)
Me.TP_SUBS.TabIndex = 2
'
'TXT_SUBS
'
ActionButton1.BackgroundImage = CType(resources.GetObject("ActionButton1.BackgroundImage"), System.Drawing.Image)
ActionButton1.Name = "Open"
ActionButton1.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton1.ToolTipText = "Choose subtitles"
ActionButton2.BackgroundImage = CType(resources.GetObject("ActionButton2.BackgroundImage"), System.Drawing.Image)
ActionButton2.Name = "Refresh"
ActionButton2.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton2.ToolTipText = "Reset subtitles to initial selected"
ActionButton3.BackgroundImage = CType(resources.GetObject("ActionButton3.BackgroundImage"), System.Drawing.Image)
ActionButton3.Name = "Clear"
ActionButton3.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton3.ToolTipText = "Clear subtitles selection (don't download subtitles)"
Me.TXT_SUBS.Buttons.Add(ActionButton1)
Me.TXT_SUBS.Buttons.Add(ActionButton2)
Me.TXT_SUBS.Buttons.Add(ActionButton3)
Me.TXT_SUBS.CaptionText = "Subtitles"
Me.TXT_SUBS.CaptionToolTipEnabled = True
Me.TXT_SUBS.CaptionToolTipText = "The selected subtitles will also be downloaded"
Me.TXT_SUBS.CaptionWidth = 60.0R
Me.TXT_SUBS.ClearTextByButtonClear = False
Me.TXT_SUBS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SUBS.Location = New System.Drawing.Point(3, 3)
Me.TXT_SUBS.Name = "TXT_SUBS"
Me.TXT_SUBS.Size = New System.Drawing.Size(423, 22)
Me.TXT_SUBS.TabIndex = 0
Me.TXT_SUBS.TextBoxReadOnly = True
'
'CMB_SUBS_FORMAT
'
Me.CMB_SUBS_FORMAT.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_SUBS_FORMAT.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.CMB_SUBS_FORMAT.FormattingEnabled = True
Me.CMB_SUBS_FORMAT.Location = New System.Drawing.Point(512, 3)
Me.CMB_SUBS_FORMAT.Name = "CMB_SUBS_FORMAT"
Me.CMB_SUBS_FORMAT.Size = New System.Drawing.Size(74, 21)
Me.CMB_SUBS_FORMAT.TabIndex = 1
'
'TP_MAIN
'
Me.TP_MAIN.ColumnCount = 1
Me.TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_MAIN.Controls.Add(Me.TP_HEADER_BASE, 0, 0)
Me.TP_MAIN.Controls.Add(TP_FOOTER, 0, 8)
Me.TP_MAIN.Controls.Add(Me.TP_OPTIONS, 0, 1)
Me.TP_MAIN.Controls.Add(Me.TP_CONTROLS, 0, 6)
Me.TP_MAIN.Controls.Add(LB_SEP_1, 0, 5)
Me.TP_MAIN.Controls.Add(LB_SEP_2, 0, 7)
Me.TP_MAIN.Controls.Add(Me.TP_SUBS, 0, 2)
Me.TP_MAIN.Controls.Add(Me.TXT_SUBS_ADDIT, 0, 3)
Me.TP_MAIN.Controls.Add(Me.TXT_EXTRA_AUDIO_FORMATS, 0, 4)
Me.TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_MAIN.Location = New System.Drawing.Point(0, 0)
Me.TP_MAIN.Name = "TP_MAIN"
Me.TP_MAIN.RowCount = 10
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 65.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 28.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 5.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 25.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 5.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 58.0!))
Me.TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TP_MAIN.Size = New System.Drawing.Size(601, 271)
Me.TP_MAIN.TabIndex = 0
'
'TP_OPTIONS
'
Me.TP_OPTIONS.ColumnCount = 6
Me.TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_OPTIONS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80.0!))
Me.TP_OPTIONS.Controls.Add(LBL_FORMAT, 1, 0)
Me.TP_OPTIONS.Controls.Add(TP_WHAT, 0, 0)
Me.TP_OPTIONS.Controls.Add(Me.CMB_FORMAT, 2, 0)
Me.TP_OPTIONS.Controls.Add(Me.LBL_AUDIO_CODEC, 4, 0)
Me.TP_OPTIONS.Controls.Add(Me.CMB_AUDIO_CODEC, 5, 0)
Me.TP_OPTIONS.Controls.Add(Me.NUM_RES, 3, 0)
Me.TP_OPTIONS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_OPTIONS.Location = New System.Drawing.Point(6, 65)
Me.TP_OPTIONS.Margin = New System.Windows.Forms.Padding(6, 0, 6, 0)
Me.TP_OPTIONS.Name = "TP_OPTIONS"
Me.TP_OPTIONS.RowCount = 1
Me.TP_OPTIONS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_OPTIONS.Size = New System.Drawing.Size(589, 28)
Me.TP_OPTIONS.TabIndex = 1
'
'CMB_FORMAT
'
Me.CMB_FORMAT.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_FORMAT.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.CMB_FORMAT.FormattingEnabled = True
Me.CMB_FORMAT.Location = New System.Drawing.Point(272, 3)
Me.CMB_FORMAT.Name = "CMB_FORMAT"
Me.CMB_FORMAT.Size = New System.Drawing.Size(74, 21)
Me.CMB_FORMAT.TabIndex = 1
'
'CMB_AUDIO_CODEC
'
Me.CMB_AUDIO_CODEC.Dock = System.Windows.Forms.DockStyle.Fill
Me.CMB_AUDIO_CODEC.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.CMB_AUDIO_CODEC.FormattingEnabled = True
Me.CMB_AUDIO_CODEC.Location = New System.Drawing.Point(512, 3)
Me.CMB_AUDIO_CODEC.Name = "CMB_AUDIO_CODEC"
Me.CMB_AUDIO_CODEC.Size = New System.Drawing.Size(74, 21)
Me.CMB_AUDIO_CODEC.TabIndex = 3
'
'NUM_RES
'
Me.NUM_RES.Dock = System.Windows.Forms.DockStyle.Fill
Me.NUM_RES.Location = New System.Drawing.Point(352, 3)
Me.NUM_RES.Maximum = New Decimal(New Integer() {10000, 0, 0, 0})
Me.NUM_RES.Minimum = New Decimal(New Integer() {1, 0, 0, -2147483648})
Me.NUM_RES.Name = "NUM_RES"
Me.NUM_RES.Size = New System.Drawing.Size(74, 20)
Me.NUM_RES.TabIndex = 2
Me.NUM_RES.TextAlign = System.Windows.Forms.HorizontalAlignment.Center
Me.NUM_RES.Value = New Decimal(New Integer() {1080, 0, 0, 0})
'
'TP_CONTROLS
'
Me.TP_CONTROLS.ColumnCount = 1
Me.TP_CONTROLS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_CONTROLS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_CONTROLS.Location = New System.Drawing.Point(3, 182)
Me.TP_CONTROLS.Margin = New System.Windows.Forms.Padding(3, 0, 3, 0)
Me.TP_CONTROLS.Name = "TP_CONTROLS"
Me.TP_CONTROLS.RowCount = 1
Me.TP_CONTROLS.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_CONTROLS.Size = New System.Drawing.Size(595, 25)
Me.TP_CONTROLS.TabIndex = 0
'
'TXT_SUBS_ADDIT
'
ActionButton4.BackgroundImage = CType(resources.GetObject("ActionButton4.BackgroundImage"), System.Drawing.Image)
ActionButton4.Enabled = False
ActionButton4.Name = "Open"
ActionButton4.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton4.ToolTipText = "Choose additional formats"
ActionButton5.BackgroundImage = CType(resources.GetObject("ActionButton5.BackgroundImage"), System.Drawing.Image)
ActionButton5.Enabled = False
ActionButton5.Name = "Refresh"
ActionButton5.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton5.ToolTipText = "Fill in additional formats from the defaults"
ActionButton6.BackgroundImage = CType(resources.GetObject("ActionButton6.BackgroundImage"), System.Drawing.Image)
ActionButton6.Enabled = False
ActionButton6.Name = "Clear"
ActionButton6.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton6.ToolTipText = "Remove all additional formats"
Me.TXT_SUBS_ADDIT.Buttons.Add(ActionButton4)
Me.TXT_SUBS_ADDIT.Buttons.Add(ActionButton5)
Me.TXT_SUBS_ADDIT.Buttons.Add(ActionButton6)
Me.TXT_SUBS_ADDIT.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_SUBS_ADDIT.CaptionText = "Additional subtitle formats"
Me.TXT_SUBS_ADDIT.CaptionToolTipEnabled = True
Me.TXT_SUBS_ADDIT.CaptionToolTipText = "Subtitles will be downloaded in 'SRT' format and converted to additional formats"
Me.TXT_SUBS_ADDIT.CaptionWidth = 150.0R
Me.TXT_SUBS_ADDIT.ClearTextByButtonClear = False
Me.TXT_SUBS_ADDIT.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_SUBS_ADDIT.Location = New System.Drawing.Point(6, 124)
Me.TXT_SUBS_ADDIT.Margin = New System.Windows.Forms.Padding(6, 3, 6, 3)
Me.TXT_SUBS_ADDIT.Name = "TXT_SUBS_ADDIT"
Me.TXT_SUBS_ADDIT.Size = New System.Drawing.Size(589, 22)
Me.TXT_SUBS_ADDIT.TabIndex = 3
Me.TXT_SUBS_ADDIT.Tag = "s"
Me.TXT_SUBS_ADDIT.TextBoxReadOnly = True
'
'TXT_EXTRA_AUDIO_FORMATS
'
ActionButton7.BackgroundImage = CType(resources.GetObject("ActionButton7.BackgroundImage"), System.Drawing.Image)
ActionButton7.Enabled = False
ActionButton7.Name = "Open"
ActionButton7.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Open
ActionButton7.ToolTipText = "Choose additional formats"
ActionButton8.BackgroundImage = CType(resources.GetObject("ActionButton8.BackgroundImage"), System.Drawing.Image)
ActionButton8.Enabled = False
ActionButton8.Name = "Refresh"
ActionButton8.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Refresh
ActionButton8.ToolTipText = "Fill in additional formats from the defaults"
ActionButton9.BackgroundImage = CType(resources.GetObject("ActionButton9.BackgroundImage"), System.Drawing.Image)
ActionButton9.Enabled = False
ActionButton9.Name = "Clear"
ActionButton9.Tag = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons.Clear
ActionButton9.ToolTipText = "Choose additional formats"
Me.TXT_EXTRA_AUDIO_FORMATS.Buttons.Add(ActionButton7)
Me.TXT_EXTRA_AUDIO_FORMATS.Buttons.Add(ActionButton8)
Me.TXT_EXTRA_AUDIO_FORMATS.Buttons.Add(ActionButton9)
Me.TXT_EXTRA_AUDIO_FORMATS.CaptionMode = PersonalUtilities.Forms.Controls.Base.ICaptionControl.Modes.CheckBox
Me.TXT_EXTRA_AUDIO_FORMATS.CaptionText = "Additional audio formats"
Me.TXT_EXTRA_AUDIO_FORMATS.CaptionToolTipEnabled = True
Me.TXT_EXTRA_AUDIO_FORMATS.CaptionWidth = 150.0R
Me.TXT_EXTRA_AUDIO_FORMATS.ClearTextByButtonClear = False
Me.TXT_EXTRA_AUDIO_FORMATS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TXT_EXTRA_AUDIO_FORMATS.Location = New System.Drawing.Point(6, 152)
Me.TXT_EXTRA_AUDIO_FORMATS.Margin = New System.Windows.Forms.Padding(6, 3, 6, 3)
Me.TXT_EXTRA_AUDIO_FORMATS.Name = "TXT_EXTRA_AUDIO_FORMATS"
Me.TXT_EXTRA_AUDIO_FORMATS.Size = New System.Drawing.Size(589, 22)
Me.TXT_EXTRA_AUDIO_FORMATS.TabIndex = 4
Me.TXT_EXTRA_AUDIO_FORMATS.Tag = "a"
Me.TXT_EXTRA_AUDIO_FORMATS.TextBoxReadOnly = True
'
'VideoOptionsForm
'
Me.AcceptButton = Me.BTT_DOWN
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.CancelButton = Me.BTT_CANCEL
Me.ClientSize = New System.Drawing.Size(601, 271)
Me.Controls.Add(Me.TP_MAIN)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeIcon_32
Me.KeyPreview = True
Me.MaximizeBox = False
Me.MinimizeBox = False
Me.Name = "VideoOptionsForm"
Me.ShowInTaskbar = False
Me.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide
Me.Text = "Download video"
TP_HEADER.ResumeLayout(False)
CType(Me.ICON_VIDEO, System.ComponentModel.ISupportInitialize).EndInit()
TP_HEADER_INFO.ResumeLayout(False)
Me.TP_HEADER_INFO_2.ResumeLayout(False)
Me.TP_HEADER_INFO_2.PerformLayout()
CType(ICON_CLOCK, System.ComponentModel.ISupportInitialize).EndInit()
CType(ICON_LINK, System.ComponentModel.ISupportInitialize).EndInit()
TP_FOOTER.ResumeLayout(False)
TP_DESTINATION.ResumeLayout(False)
TP_DESTINATION.PerformLayout()
TP_OK_CANCEL.ResumeLayout(False)
TP_WHAT.ResumeLayout(False)
TP_WHAT.PerformLayout()
Me.TP_HEADER_BASE.ResumeLayout(False)
Me.TP_SUBS.ResumeLayout(False)
Me.TP_SUBS.PerformLayout()
CType(Me.TXT_SUBS, System.ComponentModel.ISupportInitialize).EndInit()
Me.TP_MAIN.ResumeLayout(False)
Me.TP_OPTIONS.ResumeLayout(False)
Me.TP_OPTIONS.PerformLayout()
CType(Me.NUM_RES, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_SUBS_ADDIT, System.ComponentModel.ISupportInitialize).EndInit()
CType(Me.TXT_EXTRA_AUDIO_FORMATS, System.ComponentModel.ISupportInitialize).EndInit()
Me.ResumeLayout(False)
End Sub
Private WithEvents ICON_VIDEO As PictureBox
Private WithEvents LBL_TITLE As Label
Private WithEvents LBL_TIME As Label
Private WithEvents LBL_URL As LinkLabel
Private WithEvents TP_OPTIONS As TableLayoutPanel
Private WithEvents LBL_AUDIO_CODEC As Label
Private WithEvents TP_SUBS As TableLayoutPanel
Private WithEvents NUM_RES As NumericUpDown
Private WithEvents TP_HEADER_BASE As TableLayoutPanel
Private WithEvents TP_CONTROLS As TableLayoutPanel
Private WithEvents TP_MAIN As TableLayoutPanel
Private WithEvents CMB_AUDIO_CODEC As ComboBox
Private WithEvents OPT_VIDEO As RadioButton
Private WithEvents OPT_AUDIO As RadioButton
Private WithEvents CMB_FORMAT As ComboBox
Private WithEvents TXT_SUBS As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents CMB_SUBS_FORMAT As ComboBox
Private WithEvents TXT_SUBS_ADDIT As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_EXTRA_AUDIO_FORMATS As PersonalUtilities.Forms.Controls.TextBoxExtended
Private WithEvents TXT_FILE As TextBox
Private WithEvents BTT_BROWSE As Button
Private WithEvents BTT_DOWN As Button
Private WithEvents BTT_CANCEL As Button
Private WithEvents TP_HEADER_INFO_2 As TableLayoutPanel
End Class
End Namespace

View File

@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TP_HEADER.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_HEADER_INFO.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ICON_CLOCK.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="ICON_LINK.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_FOOTER.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_DESTINATION.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="TP_OK_CANCEL.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="LB_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="LB_SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TP_WHAT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="LBL_WHAT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="LBL_FORMAT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="LBL_SUBS_FORMAT.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="ActionButton1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton2.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton3.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton4.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton5.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton6.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
<data name="ActionButton7.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAR5JREFUOE+VkjFqwzAUhn2D9iShRyi+QhYbGujg3ZATZPKYdC6FQhPwlAMkg3dP
WQwhyWIyJIUW5NqyPb7oCVtIlhVTwYf8nv7/t2zJagel9KmqKsIACYL9RjI8UHz5zshougZr/AEvbxEP
aZCDBY3VslixaJvX3wzkkDiOwbZtDRGA5vdNAg+TL27qgmt5XkBG/gTdAG7Gt+3PP9oOaEGFCVEC6rp+
5g9MfM/c5e4OsEZMZkQEtGL5H2DdZ5JRArDwPA+iKII0TfkC9vroC9j5vq8JTWw3WzWgLMtZGIaa0MR8
vlAD8PYlSaIJTTiOowY0p0Bc19XEJo6HE59FAPuMzyAINKGJ1XLFZxHALtMrnkBXOIQIIIQ8YvF/KrgB
cMaRN0UdBBkAAAAASUVORK5CYII=
</value>
</data>
<data name="ActionButton8.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAACOElE
QVQ4T2P4//8/QczOJyyqHpzfiE0OQwAZC8iqszAzs7CJ69o4BR768V/W2jcGXQ0KB4aFNS3dDQtnrbCb
ePCK48wTN1wXXXzge/jXf/clV55zC4hIIatF0cjIyMikElzc57z0wX+XHd/+2+//99/ywP//xlu//tdb
+eK/4Zp3/1WTOhYzARViNUAluKjTdf37/0ZTTn9TbdhwXblhwwW1/qOP1Ja9+K8w+95/6cm3/6v2Xvkv
qKjniGGAoIqRpW3/4e8S9uGdzFz82gwMDFxAzCxm4ZegtuLDf+VJ1/8rZM25IqLvnM/CximCYYCic1QN
v7x2JIwPwyrJ3XNUylddE9G2TWNmZOBDl4czmJiZMSRBmFdSyYyJgUEQmxwIYxWEYXZBCUls4sgYq6CA
prWNbtG8nXKeaVPR5XiVjSxEzf0yYXy4BBMLO6eQjoOXZvrkbbazrv53Xf/2v4CSbjBMXkhBl1/CMyNZ
qWnvGy5pNQ+YONwAfjXzAOupl/47LLr333L50/96q9/8l23YdES6cO5KuYqVW+R7Tj6SnfP0v4hryjyY
HhQDmFjYeHVKFp7WX/Xuv9Kq9/+Vd/z7r7rv/3+l7f//y676DEwDN/9L+BVvYkKLCTgDhNkkVUyVlr74
qbbz73/VOTc/qsy89kWx+9h7qbQpJwS1bbOAscGGrB6EUTggLOqf16C55ft/HlnNAFZOXgVWdi4FRgYG
VnR1MIwhwMTCyqEQ37qEmZVDFF0OE/9nAACtFF4Ey6OP+wAAAABJRU5ErkJggg==
</value>
</data>
<data name="ActionButton9.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
xAAADsQBlSsOGwAAAIZJREFUOE+1j10KwCAMgz2b755xl/IsvnaL2K20UfbDAmEako+ZROSTafjE12Go
tbbB43rK5xSAQq1VYFtmeQBoqZTSreVZvgTknM8yyyjA/qodsDF9gspD2Bj6B+DH+NqzhQQAG+POMnSX
AFuc5QFgn6ClHh5iOQVAKNixyucB8NY0vG9JOzzyhrdq5IRgAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,474 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls
Imports PersonalUtilities.Forms.Controls.Base
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Tools
Imports SCrawler.API.YouTube.Base
Imports SCrawler.API.YouTube.Objects
Imports SCrawler.DownloadObjects.STDownloader
Imports UMTypes = SCrawler.Plugin.UserMediaTypes
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace API.YouTube.Controls
Friend Class VideoOptionsForm : Implements IDesignXMLContainer
#Region "Declarations"
Private MyView As FormView
Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
Private Const ControlsRow As Integer = 6
Private ReadOnly Property CNT_PROCESSOR As TableControlsProcessor
Friend Property MyContainer As YouTubeMediaContainerBase
Private Initialization As Boolean = True
Private ReadOnly IsSavedObject As Boolean
#End Region
#Region "Initializers"
Friend Sub New(ByVal Container As YouTubeMediaContainerBase, Optional ByVal IsSavedObject As Boolean = False)
InitializeComponent()
MyContainer = Container
CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS)
Me.IsSavedObject = IsSavedObject
End Sub
#End Region
#Region "Form handlers"
Private Sub VideoOptionsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not DesignXML Is Nothing Then
MyView = New FormView(Me) With {.LocationOnly = True}
MyView.Import()
MyView.SetFormSize()
End If
If Not MyContainer Is Nothing Then
With MyContainer
Dim i%
Dim arr$() = Nothing
Dim arrComparer As New FComparer(Of String)(Function(x, y) x.ToLower = y.ToLower)
Dim setDef As Action(Of ComboBox, String) =
Sub(ByVal cmb As ComboBox, ByVal compValue As String)
i = -1
If Not compValue.IsEmptyString Then i = arr.ListIndexOf(compValue, arrComparer, EDP.ReturnValue)
If i >= 0 Then cmb.SelectedIndex = i Else cmb.SelectedIndex = 0
End Sub
Dim __audioOnly As Boolean = False
Dim __optionValue$
If .HasElements Then
Text = "Playlist"
If Not .PlaylistTitle.IsEmptyString Or Not .Title.IsEmptyString Then Text &= $" - { .PlaylistTitle.IfNullOrEmpty(.Title)}"
TP_MAIN.Controls.Remove(TP_HEADER_BASE)
TP_MAIN.RowStyles(0).Height = 0
Dim def% = If(IsSavedObject, .ArrayMaxResolution, MyYouTubeSettings.DefaultVideoDefinition.Value)
If IsSavedObject Then
__audioOnly = def = -2
If def <= 0 Then def = MyYouTubeSettings.DefaultVideoDefinition
Else
If Not def.ValueBetween(-1, 10000) Then def = 1080
End If
NUM_RES.Value = def
Else
TP_OPTIONS.Controls.Remove(NUM_RES)
TP_OPTIONS.ColumnStyles(3).Width = 0
Dim img As Image = Nothing
Dim imgUrl$ = .ThumbnailUrlMedia
If Not imgUrl.IsEmptyString Then
img = ImageRenderer.GetImage(SFile.GetBytesFromNet(imgUrl, EDP.ReturnValue), EDP.ReturnValue)
If Not img Is Nothing Then ICON_VIDEO.Image = img : ICON_VIDEO.InitialImage = img
End If
LBL_TITLE.Text = .Title
LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
TP_HEADER_INFO_2.ColumnStyles(1).Width = MeasureTextDefault(LBL_TIME.Text, LBL_TIME.Font).Width + PaddingE.GetOf({LBL_TIME}).Horizontal
TP_HEADER_INFO_2.Refresh()
LBL_URL.Text = .URL
End If
If .IsMusic Or __audioOnly Then
OPT_AUDIO.Checked = True
Else
OPT_VIDEO.Checked = True
End If
CMB_FORMAT.Enabled = OPT_VIDEO.Checked
arr = AvailableVideoFormats
CMB_FORMAT.Items.AddRange(arr)
If IsSavedObject Then
__optionValue = .OutputVideoExtension.IfNullOrEmpty(MyYouTubeSettings.DefaultVideoFormat.Value)
Else
__optionValue = MyYouTubeSettings.DefaultVideoFormat.Value
End If
setDef(CMB_FORMAT, __optionValue)
arr = AvailableAudioFormats
CMB_AUDIO_CODEC.Items.AddRange(arr)
If IsSavedObject Then
__optionValue = .OutputAudioCodec.IfNullOrEmpty(IIf(.IsMusic, MyYouTubeSettings.DefaultAudioCodecMusic.Value, MyYouTubeSettings.DefaultAudioCodec.Value))
Else
__optionValue = IIf(.IsMusic, MyYouTubeSettings.DefaultAudioCodecMusic.Value, MyYouTubeSettings.DefaultAudioCodec.Value)
End If
setDef(CMB_AUDIO_CODEC, __optionValue)
arr = AvailableSubtitlesFormats
CMB_SUBS_FORMAT.Items.AddRange(arr)
If IsSavedObject Then
__optionValue = .OutputSubtitlesFormat.IfNullOrEmpty(IIf(.IsMusic, "LRC", MyYouTubeSettings.DefaultSubtitlesFormat.Value))
Else
__optionValue = IIf(.IsMusic, "LRC", MyYouTubeSettings.DefaultSubtitlesFormat.Value)
End If
setDef(CMB_SUBS_FORMAT, __optionValue)
TP_SUBS.Enabled = .Subtitles.Count > 0
TXT_SUBS_ADDIT.Enabled = .Subtitles.Count > 0
RefillTextBoxes()
TXT_SUBS_ADDIT.Checked = .PostProcessing_OutputSubtitlesFormats.Count > 0
TXT_EXTRA_AUDIO_FORMATS.Checked = .PostProcessing_OutputAudioFormats.Count > 0
TXT_FILE.Text = .File
RefillList()
If OPT_VIDEO.Checked Then
ChangeFileExtension(CMB_FORMAT.Text)
Else
If .HasElements Then NUM_RES.Enabled = False
ChangeFileExtension(CMB_AUDIO_CODEC.Text)
End If
End With
End If
Initialization = False
End Sub
Private Sub VideoOptionsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
MyView.DisposeIfReady()
End Sub
#End Region
#Region "Refill"
Private Sub RefillList()
Dim i%
Dim h% = -1
Dim rh% = IIf(MyContainer.HasElements, 60, 25)
Dim s As New Size(Width, h)
Dim CalculateSize As Action(Of Integer) =
Sub(ByVal InitHeight As Integer)
With TP_MAIN.RowStyles(ControlsRow) : .SizeType = SizeType.Absolute : .Height = InitHeight : End With
s.Height = InitHeight
For ii% = 0 To TP_MAIN.RowStyles.Count - 1
If Not ii = ControlsRow And TP_MAIN.RowStyles(ii).SizeType = SizeType.Absolute Then s.Height += TP_MAIN.RowStyles(ii).Height
Next
s.Height += PaddingE.GetOf({TP_MAIN}).Vertical(TP_MAIN.RowStyles.Count - 3 - IIf(MyContainer.HasElements, 1, 0))
End Sub
Dim __contentType As UMTypes = IIf(OPT_VIDEO.Checked, UMTypes.Video, UMTypes.Audio)
With TP_CONTROLS
If .Controls.Count > 0 Then
For Each cnt As Control In .Controls : cnt.Dispose() : Next
.Controls.Clear()
End If
.RowStyles.Clear()
.RowCount = 0
End With
With MyContainer
Dim audio As MediaObject = Nothing
If __contentType = UMTypes.Video Then audio = .SelectedAudio
Dim data As IEnumerable(Of Control)
If .HasElements Then
data = .Elements.Select(Function(ee) New MediaItem(ee) With {.Dock = DockStyle.Fill, .Checked = ee.Checked, .IgnoreDownloadState = True})
Else
data = (From m As MediaObject In .Self.MediaObjects
Where m.Type = __contentType
Select New VideoOption(m, audio) With {.Dock = DockStyle.Fill, .Checked = m.Index = MyContainer.SelectedVideoIndex})
End If
If data.ListExists Then
With TP_CONTROLS
With .RowStyles
.Clear()
For i = 0 To data.Count - 1 : .Add(New RowStyle(SizeType.Absolute, rh)) : Next
.Add(New RowStyle(SizeType.AutoSize))
End With
.RowCount = .RowStyles.Count
For i = 0 To data.Count - 1 : .Controls.Add(data(i), 0, i) : Next
.Controls.Cast(Of Control).ToList.ForEach(Sub(ByVal d As Control)
DirectCast(d, ISupportInitialize).EndInit()
If MyContainer.HasElements Then
With DirectCast(d, MediaItem)
AddHandler .CheckedChanged, AddressOf MediaItem_CheckedChanged
AddHandler .Click, AddressOf CNT_PROCESSOR.MediaItem_Click
AddHandler .KeyDown, AddressOf CNT_PROCESSOR.MediaItem_KeyDown
End With
End If
End Sub)
If MyContainer.HasElements Then
If .Controls.Count > 0 Then
Dim cIndx% = 0
Dim c As Color
For Each cnt As MediaItem In .Controls
cIndx += 1
If (cIndx Mod 2) = 0 Then c = SystemColors.ControlLight Else c = SystemColors.Window
cnt.BackColor = c
Next
End If
Else
If Not data.ListExists(Function(d As VideoOption) d.Checked) Then
If MyYouTubeSettings.DefaultVideoDefinition > 0 Then
For Each cnt As VideoOption In .Controls
If cnt.MyMedia.Height <= MyYouTubeSettings.DefaultVideoDefinition Then cnt.Checked = True : Exit For
Next
Else
DirectCast(.Controls(0), VideoOption).Checked = True
End If
End If
End If
End With
h = data.Count * rh + PaddingE.GetOf({TP_CONTROLS}).Vertical(1.5)
CalculateSize(h)
Dim hh% = Screen.PrimaryScreen.WorkingArea.Height - 20
If s.Height > hh Then
h = 5 * rh + PaddingE.GetOf({TP_CONTROLS}).Vertical(1.5)
CalculateSize(h)
With TP_CONTROLS
.AutoSizeMode = AutoSizeMode.GrowAndShrink
.AutoScroll = True
Dim p As Padding = .Padding
p.Right += 3
.Padding = p
.VerticalScroll.Visible = True
.VerticalScroll.Enabled = True
.HorizontalScroll.Visible = False
.HorizontalScroll.Enabled = False
End With
End If
With TP_CONTROLS
.PerformLayout()
.Select()
If .Controls.Count > 0 Then .Controls(0).Focus()
End With
End If
End With
If s.Height = -1 Then s.Height = rh
MaximumSize = Nothing
MinimumSize = Nothing
Size = s
MinimumSize = Size
MaximumSize = Size
End Sub
#End Region
#Region "Media items' handlers"
Private Sub MediaItem_CheckedChanged(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
ControlInvokeFast(TP_CONTROLS, Sub() Container.Checked = Sender.Checked, EDP.None)
End Sub
#End Region
#Region "OK, Cancel"
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
Try
Dim f As SFile
If MyContainer.HasElements Then
f = TXT_FILE.Text.CSFileP
Else
f = TXT_FILE.Text
End If
If f.IsEmptyString Then Throw New ArgumentNullException("File", "The output file cannot be null")
With MyContainer
.OutputVideoExtension = CMB_FORMAT.Text.StringToLower
.OutputAudioCodec = CMB_AUDIO_CODEC.Text.StringToLower
.OutputSubtitlesFormat = CMB_SUBS_FORMAT.Text.StringToLower
If Not .HasElements Then
Dim cntIndex% = -1
With TP_CONTROLS.Controls
If .Count > 0 Then
For Each cnt As VideoOption In .Self
If cnt.Checked Then cntIndex = cnt.MyMedia.Index : Exit For
Next
End If
End With
If cntIndex = -1 Then Throw New ArgumentOutOfRangeException("Download option", "What to download is not selected")
If OPT_VIDEO.Checked Then
.SelectedVideoIndex = cntIndex
Else
.SelectedVideoIndex = -1
.SelectedAudioIndex = cntIndex
End If
.File = f
.FileSetManually = True
.UpdateInfoFields()
'#If DEBUG Then
' Debug.WriteLine(.Command(False))
'#End If
Else
If OPT_AUDIO.Checked Then
.SetMaxResolution(-2)
Else
.SetMaxResolution(NUM_RES.Value)
End If
.File = f
End If
End With
If MyYouTubeSettings.OutputPathAutoChange Then MyYouTubeSettings.OutputPath.Value = f
DialogResult = DialogResult.OK
Close()
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog + EDP.ShowMainMsg, ex, $"Download {IIf(MyContainer.HasElements, "playlist", "video")}")
End Try
End Sub
Private Sub BTT_CANCEL_Click(sender As Object, e As EventArgs) Handles BTT_CANCEL.Click
DialogResult = DialogResult.Cancel
Close()
End Sub
#End Region
#Region "Controls' handlers"
#Region "Header"
Private Sub LBL_URL_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LBL_URL.LinkClicked
If Not LBL_URL.Text.IsEmptyString Then
Try : Process.Start(LBL_URL.Text) : Catch : End Try
End If
End Sub
#End Region
#Region "Settings"
Private Sub OPT_VIDEO_AUDIO_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_VIDEO.CheckedChanged, OPT_AUDIO.CheckedChanged
If Not Initialization Then
CMB_FORMAT.Enabled = OPT_VIDEO.Checked
If MyContainer.HasElements Then
NUM_RES.Enabled = OPT_VIDEO.Checked
Else
RefillList()
If OPT_VIDEO.Checked Then
ChangeFileExtension(CMB_FORMAT.Text)
Else
ChangeFileExtension(CMB_AUDIO_CODEC.Text)
End If
End If
End If
End Sub
Private Sub CMB_FORMAT_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CMB_FORMAT.SelectedIndexChanged
If Not Initialization AndAlso OPT_VIDEO.Checked Then ChangeFileExtension(CMB_FORMAT.Text)
End Sub
Private Sub CMB_AUDIO_CODEC_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CMB_AUDIO_CODEC.SelectedIndexChanged
If Not Initialization AndAlso OPT_AUDIO.Checked Then ChangeFileExtension(CMB_AUDIO_CODEC.Text)
End Sub
Private Sub ChangeFileExtension(ByVal NewExt As String)
If Not MyContainer.HasElements Then
Dim f As SFile = TXT_FILE.Text
f.Extension = NewExt.StringToLower
TXT_FILE.Text = f
End If
End Sub
Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick
Select Case Sender.DefaultButton
Case ADB.Open
If MyContainer.Subtitles.Count > 0 Then
Using f As New SimpleListForm(Of String)(MyContainer.Subtitles.Select(Function(s) s.Name)) With {
.DesignXML = DesignXML,
.DesignXMLNodeName = SimpleArraysFormNode,
.Mode = SimpleListFormModes.CheckedItems,
.FormText = "Subtitles"
}
With MyContainer
If .SubtitlesSelectedIndexes.Count > 0 Then f.DataSelectedIndexes.AddRange(.SubtitlesSelectedIndexes)
If f.ShowDialog() = DialogResult.OK Then
.SubtitlesSelectedIndexes.Clear()
If f.DataResultIndexes.Count > 0 Then .SubtitlesSelectedIndexes.AddRange(f.DataResultIndexes)
RefillTextBoxes()
End If
End With
End Using
End If
Case ADB.Refresh
MyContainer.SubtitlesSelectedIndexesReset()
RefillTextBoxes()
Case ADB.Clear
MyContainer.SubtitlesSelectedIndexes.Clear()
RefillTextBoxes()
End Select
End Sub
Private Sub CONTROLS_ADDIT_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS_ADDIT.ActionOnButtonClick,
TXT_EXTRA_AUDIO_FORMATS.ActionOnButtonClick
Dim isSubs As Boolean = CStr(DirectCast(e.AssociatedControl, TextBoxExtended).Tag) = "s"
Select Case Sender.DefaultButton
Case ADB.Open
Using f As New SimpleListForm(Of String)(If(isSubs, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
.DesignXML = DesignXML,
.DesignXMLNodeName = SimpleArraysFormNode,
.Mode = SimpleListFormModes.CheckedItems,
.FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText
}
With MyContainer
With If(isSubs, .PostProcessing_OutputSubtitlesFormats, .PostProcessing_OutputAudioFormats)
If .Self.Count > 0 Then f.DataSelected.AddRange(.Self)
If f.ShowDialog() = DialogResult.OK Then
.Self.Clear()
If f.DataResultIndexes.Count > 0 Then .Self.AddRange(f.DataResult)
DirectCast(e.AssociatedControl, TextBoxExtended).Text = .ListToString
RefillTextBoxes()
End If
End With
End With
End Using
Case ADB.Refresh
If isSubs Then
MyContainer.PostProcessing_OutputSubtitlesFormats_Reset()
Else
MyContainer.PostProcessing_OutputAudioFormats_Reset()
End If
RefillTextBoxes()
Case ADB.Clear
If isSubs Then
MyContainer.PostProcessing_OutputSubtitlesFormats.Clear()
Else
MyContainer.PostProcessing_OutputAudioFormats.Clear()
End If
RefillTextBoxes()
End Select
End Sub
#End Region
#Region "Footer"
Private Sub BTT_BROWSE_Click(sender As Object, e As EventArgs) Handles BTT_BROWSE.Click
Dim f As SFile
#Disable Warning BC40000
If MyContainer.HasElements Then
f = TXT_FILE.Text.CSFileP
f = SFile.SelectPath(f, "Select the destination of the video files", EDP.ReturnValue)
Else
f = TXT_FILE.Text
Dim sPattern$ = $"Video|{AvailableVideoFormats.Select(Function(vf) $"*.{vf.ToLower}").ListToString(";")}" &
$"|Audio|{AvailableAudioFormats.Select(Function(af) $"*.{af.ToLower}").ListToString(";")}" &
"|All Files|*.*"
f = SFile.SaveAs(f, "Select the destination of the video file",,, sPattern, EDP.ReturnValue)
End If
#Enable Warning
If Not f.IsEmptyString Then TXT_FILE.Text = f
End Sub
#End Region
#End Region
#Region "Functions"
Private Sub RefillTextBoxes()
With MyContainer
If .SubtitlesSelectedIndexes.Count > 0 Then
TXT_SUBS.Text = ListAddList(Nothing, .Subtitles.Select(Function(s, i) If(.SubtitlesSelectedIndexes.Contains(i), s.ID, String.Empty)),
LAP.NotContainsOnly, EDP.ReturnValue).ListToString(",")
Else
TXT_SUBS.Clear()
End If
If .PostProcessing_OutputSubtitlesFormats.Count > 0 Then
TXT_SUBS_ADDIT.Text = .PostProcessing_OutputSubtitlesFormats.ListToString
Else
TXT_SUBS_ADDIT.Clear()
End If
If .PostProcessing_OutputAudioFormats.Count > 0 Then
TXT_EXTRA_AUDIO_FORMATS.Text = .PostProcessing_OutputAudioFormats.ListToString
Else
TXT_EXTRA_AUDIO_FORMATS.Clear()
End If
End With
End Sub
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,112 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Functions.RegularExpressions
Namespace API.YouTube
Public Module YTDeclarations
Public Const YouTubeSite As String = "YouTube"
Public Const YouTubeSiteKey As String = "AndyProgram_YouTube"
Public Const YouTubeSettingsFile As String = "Settings\SettingsYouTube.xml"
Public Const DownloaderDataFolderYouTube As String = DownloadObjects.STDownloader.DownloaderDataFolder & "YouTube\"
Friend Const YouTubeDownloadPathDefault As String = "YouTubeDownloads\"
Friend Const SimpleArraysFormNode As String = "SimpleFormatsChooserForm"
Public Property MyYouTubeSettings As Base.YouTubeSettings
Public Property MyCache As CacheKeeper
Friend ReadOnly Property MyCacheSettings As New CacheKeeper(DownloaderDataFolderYouTube) With {.DeleteCacheOnDispose = False, .DeleteRootOnDispose = False}
Public ReadOnly Property YouTubeCookieNetscapeFile As New SFile($"Settings\Responser_{YouTubeSite}_Cookies_Netscape.txt")
Friend ReadOnly Property AvailableSubtitlesFormats As String()
Get
Return {"ASS", "LRC", "SRT", "VTT"}
End Get
End Property
Friend ReadOnly Property AvailableVideoFormats As String()
Get
Return {"AVI", "FLV", "GIF", "MKV", "MOV", "MP4", "WEBM", "AAC", "AIFF", "ALAC", "FLAC", "M4A", "MKA", "MP3", "OGG", "OPUS", "VORBIS", "WAV"}
End Get
End Property
Friend ReadOnly Property AvailableAudioFormats As String()
Get
'AC3 not supported
Return {"AC3", "AAC", "ALAC", "FLAC", "M4A", "MP3", "OPUS", "VORBIS", "WAV"}
End Get
End Property
Friend ReadOnly VideoSizeProvider As New ANumbers(ANumbers.Cultures.USA, ANumbers.Options.DecimalsTrim) With {.DeclaredError = EDP.ReturnValue}
Friend ReadOnly NumberProvider As New ANumbers(ANumbers.Cultures.Primitive) With {.DeclaredError = EDP.ReturnValue}
Friend ReadOnly DateBaseProvider As New ADateTime(ADateTime.Formats.BaseDateTime)
Friend ReadOnly DateAddedProvider As New ADateTime(ADateTime.Formats.yyyymmdd) With {.DateSeparator = String.Empty}
Friend ReadOnly TimeToStringProvider As IFormatProvider = New TimeToStringConverter
Friend ReadOnly TitleHtmlConverter As Func(Of String, String) = Function(Input) Input.StringRemoveWinForbiddenSymbols().StringTrim()
Friend ReadOnly ProgressProvider As IMyProgressNumberProvider = MyProgressNumberProvider.Percentage
Public ReadOnly TrueUrlRegEx As RParams = RParams.DM(Base.YouTubeFunctions.TrueUrlPattern, 0, EDP.ReturnValue)
Private Class TimeToStringConverter : Implements ICustomProvider
Private ReadOnly _Provider As New ADateTime("mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
Private ReadOnly _ProviderWithHours As New ADateTime("h\:mm\:ss") With {.TimeParseMode = ADateTime.TimeModes.TimeSpan}
Private ReadOnly Property Provider(ByVal t As TimeSpan) As IFormatProvider
Get
Return If(t.Hours > 0, _ProviderWithHours, _Provider)
End Get
End Property
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
If Not IsNothing(Value) Then
If TypeOf Value Is Nullable(Of TimeSpan) Then
With DirectCast(Value, Nullable(Of TimeSpan))
If .HasValue Then Return AConvert(Of String)(.Value, Me.Provider(.Value), String.Empty)
End With
ElseIf TypeOf Value Is TimeSpan Then
Dim t As TimeSpan = Value
Return AConvert(Of String)(t, Me.Provider(t), String.Empty)
End If
End If
Return String.Empty
End Function
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
Throw New NotImplementedException("'GetFormat' is not available in the 'TimeToStringConverter' context")
End Function
End Class
Friend Class DurationXmlConverter : Implements ICustomProvider
Private Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object Implements ICustomProvider.Convert
Try
If DestinationType Is GetType(String) Then
If IsNothing(Value) Then
Return 0
ElseIf TypeOf Value Is TimeSpan Then
Return DirectCast(Value, TimeSpan).TotalSeconds
Else
Throw New Exception
End If
ElseIf DestinationType Is GetType(TimeSpan) Then
If IsNothing(Value) Then
Return New TimeSpan
ElseIf TypeOf Value Is String Then
If CStr(Value).IsEmptyString Then
Return New TimeSpan
Else
Return TimeSpan.FromSeconds(AConvert(Of Double)(Value, EDP.ThrowException))
End If
ElseIf TypeOf Value Is Double Or IsNumeric(Value) Then
Return TimeSpan.FromSeconds(Value)
Else
Throw New Exception
End If
Else
Throw New Exception
End If
Catch ex As Exception
Throw New Exception($"Cannot convert {Value.GetType.Name} to {DestinationType.Name}", ex)
End Try
End Function
Private Function GetFormat(ByVal FormatType As Type) As Object Implements IFormatProvider.GetFormat
Throw New NotImplementedException("'GetFormat' is not available in the 'DurationXmlConverter' context")
End Function
End Class
End Module
End Namespace

View File

@@ -0,0 +1,20 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace DownloadObjects.STDownloader
Public Interface IDownloaderSettings
ReadOnly Property ShowNotifications As Boolean
ReadOnly Property ShowNotificationsEveryDownload As Boolean
ReadOnly Property MaxJobsCount As Integer
ReadOnly Property DownloadAutomatically As Boolean
ReadOnly Property RemoveDownloadedAutomatically As Boolean
ReadOnly Property OnItemDoubleClick As DoubleClickBehavior
ReadOnly Property OpenFolderInOtherProgram As Boolean
ReadOnly Property OpenFolderInOtherProgram_Command As String
End Interface
End Namespace

View File

@@ -0,0 +1,257 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace DownloadObjects.STDownloader
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Public Class MediaItem : Inherits System.Windows.Forms.UserControl
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Dim TP_MAIN As System.Windows.Forms.TableLayoutPanel
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(MediaItem))
Me.ICON_VIDEO = New System.Windows.Forms.PictureBox()
Me.CONTEXT_MAIN = New System.Windows.Forms.ContextMenuStrip(Me.components)
Me.BTT_DOWN = New System.Windows.Forms.ToolStripMenuItem()
Me.SEP_DOWN = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_OPEN_FOLDER = New System.Windows.Forms.ToolStripMenuItem()
Me.SEP_FOLDER = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_COPY_LINK = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_OPEN_IN_BROWSER = New System.Windows.Forms.ToolStripMenuItem()
Me.SEP_DOWN_AGAIN = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_DOWN_AGAIN = New System.Windows.Forms.ToolStripMenuItem()
Me.SEP_DEL = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_REMOVE_FROM_LIST = New System.Windows.Forms.ToolStripMenuItem()
Me.BTT_DELETE_FILE = New System.Windows.Forms.ToolStripMenuItem()
Me.TP_INFO = New System.Windows.Forms.TableLayoutPanel()
Me.TP_CHECKED_TITLE = New System.Windows.Forms.TableLayoutPanel()
Me.LBL_TITLE = New System.Windows.Forms.Label()
Me.CH_CHECKED = New System.Windows.Forms.CheckBox()
Me.BTT_VIEW_SETTINGS = New System.Windows.Forms.ToolStripMenuItem()
TP_MAIN = New System.Windows.Forms.TableLayoutPanel()
TP_MAIN.SuspendLayout()
CType(Me.ICON_VIDEO, System.ComponentModel.ISupportInitialize).BeginInit()
Me.CONTEXT_MAIN.SuspendLayout()
Me.TP_INFO.SuspendLayout()
Me.TP_CHECKED_TITLE.SuspendLayout()
Me.SuspendLayout()
'
'TP_MAIN
'
TP_MAIN.ColumnCount = 2
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 125.0!))
TP_MAIN.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.Controls.Add(Me.ICON_VIDEO, 0, 0)
TP_MAIN.Controls.Add(Me.TP_INFO, 1, 0)
TP_MAIN.Dock = System.Windows.Forms.DockStyle.Fill
TP_MAIN.Location = New System.Drawing.Point(0, 0)
TP_MAIN.Margin = New System.Windows.Forms.Padding(0)
TP_MAIN.Name = "TP_MAIN"
TP_MAIN.RowCount = 1
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
TP_MAIN.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 65.0!))
TP_MAIN.Size = New System.Drawing.Size(549, 65)
TP_MAIN.TabIndex = 0
AddHandler TP_MAIN.Click, AddressOf Me.Controls_Click
'
'ICON_VIDEO
'
Me.ICON_VIDEO.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom
Me.ICON_VIDEO.ContextMenuStrip = Me.CONTEXT_MAIN
Me.ICON_VIDEO.Dock = System.Windows.Forms.DockStyle.Fill
Me.ICON_VIDEO.Location = New System.Drawing.Point(3, 3)
Me.ICON_VIDEO.Name = "ICON_VIDEO"
Me.ICON_VIDEO.Size = New System.Drawing.Size(119, 59)
Me.ICON_VIDEO.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom
Me.ICON_VIDEO.TabIndex = 0
Me.ICON_VIDEO.TabStop = False
'
'CONTEXT_MAIN
'
Me.CONTEXT_MAIN.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_DOWN, Me.SEP_DOWN, Me.BTT_OPEN_FOLDER, Me.SEP_FOLDER, Me.BTT_COPY_LINK, Me.BTT_OPEN_IN_BROWSER, Me.SEP_DOWN_AGAIN, Me.BTT_DOWN_AGAIN, Me.BTT_VIEW_SETTINGS, Me.SEP_DEL, Me.BTT_REMOVE_FROM_LIST, Me.BTT_DELETE_FILE})
Me.CONTEXT_MAIN.Name = "CONTEXT_MAIN"
Me.CONTEXT_MAIN.ShowItemToolTips = False
Me.CONTEXT_MAIN.Size = New System.Drawing.Size(185, 226)
'
'BTT_DOWN
'
Me.BTT_DOWN.Image = Global.SCrawler.My.Resources.Resources.ArrowDownPic_Blue_24
Me.BTT_DOWN.Name = "BTT_DOWN"
Me.BTT_DOWN.Size = New System.Drawing.Size(184, 22)
Me.BTT_DOWN.Text = "Download"
'
'SEP_DOWN
'
Me.SEP_DOWN.Name = "SEP_DOWN"
Me.SEP_DOWN.Size = New System.Drawing.Size(181, 6)
'
'BTT_OPEN_FOLDER
'
Me.BTT_OPEN_FOLDER.Image = CType(resources.GetObject("BTT_OPEN_FOLDER.Image"), System.Drawing.Image)
Me.BTT_OPEN_FOLDER.Name = "BTT_OPEN_FOLDER"
Me.BTT_OPEN_FOLDER.Size = New System.Drawing.Size(184, 22)
Me.BTT_OPEN_FOLDER.Text = "Open folder"
'
'SEP_FOLDER
'
Me.SEP_FOLDER.Name = "SEP_FOLDER"
Me.SEP_FOLDER.Size = New System.Drawing.Size(181, 6)
'
'BTT_COPY_LINK
'
Me.BTT_COPY_LINK.Image = Global.SCrawler.My.Resources.Resources.LinkPic_32
Me.BTT_COPY_LINK.Name = "BTT_COPY_LINK"
Me.BTT_COPY_LINK.Size = New System.Drawing.Size(184, 22)
Me.BTT_COPY_LINK.Text = "Copy link address"
'
'BTT_OPEN_IN_BROWSER
'
Me.BTT_OPEN_IN_BROWSER.Image = CType(resources.GetObject("BTT_OPEN_IN_BROWSER.Image"), System.Drawing.Image)
Me.BTT_OPEN_IN_BROWSER.Name = "BTT_OPEN_IN_BROWSER"
Me.BTT_OPEN_IN_BROWSER.Size = New System.Drawing.Size(184, 22)
Me.BTT_OPEN_IN_BROWSER.Text = "Open link in browser"
'
'SEP_DOWN_AGAIN
'
Me.SEP_DOWN_AGAIN.Name = "SEP_DOWN_AGAIN"
Me.SEP_DOWN_AGAIN.Size = New System.Drawing.Size(181, 6)
'
'BTT_DOWN_AGAIN
'
Me.BTT_DOWN_AGAIN.Image = CType(resources.GetObject("BTT_DOWN_AGAIN.Image"), System.Drawing.Image)
Me.BTT_DOWN_AGAIN.Name = "BTT_DOWN_AGAIN"
Me.BTT_DOWN_AGAIN.Size = New System.Drawing.Size(184, 22)
Me.BTT_DOWN_AGAIN.Text = "Download again"
'
'SEP_DEL
'
Me.SEP_DEL.Name = "SEP_DEL"
Me.SEP_DEL.Size = New System.Drawing.Size(181, 6)
'
'BTT_REMOVE_FROM_LIST
'
Me.BTT_REMOVE_FROM_LIST.Image = CType(resources.GetObject("BTT_REMOVE_FROM_LIST.Image"), System.Drawing.Image)
Me.BTT_REMOVE_FROM_LIST.Name = "BTT_REMOVE_FROM_LIST"
Me.BTT_REMOVE_FROM_LIST.Size = New System.Drawing.Size(184, 22)
Me.BTT_REMOVE_FROM_LIST.Text = "Remove from the list"
'
'BTT_DELETE_FILE
'
Me.BTT_DELETE_FILE.Image = CType(resources.GetObject("BTT_DELETE_FILE.Image"), System.Drawing.Image)
Me.BTT_DELETE_FILE.Name = "BTT_DELETE_FILE"
Me.BTT_DELETE_FILE.Size = New System.Drawing.Size(184, 22)
Me.BTT_DELETE_FILE.Text = "Delete file"
'
'TP_INFO
'
Me.TP_INFO.ColumnCount = 1
Me.TP_INFO.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_INFO.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
Me.TP_INFO.Controls.Add(Me.TP_CHECKED_TITLE, 0, 0)
Me.TP_INFO.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_INFO.Location = New System.Drawing.Point(125, 0)
Me.TP_INFO.Margin = New System.Windows.Forms.Padding(0)
Me.TP_INFO.Name = "TP_INFO"
Me.TP_INFO.RowCount = 2
Me.TP_INFO.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.TP_INFO.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50.0!))
Me.TP_INFO.Size = New System.Drawing.Size(424, 65)
Me.TP_INFO.TabIndex = 1
'
'TP_CHECKED_TITLE
'
Me.TP_CHECKED_TITLE.ColumnCount = 2
Me.TP_CHECKED_TITLE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20.0!))
Me.TP_CHECKED_TITLE.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_CHECKED_TITLE.Controls.Add(Me.LBL_TITLE, 1, 0)
Me.TP_CHECKED_TITLE.Controls.Add(Me.CH_CHECKED, 0, 0)
Me.TP_CHECKED_TITLE.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_CHECKED_TITLE.Location = New System.Drawing.Point(0, 0)
Me.TP_CHECKED_TITLE.Margin = New System.Windows.Forms.Padding(0)
Me.TP_CHECKED_TITLE.Name = "TP_CHECKED_TITLE"
Me.TP_CHECKED_TITLE.RowCount = 1
Me.TP_CHECKED_TITLE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_CHECKED_TITLE.RowStyles.Add(New System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32.0!))
Me.TP_CHECKED_TITLE.Size = New System.Drawing.Size(424, 32)
Me.TP_CHECKED_TITLE.TabIndex = 0
'
'LBL_TITLE
'
Me.LBL_TITLE.ContextMenuStrip = Me.CONTEXT_MAIN
Me.LBL_TITLE.Dock = System.Windows.Forms.DockStyle.Fill
Me.LBL_TITLE.Font = New System.Drawing.Font("Arial", 9.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(204, Byte))
Me.LBL_TITLE.Location = New System.Drawing.Point(23, 0)
Me.LBL_TITLE.Name = "LBL_TITLE"
Me.LBL_TITLE.Size = New System.Drawing.Size(398, 32)
Me.LBL_TITLE.TabIndex = 1
Me.LBL_TITLE.Text = "Video title"
Me.LBL_TITLE.TextAlign = System.Drawing.ContentAlignment.MiddleLeft
'
'CH_CHECKED
'
Me.CH_CHECKED.AutoSize = True
Me.CH_CHECKED.Dock = System.Windows.Forms.DockStyle.Fill
Me.CH_CHECKED.Location = New System.Drawing.Point(3, 3)
Me.CH_CHECKED.Name = "CH_CHECKED"
Me.CH_CHECKED.Size = New System.Drawing.Size(14, 26)
Me.CH_CHECKED.TabIndex = 0
Me.CH_CHECKED.UseVisualStyleBackColor = True
'
'BTT_VIEW_SETTINGS
'
Me.BTT_VIEW_SETTINGS.Image = Global.SCrawler.My.Resources.Resources.SettingsPic_16
Me.BTT_VIEW_SETTINGS.Name = "BTT_VIEW_SETTINGS"
Me.BTT_VIEW_SETTINGS.Size = New System.Drawing.Size(184, 22)
Me.BTT_VIEW_SETTINGS.Text = "View settings"
'
'MediaItem
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Controls.Add(TP_MAIN)
Me.Name = "MediaItem"
Me.Size = New System.Drawing.Size(549, 65)
TP_MAIN.ResumeLayout(False)
CType(Me.ICON_VIDEO, System.ComponentModel.ISupportInitialize).EndInit()
Me.CONTEXT_MAIN.ResumeLayout(False)
Me.TP_INFO.ResumeLayout(False)
Me.TP_CHECKED_TITLE.ResumeLayout(False)
Me.TP_CHECKED_TITLE.PerformLayout()
Me.ResumeLayout(False)
End Sub
Private WithEvents ICON_VIDEO As PictureBox
Private WithEvents LBL_TITLE As Label
Private WithEvents CONTEXT_MAIN As ContextMenuStrip
Private WithEvents BTT_OPEN_FOLDER As ToolStripMenuItem
Private WithEvents BTT_COPY_LINK As ToolStripMenuItem
Private WithEvents BTT_OPEN_IN_BROWSER As ToolStripMenuItem
Private WithEvents BTT_DOWN_AGAIN As ToolStripMenuItem
Private WithEvents BTT_REMOVE_FROM_LIST As ToolStripMenuItem
Private WithEvents BTT_DELETE_FILE As ToolStripMenuItem
Private WithEvents BTT_DOWN As ToolStripMenuItem
Private WithEvents SEP_DOWN As ToolStripSeparator
Private WithEvents TP_INFO As TableLayoutPanel
Friend WithEvents TP_CHECKED_TITLE As TableLayoutPanel
Private WithEvents CH_CHECKED As CheckBox
Private WithEvents SEP_FOLDER As ToolStripSeparator
Private WithEvents SEP_DOWN_AGAIN As ToolStripSeparator
Private WithEvents SEP_DEL As ToolStripSeparator
Private WithEvents BTT_VIEW_SETTINGS As ToolStripMenuItem
End Class
End Namespace

View File

@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="TP_MAIN.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="CONTEXT_MAIN.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="BTT_OPEN_FOLDER.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
wwAADsMBx2+oZAAAAk9JREFUOE+Nk0tIVGEUgKcWZlZWEK1aZEmZUlmpEQUtrF1Q0WNfUUgtCqKZLMXQ
UPJRmuY4TYYKmbPJcVSCAkuFQislzCx7rSo3Oc5T7zzu17njdZosxMXH/bn/+b97zn/ONfBjAJoPQctR
sB2bH1rsw8OEvnVj0BbUbdNJ19HW2+fmbgZO4wIR2MRm3irIQcsO2RA0Qe3mf9EOajGRuEycuXEiaDky
vdlXTfjrc0Kfu1BfVkJjtqR68G80cfRDIrgSL4Km/fCinFC/GU9JEs7CTUy25hAafYIy8hhl2IEy2Iwy
0IzacRaq1kNNClizdEHjPhiw4nFcRClKFLukWZvG1PWVuI0GPMVr8LYb8XZcRvX/gqEH0HZSskmPEbyu
w9N+CaV41bS9/Qx86oQPdhh1EOwuwesw4bGdY7LvPoHhNgIlq5nIS5gl0DLoyIF3LfgbDjBhFap348uL
Q5EDyrVEgvZT+Htv4ytYiit/WYzAfh6lIgl1bBB/xQYmi1YQqkomVJmMapbLswhN2ajfX+ErW8dU+Vpc
eUtiBRcIPDpBoKcU99V4uJf1p2Va+2q3QE8hSvcN3PkJUL9r5g6kXW8sUoKRqSE7vlupBCUTrJl6u3SB
PNWfb/GWbyQQ2Z/pgjaJ9XsI91sIjr1H+fgUVeYh/KVrFs8Itp6O1B2RR+fAdhzupEHDXnw3U3GVpuAq
+w/y3l2wnHCNxMrhGIGMcp2WpkyYWeqcC30Co5OYu0gvwZIRtc4b606cpoUYtF9y3BgvNkFSmhcSO25a
TGCkk99shOQwl9bXawAAAABJRU5ErkJggg==
</value>
</data>
<data name="BTT_OPEN_IN_BROWSER.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
Qk02AwAAAAAAADYAAAAoAAAAEAAAABAAAAABABgAAAAAAAAAAADDDgAAww4AAAAAAAAAAAAA/wD//wD/
/wD//wD/9vb29vb29vb29vb29vb29vb29vb29vb2/wD//wD//wD//wD//wD//wD/9vb29vb27t654bNN
15UA15UA15UA15UA4bNN7t659vb29vb2/wD//wD//wD/9vb29vb25b9s15UA15UA15UA15UA15UA15UA
15UA15UA5b9s9vb29vb2/wD//wD/9vb247lc15UA15UA5MJ43KYt7+nh7+nh3KYt5MJ415UA15UA5b9s
9vb2/wD/9vb27t6515UA15UA7N7D69m015UA8e/w8e/w15UA69m07N7D15UA15UA7t659vb29vb24bNN
15UA5MJ48e/w15UA7uTS8e/w8e/w7uTS15UA8e/w5MJ415UA4bNN9vb29vb215UA15UA15UA15UA15UA
15UA15UA15UA15UA15UA15UA15UA15UA15UA9vb29vb215UA15UA8e/w8e/w15UA8e/w8e/w8e/w8e/w
15UA8e/w8e/w15UA15UA9vb29vb215UA15UA8e/w8e/w15UA8e/w8e/w8e/w8e/w15UA8e/w8e/w15UA
15UA9vb29vb215UA15UA15UA15UA15UA15UA15UA15UA15UA15UA15UA15UA15UA15UA9vb29vb24bNN
15UA5MJ48e/w15UA7uTS8e/w8e/w7uTS15UA8e/w5MJ415UA4bNN9vb29vb27t6515UA15UA7N7D69m0
15UA8e/w8e/w15UA69m07N7D15UA15UA7t659vb2/wD/9vb25b9s15UA15UA5MJ43KYt7+nh7+nh3KYt
5MJ415UA15UA5b9s9vb2/wD//wD/9vb29vb247lc15UA15UA15UA15UA15UA15UA15UA15UA5b9s9vb2
9vb2/wD//wD//wD/9vb29vb27t654bNN15UA15UA15UA15UA4bNN7t659vb29vb2/wD//wD//wD//wD/
/wD//wD/9vb29vb29vb29vb29vb29vb29vb29vb2/wD//wD//wD//wD/
</value>
</data>
<data name="BTT_DOWN_AGAIN.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6
JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsTAAALEwEAmpwYAAADmUlE
QVRIS62WWWxMURjHL220JW1HausmlFrDFKUhnUGH6bRFzJ2idImlC0Vp2mlji1A8iNhCPIjIRES8EU+W
h2oEtbSDTk3HNNM7S01VKsXjkb/vXBo3k1Ee7sMvmZzzzf//ne/+z50RAAxL1MUIG4G/YAv3HSVhF5Vw
IYNdz3LadVj9RgdTB+HQYYPHIJuE1ocSdlEJFzG+1bPRLQLinglIeCkg+XUkKvz56hnkOfQs/rmA8S9H
YEp7FDI64tAQtKhnsMapZ7zzNHsUFnbGY4VzIk70l6hnIH4wsDR7NBZ3apDrSqL5T8eFgUr1DLZ78lim
Q4N8VzK29MxEpZSBa4M16hnU+c3M9CEFpdJsVHsXos63DDcHrf9nQEXD5VymwW/5USLNwl5vJhp7dTgW
NML2pR7jbsUMS+KdMTa5Q8NQxinfBU4dRFcOyjy52OtbhwOBDTgZLKPPmTgY0ON4MBdNfSbYBupxY8Aq
G10dqMG5/nIc7ytGQ6CQRliAamkTN/g1Ai4e95Qy3iogpX0UtBRDnhRzdxq2SXOxz5eFQ70rScCEU335
ssGxj0YS06HSm4GN3ekwdE2C1hGH1LZR0JDOJof5jwHvnIvzTa0jlooTYfktvt+fhcOBHDQFTWRgxJGP
ObAGsulZLMLWnjlY756K5c4JmNcRi6T2SGheCIihS2l5ozAo6NRhMolnUAcGV6IcwwqvFrX+JTjYuwKH
SfRAYDms/mzs9y1GFe2VSnOw1j0FejqpLN4WCX4ZufiIBwLMLxQGm12rsLQzgWKYgmLPLNTQw6ynpDSS
IBet8y+TqaVRVdFIeJrWuCcj+/0EzH43BomvIhBLI45uFiDcJ+6QwROFwa6+Amb9bGFNg6Xs9Ncd7Oy3
Knb2eyU7/20nu9y/m136tIvEl6BC0qKoZwby3alo9JVhj7T5R7m/kJVIIityi8zyXmTiW+I10SqyIQNb
uIgNwYuuf25kFd75KPKkI49OmUWnrfYWyXv/wBb2cijhhVf6a9lGei65XclYRDd6mj0GWz2iLBJaH0rY
RSVc5Eywmhm7kuQXHX+bJlBStrh+zTi0PpSwi0q4yNFAOVvgiEcKJWUsxZn/NhT+znlofShhF5VwkRpv
MUtti4KGYjj6sYCIh5QSu4oG27stjItHU+cjeQzvkcFzFQ2KnSKLoc4FukDCXeI2GbSoaFD4ziyPxNxK
0AUyNxOP1DOwcaG/8I+/LRB+At7psBnyDBG0AAAAAElFTkSuQmCC
</value>
</data>
<data name="BTT_REMOVE_FROM_LIST.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAVoSURBVEhLhZVrTJNXGMdfrtNSQIoadKRz2o0CorU3
WkDIVBRaaGNbwAteh+AARRQlitEYTTRekiX7sH3YPmyZH9wtziybigLRCWTaCW5sCBWhlrb0Ci9zSxbo
2f+UliGX7SS/tO85z/k9T57zXhhCCPO7Wh3VIhB83JKQ0Nu4bNlHm5YseZ1hmHC69n+Y5HLFcz7/ft/S
pY+vr1hhwL4oEBJcZ0x793If5uZ+1VNfT/qvXCHP6+p8tzMymqRxcW8hMGKqbDo9MlmWddu2AfbiRTJ6
+TIZKC52fyAUVi2JiYkLJmGaBYIPnx4+TPrOnCH9p08TC4LNx46RWwrF/ZXR0W/PleRZZuY669atZvbS
JcJiL9vQQEZPnSKmwkLPjcTE97GPB8KZlvh4C5X31dWRgRMniAVBtvPnyWB9ve+2XP7jmtjYpOlJTOnp
G60lJRZaOZWPQs4ePUpGUZh3xw7SnJDQhT0KEM3c5fOv9paVkX4kMAPL8ePEig1D584RG9rVpFS2rY6J
EQaTmKTSjbbiYsvIhQuERTGjKIrFvtHaWjK8fz9plsudexYu/BLxKsBj9ALBGzel0vt9e/b4XiBoENhQ
zRDOxIWWOY4cIS0KRZs4Nja5QyLJtRoM1pGzZ/0tYVExi/ayNTVkBPJ76enuJA7nM4j3gVWAHjgTIYqL
E96SStvMu3YR64EDxF5dTYYOHSJOJPNA5Kiu9rUrlZ1mrdbCnjzpr5jFGotYtqpqQi6TuVM4nKvwlYHU
gDzU31OMSGl8fPJtsbjVsn27z15RQRzAVVlJ3BB4kcx78CAZQbUjVIxrFtd+OdrbmpHhEXG5VE4rTwHz
wMRdFDw4jEgFj5dyRyRqsxYVEcfu3cQFPPv2ES8qHEbCYRzgsFZLvO+8Q7xKJXGDVoXCK46Ovob95YBW
Ph/8+xwE/wSTyHi81OZVq9qsGs2Ye8sW4srPJy6JhDgTE4kzOpo4IyKIMyyMOLhcX9Py5R4lj0cPtAKs
BBwwKfc7p174J5BEhHY9FIk6bBDaIRuiQkDFfsLDSbdU+pdBKPwe8e+BNDBD7vdNn6BYd+6stK5da7bP
nz9TDujcoEAw1lJY+CyFz9dCHDubnDJjwltRccS5fr3TjurnlIMBYE5NJY8Nhq7SrCwREsz6xL9y4S4v
b3Bt2uSyR0XNkDvQe9ouKu8HvaGh5FfQIxL5OgyG30qUStqmGUkm/3jKy0+48vLcs1XuiI8nL/Ly/rYl
JfmovCcgN4JW+l8iGe8oKuoqzcyckSQob3CpVB47l+sXv9KWxYtJt0r1x9ns7HZjQYHNnJxMfoH0EXgA
7oFm0CmTjRsNhs6Na9bQF+Tkq57xlJXVu9Rqz9Bs8kWLSG9BwcsqieQONlXnpaaWdul0z7rR+6C8CTSC
m8Aol4+36/XGT7VaevCRIIRx6/WWoQULZq2cyveLxY0IrAT0IHm1OTmZT3Q6U2da2qT8B/Ad+BZ05OSM
GXW6p4hdBiIZZ1FRt5vPn6vyuwiqCsj9Xyq6qXbDBkWnXm/6OS3NN1X+dUgIeZSdPXZPoxlEXC6IY9pL
S7faNBqXC9Iplf95YBb5ZF+RpGbdunQcbO/D1avJ9YC8LT19/Iv8/BeqpKRPEDORAGNeY3HxSYtG43Eq
FL5etfpljUzWhPlZ5VOTlGVliR+hHUbs+0mpHP9GpRqM5XAuY20zmGgRRohYKIx9rNd/3qfTOa7l5uLu
C63BvARw6fp0eRCMyBslJe8+2bx58EFhoVMlFNJvgQ4kgggQEgykvV0ApEAd+J3z8Z8KxmuA3pr0zikA
b4LJZ2FqYBigFdOPNf0NC679Fxi0OPr+XxiAJgwURph/AJfOQQebMR8TAAAAAElFTkSuQmCC
</value>
</data>
<data name="BTT_DELETE_FILE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAVoSURBVEhLhZVrTJNXGMdfrtNSQIoadKRz2o0CorU3
WkDIVBRaaGNbwAteh+AARRQlitEYTTRekiX7sH3YPmyZH9wtziybigLRCWTaCW5sCBWhlrb0Ci9zSxbo
2f+UliGX7SS/tO85z/k9T57zXhhCCPO7Wh3VIhB83JKQ0Nu4bNlHm5YseZ1hmHC69n+Y5HLFcz7/ft/S
pY+vr1hhwL4oEBJcZ0x793If5uZ+1VNfT/qvXCHP6+p8tzMymqRxcW8hMGKqbDo9MlmWddu2AfbiRTJ6
+TIZKC52fyAUVi2JiYkLJmGaBYIPnx4+TPrOnCH9p08TC4LNx46RWwrF/ZXR0W/PleRZZuY669atZvbS
JcJiL9vQQEZPnSKmwkLPjcTE97GPB8KZlvh4C5X31dWRgRMniAVBtvPnyWB9ve+2XP7jmtjYpOlJTOnp
G60lJRZaOZWPQs4ePUpGUZh3xw7SnJDQhT0KEM3c5fOv9paVkX4kMAPL8ePEig1D584RG9rVpFS2rY6J
EQaTmKTSjbbiYsvIhQuERTGjKIrFvtHaWjK8fz9plsudexYu/BLxKsBj9ALBGzel0vt9e/b4XiBoENhQ
zRDOxIWWOY4cIS0KRZs4Nja5QyLJtRoM1pGzZ/0tYVExi/ayNTVkBPJ76enuJA7nM4j3gVWAHjgTIYqL
E96SStvMu3YR64EDxF5dTYYOHSJOJPNA5Kiu9rUrlZ1mrdbCnjzpr5jFGotYtqpqQi6TuVM4nKvwlYHU
gDzU31OMSGl8fPJtsbjVsn27z15RQRzAVVlJ3BB4kcx78CAZQbUjVIxrFtd+OdrbmpHhEXG5VE4rTwHz
wMRdFDw4jEgFj5dyRyRqsxYVEcfu3cQFPPv2ES8qHEbCYRzgsFZLvO+8Q7xKJXGDVoXCK46Ovob95YBW
Ph/8+xwE/wSTyHi81OZVq9qsGs2Ye8sW4srPJy6JhDgTE4kzOpo4IyKIMyyMOLhcX9Py5R4lj0cPtAKs
BBwwKfc7p174J5BEhHY9FIk6bBDaIRuiQkDFfsLDSbdU+pdBKPwe8e+BNDBD7vdNn6BYd+6stK5da7bP
nz9TDujcoEAw1lJY+CyFz9dCHDubnDJjwltRccS5fr3TjurnlIMBYE5NJY8Nhq7SrCwREsz6xL9y4S4v
b3Bt2uSyR0XNkDvQe9ouKu8HvaGh5FfQIxL5OgyG30qUStqmGUkm/3jKy0+48vLcs1XuiI8nL/Ly/rYl
JfmovCcgN4JW+l8iGe8oKuoqzcyckSQob3CpVB47l+sXv9KWxYtJt0r1x9ns7HZjQYHNnJxMfoH0EXgA
7oFm0CmTjRsNhs6Na9bQF+Tkq57xlJXVu9Rqz9Bs8kWLSG9BwcsqieQONlXnpaaWdul0z7rR+6C8CTSC
m8Aol4+36/XGT7VaevCRIIRx6/WWoQULZq2cyveLxY0IrAT0IHm1OTmZT3Q6U2da2qT8B/Ad+BZ05OSM
GXW6p4hdBiIZZ1FRt5vPn6vyuwiqCsj9Xyq6qXbDBkWnXm/6OS3NN1X+dUgIeZSdPXZPoxlEXC6IY9pL
S7faNBqXC9Iplf95YBb5ZF+RpGbdunQcbO/D1avJ9YC8LT19/Iv8/BeqpKRPEDORAGNeY3HxSYtG43Eq
FL5etfpljUzWhPlZ5VOTlGVliR+hHUbs+0mpHP9GpRqM5XAuY20zmGgRRohYKIx9rNd/3qfTOa7l5uLu
C63BvARw6fp0eRCMyBslJe8+2bx58EFhoVMlFNJvgQ4kgggQEgykvV0ApEAd+J3z8Z8KxmuA3pr0zikA
b4LJZ2FqYBigFdOPNf0NC679Fxi0OPr+XxiAJgwURph/AJfOQQebMR8TAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,471 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports SCrawler.API.YouTube
Imports SCrawler.API.YouTube.Objects
Imports SCrawler.API.YouTube.Controls
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Forms.Toolbars
Namespace DownloadObjects.STDownloader
Public Delegate Sub MediaItemEventHandler(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
<DefaultEvent("DoubleClick"), DesignTimeVisible(False), ToolboxItem(False)>
Public Class MediaItem : Implements ISupportInitialize
#Region "Events"
Public Event DownloadStarted As MediaItemEventHandler
Public Event FileDownloaded As MediaItemEventHandler
Public Event Removal As MediaItemEventHandler
Public Event DownloadAgain As MediaItemEventHandler
Public Event DownloadRequested As MediaItemEventHandler
Public Event CheckedChanged As MediaItemEventHandler
#End Region
#Region "Declarations"
#Region "Controls"
Private WithEvents TP_CONTROLS As TableLayoutPanel
Private WithEvents TP_PROGRESS As TableLayoutPanel
Private WithEvents ICON_SITE As PictureBox
Private WithEvents ICON_CLOCK As PictureBox
Private WithEvents ICON_WHAT As PictureBox
Private WithEvents LBL_TIME As Label '54
Private WithEvents ICON_SIZE As PictureBox
Private WithEvents LBL_SIZE As Label '68
Private WithEvents LBL_INFO As Label
Private WithEvents LBL_PROGRESS As Label
Private WithEvents PR_MAIN As ProgressBar
#End Region
Private ReadOnly BindedControls As List(Of MediaItem)
<Browsable(False)> Public Property MyContainer As IYouTubeMediaContainer
Private ReadOnly Property MyProgress As MyProgress
<Browsable(False)> Public Property UseCookies As Boolean
<Browsable(False)> Public Property Pending As Boolean = False
<Browsable(False)> Public Property Checked As Boolean
Get
Return ControlInvokeFast(CH_CHECKED, Function() CH_CHECKED.Checked, False, EDP.ReturnValue)
End Get
Set(ByVal _Checked As Boolean)
ControlInvokeFast(CH_CHECKED, Sub() CH_CHECKED.Checked = _Checked, EDP.None)
End Set
End Property
<Browsable(False)> Public Property IgnoreDownloadState As Boolean = False
Private ReadOnly FileOption As SFO = SFO.File
#End Region
#Region "Initializers"
Public Sub New()
InitializeComponent()
BindedControls = New List(Of MediaItem)
CreateLabel(LBL_PROGRESS)
PR_MAIN = New ProgressBar With {.Anchor = AnchorStyles.Left + AnchorStyles.Right, .Size = New Size(.Size.Width, 18), .ContextMenuStrip = CONTEXT_MAIN}
TP_CONTROLS = New TableLayoutPanel With {.Dock = DockStyle.Fill, .ContextMenuStrip = CONTEXT_MAIN}
TP_PROGRESS = New TableLayoutPanel With {.Dock = DockStyle.Fill, .ContextMenuStrip = CONTEXT_MAIN}
With TP_PROGRESS
With .ColumnStyles
.Add(New ColumnStyle(SizeType.Percent, 40))
.Add(New ColumnStyle(SizeType.Percent, 60))
End With
.ColumnCount = .ColumnStyles.Count
.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
.RowCount = .RowStyles.Count
.Controls.Add(PR_MAIN, 0, 0)
.Controls.Add(LBL_PROGRESS, 1, 0)
End With
With TP_CONTROLS
.RowStyles.Add(New RowStyle(SizeType.Percent, 100))
.RowCount = .RowStyles.Count
End With
CreateIcon(ICON_SITE)
CreateIcon(ICON_WHAT)
CreateIcon(ICON_CLOCK, My.Resources.ClockPic_16)
CreateLabel(LBL_TIME)
CreateIcon(ICON_SIZE, My.Resources.RulerPic_32)
CreateLabel(LBL_SIZE)
CreateLabel(LBL_INFO)
MyProgress = New MyProgress(PR_MAIN, LBL_PROGRESS)
End Sub
Private Sub CreateLabel(ByRef LBL As Label)
LBL = New Label With {
.Text = String.Empty,
.Margin = New Padding(0),
.AutoSize = False,
.Dock = DockStyle.Fill,
.TextAlign = ContentAlignment.MiddleLeft,
.Font = New Font("Arial", 9, FontStyle.Bold, GraphicsUnit.Point, 204),
.ForeColor = ForeColorLabels,
.ContextMenuStrip = CONTEXT_MAIN
}
End Sub
Private Sub CreateIcon(ByRef Obj As PictureBox, Optional ByVal Image As Image = Nothing)
Obj = New PictureBox With {
.Margin = New Padding(3),
.BackgroundImageLayout = ImageLayout.Zoom,
.SizeMode = PictureBoxSizeMode.Zoom,
.Dock = DockStyle.Fill,
.Image = Image,
.ContextMenuStrip = CONTEXT_MAIN
}
End Sub
Public Sub New(ByVal Container As IYouTubeMediaContainer)
Me.New
Const d$ = " " & ChrW(183) & " "
MyContainer = Container
MyContainer.Progress = MyProgress
If MyContainer.HasElements Then FileOption = SFO.Path Else FileOption = SFO.File
If Not MyContainer.SiteKey = YouTubeSiteKey Then
BTT_DOWN_AGAIN.Visible = False
SEP_DOWN_AGAIN.Visible = False
End If
ICON_SITE.Image = MyContainer.SiteIcon
LBL_TIME.Text = AConvert(Of String)(Container.Duration, TimeToStringProvider, String.Empty)
LBL_TITLE.Text = Container.ToString(True)
If Not Container.SiteKey = YouTubeSiteKey And Container.ContentType = Plugin.UserMediaTypes.Picture Then
LBL_INFO.Text = Container.File.Extension.StringToUpper
ElseIf Not Container.IsMusic Then
If Container.Height > 0 Then
LBL_INFO.Text = $"{Container.File.Extension.StringToUpper}{d}{Container.Height}p"
Else
LBL_INFO.Text = Container.File.Extension.StringToUpper
End If
Else
If Container.Bitrate > 0 Then
LBL_INFO.Text = $"{Container.File.Extension.StringToUpper}{d}{Container.Bitrate}k"
Else
LBL_INFO.Text = Container.File.Extension.StringToUpper
End If
End If
UpdateMediaIcon()
End Sub
#End Region
#Region "Control handlers"
Private Sub MediaItem_Load(sender As Object, e As EventArgs) Handles Me.Load
RefillControls()
End Sub
Private Sub MediaItem_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
BindedControls.Clear()
MyProgress.Dispose()
ICON_SITE.Dispose()
ICON_CLOCK.Dispose()
ICON_WHAT.Dispose()
LBL_TIME.Dispose()
ICON_SIZE.Dispose()
LBL_SIZE.Dispose()
LBL_INFO.Dispose()
LBL_PROGRESS.Dispose()
PR_MAIN.Dispose()
TP_CONTROLS.Controls.Clear()
TP_CONTROLS.Dispose()
TP_PROGRESS.Controls.Clear()
TP_PROGRESS.Dispose()
End Sub
#End Region
#Region "RefillControls"
Private Sub UpdateMediaIcon()
ControlInvokeFast(Me, Sub()
With MyContainer
If Not .SiteKey = YouTubeSiteKey And .ContentType = Plugin.UserMediaTypes.Picture Then
ICON_WHAT.Image = My.Resources.ImagePic_32
ElseIf Not .IsMusic Then
ICON_WHAT.Image = My.Resources.VideoCamera_32
Else
ICON_WHAT.Image = My.Resources.AudioMusic_32
End If
End With
End Sub, EDP.None)
End Sub
Private Sub RefillControls()
ControlInvokeFast(Me, AddressOf RefillControlsImpl, EDP.None)
End Sub
Private Sub RefillControlsImpl()
With MyContainer
If ICON_VIDEO.Image Is Nothing Then
If .ThumbnailFile.Exists Then
ICON_VIDEO.Image = ImageRenderer.GetImage(SFile.GetBytes(.ThumbnailFile, EDP.ReturnValue), EDP.ReturnValue)
ElseIf Not .ThumbnailUrlMedia.IsEmptyString Then
ICON_VIDEO.Image = ImageRenderer.GetImage(SFile.GetBytesFromNet(.ThumbnailUrlMedia, EDP.ReturnValue), EDP.ReturnValue)
End If
End If
Dim s%, t%
Dim sv% = .Size / 1024
If sv >= 1000 Then
LBL_SIZE.Text = AConvert(Of String)(sv / 1024, VideoSizeProvider)
LBL_SIZE.Text &= " GB"
Else
LBL_SIZE.Text = AConvert(Of String)(sv, VideoSizeProvider)
LBL_SIZE.Text &= " MB"
End If
If .Size > 0 Then
s = MeasureTextDefault(LBL_SIZE.Text, LBL_SIZE.Font).Width
Else
s = 0
End If
If .Duration.TotalSeconds > 0 Then
t = MeasureTextDefault(LBL_TIME.Text, LBL_TIME.Font).Width
Else
t = 0
End If
LBL_TITLE.Text = MyContainer.ToString(True)
If Not .SiteKey = YouTubeSiteKey Then BTT_VIEW_SETTINGS.Visible = False
With TP_CONTROLS
.Controls.Clear()
.ColumnStyles.Clear()
.ColumnCount = 0
If IgnoreDownloadState Or MyContainer.MediaState = Plugin.UserMediaStates.Downloaded Then
If Not MyContainer.SiteKey = YouTubeSiteKey Then UpdateMediaIcon()
If IgnoreDownloadState Then
BTT_OPEN_FOLDER.Visible = False
SEP_FOLDER.Visible = False
BTT_DOWN_AGAIN.Visible = False
SEP_DOWN_AGAIN.Visible = False
BTT_REMOVE_FROM_LIST.Visible = False
BTT_DELETE_FILE.Visible = False
SEP_DEL.Visible = False
End If
BTT_DOWN.Visible = False
SEP_DOWN.Visible = False
BTT_VIEW_SETTINGS.Visible = False
With .ColumnStyles
.Add(New ColumnStyle(SizeType.Absolute, 30))
.Add(New ColumnStyle(SizeType.Absolute, 30))
.Add(New ColumnStyle(SizeType.Absolute, IIf(t = 0, 0, 30)))
.Add(New ColumnStyle(SizeType.Absolute, t))
.Add(New ColumnStyle(SizeType.Absolute, IIf(s = 0, 0, 30)))
.Add(New ColumnStyle(SizeType.Absolute, s))
.Add(New ColumnStyle(SizeType.Percent, 100))
End With
.ColumnCount = .ColumnStyles.Count
With .Controls
.Add(ICON_SITE, 0, 0)
.Add(ICON_WHAT, 1, 0)
If t > 0 Then
.Add(ICON_CLOCK, 2, 0)
.Add(LBL_TIME, 3, 0)
End If
If s > 0 Then
.Add(ICON_SIZE, 4, 0)
.Add(LBL_SIZE, 5, 0)
End If
.Add(LBL_INFO, 6, 0)
End With
Else
With .ColumnStyles
.Add(New ColumnStyle(SizeType.Absolute, 100))
.Add(New ColumnStyle(SizeType.Percent, 100))
End With
.ColumnCount = .ColumnStyles.Count
With .Controls
.Add(PR_MAIN, 0, 0)
.Add(LBL_PROGRESS, 1, 0)
End With
End If
End With
TP_INFO.Controls.Add(TP_CONTROLS, 0, 1)
BTT_OPEN_FOLDER.Enabled = .File.Exists(FileOption, False)
BTT_DELETE_FILE.Enabled = BTT_OPEN_FOLDER.Enabled
End With
End Sub
#End Region
#Region "Context buttons' handlers"
Public Sub AddToQueue()
ControlInvokeFast(Me, Sub()
Pending = True
BTT_DOWN.Visible = False
SEP_DOWN.Visible = False
End Sub, EDP.None)
End Sub
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
RaiseEvent DownloadRequested(Me, MyContainer)
End Sub
Public Sub Download(ByVal Token As Threading.CancellationToken)
Try
If Not MyContainer Is Nothing Then
RaiseEvent DownloadStarted(Me, MyContainer)
AddToQueue()
MyContainer.Download(UseCookies, Token)
MyContainer.Save()
Pending = False
RefillControls()
RaiseEvent FileDownloaded(Me, MyContainer)
End If
Catch dex As ObjectDisposedException When MyContainer.IsDisposed
Catch oex As OperationCanceledException When Token.IsCancellationRequested
Throw oex
Catch ex As Exception
ErrorsDescriber.Execute(EDP.SendToLog, ex, $"MediaItem.Download:{vbCr}{MyContainer.ToString}{vbCr}{MyContainer.URL})")
Finally
Pending = False
End Try
End Sub
#End Region
#Region "Colors"
Private ReadOnly ForeColorLabels As Color = SystemColors.ControlDark
Private ForeColorDefault As Color
Public Overrides Property ForeColor As Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal c As Color)
ForeColorDefault = c
MyBase.ForeColor = c
End Set
End Property
Private BackColorDefault As Color
Public Overrides Property BackColor As Color
Get
Return MyBase.BackColor
End Get
Set(ByVal c As Color)
BackColorDefault = c
MyBase.BackColor = c
End Set
End Property
Private IsActiveControl As Boolean = False
Private Sub DropColor()
IsActiveControl = False
MyBase.BackColor = BackColorDefault
MyBase.ForeColor = ForeColorDefault
ChangeLabelsColor(ForeColorLabels)
End Sub
Private Sub ChangeLabelsColor(ByVal ForeColor As Color)
ControlInvokeFast(Me, Sub()
LBL_TIME.ForeColor = ForeColor
LBL_SIZE.ForeColor = ForeColor
LBL_INFO.ForeColor = ForeColor
LBL_PROGRESS.ForeColor = ForeColor
End Sub, EDP.None)
End Sub
#End Region
#Region "Click handlers"
Public Sub PerformClick()
Controls_Click(Me, EventArgs.Empty)
End Sub
Private Sub Controls_Click(sender As Object, e As EventArgs) Handles ICON_VIDEO.MouseClick, CH_CHECKED.MouseClick, LBL_TITLE.MouseClick, TP_INFO.MouseClick,
TP_CONTROLS.MouseClick, TP_PROGRESS.MouseClick, ICON_SITE.MouseClick, ICON_CLOCK.MouseClick,
ICON_WHAT.MouseClick, LBL_TIME.MouseClick, ICON_SIZE.MouseClick, LBL_INFO.MouseClick,
LBL_PROGRESS.MouseClick, PR_MAIN.MouseClick, CONTEXT_MAIN.Opened
IsActiveControl = True
MyBase.BackColor = SystemColors.Highlight
MyBase.ForeColor = SystemColors.HighlightText
ChangeLabelsColor(SystemColors.HighlightText)
BindedControls.ForEach(Sub(c) c.DropColor())
OnClick(e)
End Sub
Private Sub Controls_DoubleClick(sender As Object, e As EventArgs) Handles ICON_VIDEO.DoubleClick, LBL_TITLE.DoubleClick, TP_INFO.DoubleClick,
TP_CONTROLS.DoubleClick, TP_PROGRESS.DoubleClick, ICON_SITE.DoubleClick, ICON_CLOCK.DoubleClick,
ICON_WHAT.DoubleClick, LBL_TIME.DoubleClick, ICON_SIZE.DoubleClick, LBL_INFO.DoubleClick,
LBL_PROGRESS.DoubleClick, PR_MAIN.DoubleClick
Controls_Click(sender, e)
If Not IgnoreDownloadState AndAlso Not MyDownloaderSettings.OnItemDoubleClick = DoubleClickBehavior.None Then
Dim m As New MMessage("The specified path was not found.", "Open file/folder",, vbExclamation)
If MyDownloaderSettings.OnItemDoubleClick = DoubleClickBehavior.File Then
If FileOption = SFO.File And MyContainer.File.Exists(SFO.File, False) Then
MyContainer.File.Open(SFO.File,, EDP.ShowMainMsg)
ElseIf MyContainer.File.Exists(SFO.Path, False) Then
GlobalOpenPath(MyContainer.File, EDP.ShowMainMsg)
Else
m.Show()
End If
Else
If MyContainer.File.Exists(SFO.Path, False) Then MyContainer.File.Open(SFO.Path,, EDP.ShowMainMsg) Else m.Show()
End If
End If
OnDoubleClick(e)
End Sub
Private Sub CH_CHECKED_CheckedChanged(sender As Object, e As EventArgs) Handles CH_CHECKED.CheckedChanged
RaiseEvent CheckedChanged(Me, MyContainer)
End Sub
Protected Overrides Function ProcessDialogKey(ByVal KeyData As Keys) As Boolean
If IsActiveControl Then
If KeyData = Keys.Down Or KeyData = Keys.Up Then
OnKeyDown(New KeyEventArgs(KeyData))
Return True
Else
Return MyBase.ProcessDialogKey(KeyData)
End If
Else
Return False
End If
End Function
#End Region
#Region "Context buttons' handlers"
Private Sub BTT_OPEN_FOLDER_Click(sender As Object, e As EventArgs) Handles BTT_OPEN_FOLDER.Click
If MyContainer.File.Exists(FileOption, False) Then GlobalOpenPath(MyContainer.File)
End Sub
Private Sub BTT_COPY_LINK_Click(sender As Object, e As EventArgs) Handles BTT_COPY_LINK.Click
If Not MyContainer.URL.IsEmptyString Then
BufferText = MyContainer.URL
Else
MsgBoxE({"Media URL is not found", "Copy media URL"}, vbExclamation)
End If
End Sub
Private Sub BTT_OPEN_IN_BROWSER_Click(sender As Object, e As EventArgs) Handles BTT_OPEN_IN_BROWSER.Click
If Not MyContainer.URL_BASE.IsEmptyString Then
Try : Process.Start(MyContainer.URL_BASE) : Catch : End Try
Else
MsgBoxE({"Media URL is not found", "Open link in browser"}, vbExclamation)
End If
End Sub
Private Sub BTT_DOWN_AGAIN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN_AGAIN.Click
RaiseEvent DownloadAgain(Me, MyContainer)
End Sub
Private Sub BTT_VIEW_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_VIEW_SETTINGS.Click
If Not MyContainer Is Nothing Then
Dim f As Form = Nothing
Select Case MyContainer.ObjectType
Case Base.YouTubeMediaType.Single : f = New VideoOptionsForm(MyContainer, True)
Case Base.YouTubeMediaType.Channel, Base.YouTubeMediaType.PlayList
If MyContainer.IsMusic Then
f = New MusicPlaylistsForm(MyContainer)
Else
f = New VideoOptionsForm(MyContainer, True)
End If
End Select
If Not f Is Nothing Then
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then MyContainer.Save()
f.Dispose()
End If
End If
End Sub
Private Sub BTT_REMOVE_FROM_LIST_Click(sender As Object, e As EventArgs) Handles BTT_REMOVE_FROM_LIST.Click
RaiseEvent Removal(Me, MyContainer)
End Sub
Private Sub BTT_DELETE_FILE_Click(sender As Object, e As EventArgs) Handles BTT_DELETE_FILE.Click
If MsgBoxE({$"Are you sure you want to delete the following {FileOption.ToString.ToLower}:{vbCr}" &
If(FileOption = SFO.File, MyContainer.File.ToString, MyContainer.File.PathWithSeparator),
$"Deleting a {FileOption.ToString.ToLower}"}, vbExclamation,,, {"Process", "Cancel"}) = 0 Then
MyContainer.Delete(True)
RaiseEvent Removal(Me, MyContainer)
End If
End Sub
#End Region
#Region "ISupportInitialize Support"
Public Sub BeginInit() Implements ISupportInitialize.BeginInit
End Sub
Public Sub EndInit() Implements ISupportInitialize.EndInit
If Not Parent Is Nothing AndAlso TypeOf Parent Is TableLayoutPanel Then
With DirectCast(Parent, TableLayoutPanel)
If .Controls.Count > 0 Then
For Each cnt As Control In .Controls
If Not cnt Is Nothing AndAlso TypeOf cnt Is MediaItem AndAlso Not cnt Is Me Then
With DirectCast(cnt, MediaItem)
If Not BindedControls.Contains(cnt) Then BindedControls.Add(cnt)
End With
End If
Next
End If
End With
End If
End Sub
#End Region
End Class
End Namespace

View File

@@ -0,0 +1,32 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports PersonalUtilities.Tools.Notifications
Namespace DownloadObjects.STDownloader
Public Interface INotificator
Sub Clear()
Sub ShowNotification(ByVal Text As String, ByVal Image As SFile)
End Interface
Friend Class YTNotificator : Implements INotificator
Private WithEvents Notificator As NotificationsManager
Private ReadOnly Property SourceForm As Form
Friend Sub New(ByRef Source As Form)
Notificator = New NotificationsManager
SourceForm = Source
End Sub
Friend Sub Clear() Implements INotificator.Clear
Notificator.Clear()
End Sub
Friend Sub ShowNotification(ByVal Text As String, ByVal Image As SFile) Implements INotificator.ShowNotification
If MyDownloaderSettings.ShowNotifications Then Notification.ShowNotification(Text,,, Image)
End Sub
Private Sub Notificator_OnClicked(ByVal Key As String) Handles Notificator.OnClicked
SourceForm.FormShowS
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,20 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace DownloadObjects.STDownloader
Public Module STDownloaderDeclarations
Public Const DownloaderDataFolder As String = "Settings\DownloaderData\"
Public Enum DoubleClickBehavior As Integer
None = SFO.None
Folder = SFO.Path
File = SFO.File
End Enum
Public Property MyNotificator As INotificator
Public Property MyDownloaderSettings As IDownloaderSettings
End Module
End Namespace

View File

@@ -0,0 +1,309 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Namespace DownloadObjects.STDownloader
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Public Class VideoListForm : Inherits System.Windows.Forms.Form
<System.Diagnostics.DebuggerNonUserCode()>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing AndAlso components IsNot Nothing Then
components.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Private components As System.ComponentModel.IContainer
<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent()
Dim SEP_2 As System.Windows.Forms.ToolStripSeparator
Dim SEP_3 As System.Windows.Forms.ToolStripSeparator
Dim MENU_ADD_SEP_1 As System.Windows.Forms.ToolStripSeparator
Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(VideoListForm))
Me.TOOLBAR_BOTTOM = New System.Windows.Forms.StatusStrip()
Me.PR_MAIN = New System.Windows.Forms.ToolStripProgressBar()
Me.LBL_INFO = New System.Windows.Forms.ToolStripStatusLabel()
Me.TP_CONTROLS = New System.Windows.Forms.TableLayoutPanel()
Me.TOOLBAR_TOP = New System.Windows.Forms.ToolStrip()
Me.BTT_SETTINGS = New System.Windows.Forms.ToolStripButton()
Me.SEP_1 = New System.Windows.Forms.ToolStripSeparator()
Me.MENU_ADD = New System.Windows.Forms.ToolStripDropDownButton()
Me.BTT_ADD = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
Me.BTT_ADD_PLS_ARR = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
Me.BTT_ADD_NO_SHORTS = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
Me.BTT_ADD_SHORTS_ONLY = New PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick()
Me.BTT_DOWN = New System.Windows.Forms.ToolStripButton()
Me.BTT_STOP = New System.Windows.Forms.ToolStripButton()
Me.BTT_DELETE = New System.Windows.Forms.ToolStripButton()
Me.BTT_CLEAR_DONE = New System.Windows.Forms.ToolStripButton()
Me.BTT_CLEAR_ALL = New System.Windows.Forms.ToolStripButton()
Me.SEP_LOG = New System.Windows.Forms.ToolStripSeparator()
Me.BTT_LOG = New System.Windows.Forms.ToolStripButton()
Me.BTT_INFO = New System.Windows.Forms.ToolStripButton()
Me.BTT_DONATE = New System.Windows.Forms.ToolStripButton()
SEP_2 = New System.Windows.Forms.ToolStripSeparator()
SEP_3 = New System.Windows.Forms.ToolStripSeparator()
MENU_ADD_SEP_1 = New System.Windows.Forms.ToolStripSeparator()
Me.TOOLBAR_BOTTOM.SuspendLayout()
Me.TOOLBAR_TOP.SuspendLayout()
Me.SuspendLayout()
'
'SEP_2
'
SEP_2.Name = "SEP_2"
SEP_2.Size = New System.Drawing.Size(6, 25)
'
'SEP_3
'
SEP_3.Name = "SEP_3"
SEP_3.Size = New System.Drawing.Size(6, 25)
'
'MENU_ADD_SEP_1
'
MENU_ADD_SEP_1.Name = "MENU_ADD_SEP_1"
MENU_ADD_SEP_1.Size = New System.Drawing.Size(181, 6)
'
'TOOLBAR_BOTTOM
'
Me.TOOLBAR_BOTTOM.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.PR_MAIN, Me.LBL_INFO})
Me.TOOLBAR_BOTTOM.Location = New System.Drawing.Point(0, 439)
Me.TOOLBAR_BOTTOM.Name = "TOOLBAR_BOTTOM"
Me.TOOLBAR_BOTTOM.Size = New System.Drawing.Size(584, 22)
Me.TOOLBAR_BOTTOM.TabIndex = 0
'
'PR_MAIN
'
Me.PR_MAIN.Name = "PR_MAIN"
Me.PR_MAIN.Size = New System.Drawing.Size(200, 16)
'
'LBL_INFO
'
Me.LBL_INFO.Name = "LBL_INFO"
Me.LBL_INFO.Size = New System.Drawing.Size(0, 17)
'
'TP_CONTROLS
'
Me.TP_CONTROLS.AutoScroll = True
Me.TP_CONTROLS.BackColor = System.Drawing.SystemColors.Window
Me.TP_CONTROLS.ColumnCount = 1
Me.TP_CONTROLS.ColumnStyles.Add(New System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100.0!))
Me.TP_CONTROLS.Dock = System.Windows.Forms.DockStyle.Fill
Me.TP_CONTROLS.Location = New System.Drawing.Point(0, 25)
Me.TP_CONTROLS.Name = "TP_CONTROLS"
Me.TP_CONTROLS.RowCount = 1
Me.TP_CONTROLS.RowStyles.Add(New System.Windows.Forms.RowStyle())
Me.TP_CONTROLS.Size = New System.Drawing.Size(584, 414)
Me.TP_CONTROLS.TabIndex = 0
'
'TOOLBAR_TOP
'
Me.TOOLBAR_TOP.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden
Me.TOOLBAR_TOP.Items.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_SETTINGS, Me.SEP_1, Me.MENU_ADD, SEP_2, Me.BTT_DOWN, Me.BTT_STOP, SEP_3, Me.BTT_DELETE, Me.BTT_CLEAR_DONE, Me.BTT_CLEAR_ALL, Me.SEP_LOG, Me.BTT_LOG, Me.BTT_INFO, Me.BTT_DONATE})
Me.TOOLBAR_TOP.Location = New System.Drawing.Point(0, 0)
Me.TOOLBAR_TOP.Name = "TOOLBAR_TOP"
Me.TOOLBAR_TOP.Size = New System.Drawing.Size(584, 25)
Me.TOOLBAR_TOP.TabIndex = 2
'
'BTT_SETTINGS
'
Me.BTT_SETTINGS.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.BTT_SETTINGS.Image = Global.SCrawler.My.Resources.Resources.SettingsPic_16
Me.BTT_SETTINGS.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_SETTINGS.Name = "BTT_SETTINGS"
Me.BTT_SETTINGS.Size = New System.Drawing.Size(23, 22)
Me.BTT_SETTINGS.Text = "Settings"
'
'SEP_1
'
Me.SEP_1.Name = "SEP_1"
Me.SEP_1.Size = New System.Drawing.Size(6, 25)
'
'MENU_ADD
'
Me.MENU_ADD.AutoToolTip = False
Me.MENU_ADD.DropDownItems.AddRange(New System.Windows.Forms.ToolStripItem() {Me.BTT_ADD, Me.BTT_ADD_PLS_ARR, MENU_ADD_SEP_1, Me.BTT_ADD_NO_SHORTS, Me.BTT_ADD_SHORTS_ONLY})
Me.MENU_ADD.Image = CType(resources.GetObject("MENU_ADD.Image"), System.Drawing.Image)
Me.MENU_ADD.ImageTransparentColor = System.Drawing.Color.Magenta
Me.MENU_ADD.Name = "MENU_ADD"
Me.MENU_ADD.Size = New System.Drawing.Size(84, 22)
Me.MENU_ADD.Text = "Add (Ins)"
'
'BTT_ADD
'
Me.BTT_ADD.AutoToolTip = True
Me.BTT_ADD.Image = CType(resources.GetObject("BTT_ADD.Image"), System.Drawing.Image)
Me.BTT_ADD.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_ADD.Name = "BTT_ADD"
Me.BTT_ADD.Size = New System.Drawing.Size(184, 22)
Me.BTT_ADD.Tag = "a"
Me.BTT_ADD.Text = "Add (Ins)"
Me.BTT_ADD.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" &
"dd without downloading."
'
'BTT_ADD_PLS_ARR
'
Me.BTT_ADD_PLS_ARR.AutoToolTip = True
Me.BTT_ADD_PLS_ARR.Image = CType(resources.GetObject("BTT_ADD_PLS_ARR.Image"), System.Drawing.Image)
Me.BTT_ADD_PLS_ARR.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_ADD_PLS_ARR.Name = "BTT_ADD_PLS_ARR"
Me.BTT_ADD_PLS_ARR.Size = New System.Drawing.Size(184, 22)
Me.BTT_ADD_PLS_ARR.Tag = "pls"
Me.BTT_ADD_PLS_ARR.Text = "Add playlist array"
Me.BTT_ADD_PLS_ARR.ToolTipText = "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to a" &
"dd without downloading."
'
'BTT_ADD_NO_SHORTS
'
Me.BTT_ADD_NO_SHORTS.AutoToolTip = True
Me.BTT_ADD_NO_SHORTS.Image = CType(resources.GetObject("BTT_ADD_NO_SHORTS.Image"), System.Drawing.Image)
Me.BTT_ADD_NO_SHORTS.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_ADD_NO_SHORTS.Name = "BTT_ADD_NO_SHORTS"
Me.BTT_ADD_NO_SHORTS.Size = New System.Drawing.Size(184, 22)
Me.BTT_ADD_NO_SHORTS.Tag = "ans"
Me.BTT_ADD_NO_SHORTS.Text = "Add (without Shorts)"
Me.BTT_ADD_NO_SHORTS.ToolTipText = "Download all videos except 'Shorts'." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies fo" &
"r download (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to add without downloading."
'
'BTT_ADD_SHORTS_ONLY
'
Me.BTT_ADD_SHORTS_ONLY.AutoToolTip = True
Me.BTT_ADD_SHORTS_ONLY.Image = CType(resources.GetObject("BTT_ADD_SHORTS_ONLY.Image"), System.Drawing.Image)
Me.BTT_ADD_SHORTS_ONLY.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_ADD_SHORTS_ONLY.Name = "BTT_ADD_SHORTS_ONLY"
Me.BTT_ADD_SHORTS_ONLY.Size = New System.Drawing.Size(184, 22)
Me.BTT_ADD_SHORTS_ONLY.Tag = "as"
Me.BTT_ADD_SHORTS_ONLY.Text = "Add (Shorts only)"
Me.BTT_ADD_SHORTS_ONLY.ToolTipText = "Download only 'Shorts' videos." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Click to add." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Ctrl+click to use cookies for down" &
"load (if supported)." & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "Shift to add without downloading."
'
'BTT_DOWN
'
Me.BTT_DOWN.Image = Global.SCrawler.My.Resources.Resources.StartPic_Green_16
Me.BTT_DOWN.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_DOWN.Name = "BTT_DOWN"
Me.BTT_DOWN.Size = New System.Drawing.Size(81, 22)
Me.BTT_DOWN.Text = "Download"
Me.BTT_DOWN.ToolTipText = "Download pending items (F5)"
'
'BTT_STOP
'
Me.BTT_STOP.AutoToolTip = False
Me.BTT_STOP.Enabled = False
Me.BTT_STOP.Image = CType(resources.GetObject("BTT_STOP.Image"), System.Drawing.Image)
Me.BTT_STOP.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_STOP.Name = "BTT_STOP"
Me.BTT_STOP.Size = New System.Drawing.Size(51, 22)
Me.BTT_STOP.Text = "Stop"
'
'BTT_DELETE
'
Me.BTT_DELETE.Image = CType(resources.GetObject("BTT_DELETE.Image"), System.Drawing.Image)
Me.BTT_DELETE.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_DELETE.Name = "BTT_DELETE"
Me.BTT_DELETE.Size = New System.Drawing.Size(60, 22)
Me.BTT_DELETE.Text = "Delete"
Me.BTT_DELETE.ToolTipText = "Delete selected items"
'
'BTT_CLEAR_DONE
'
Me.BTT_CLEAR_DONE.Image = CType(resources.GetObject("BTT_CLEAR_DONE.Image"), System.Drawing.Image)
Me.BTT_CLEAR_DONE.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_CLEAR_DONE.Name = "BTT_CLEAR_DONE"
Me.BTT_CLEAR_DONE.Size = New System.Drawing.Size(54, 22)
Me.BTT_CLEAR_DONE.Text = "Clear"
Me.BTT_CLEAR_DONE.ToolTipText = "Remove all downloaded items"
'
'BTT_CLEAR_ALL
'
Me.BTT_CLEAR_ALL.Image = CType(resources.GetObject("BTT_CLEAR_ALL.Image"), System.Drawing.Image)
Me.BTT_CLEAR_ALL.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_CLEAR_ALL.Name = "BTT_CLEAR_ALL"
Me.BTT_CLEAR_ALL.Size = New System.Drawing.Size(69, 22)
Me.BTT_CLEAR_ALL.Text = "Clear all"
Me.BTT_CLEAR_ALL.ToolTipText = "Remove all items (pending and downloaded)"
'
'SEP_LOG
'
Me.SEP_LOG.Name = "SEP_LOG"
Me.SEP_LOG.Size = New System.Drawing.Size(6, 25)
'
'BTT_LOG
'
Me.BTT_LOG.AutoToolTip = False
Me.BTT_LOG.Image = CType(resources.GetObject("BTT_LOG.Image"), System.Drawing.Image)
Me.BTT_LOG.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_LOG.Name = "BTT_LOG"
Me.BTT_LOG.Size = New System.Drawing.Size(50, 22)
Me.BTT_LOG.Text = "LOG"
'
'BTT_INFO
'
Me.BTT_INFO.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.BTT_INFO.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.BTT_INFO.Image = Global.SCrawler.My.Resources.Resources.InfoPic_32
Me.BTT_INFO.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_INFO.Name = "BTT_INFO"
Me.BTT_INFO.Size = New System.Drawing.Size(23, 22)
Me.BTT_INFO.ToolTipText = "Show program information and check for updates"
'
'BTT_DONATE
'
Me.BTT_DONATE.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right
Me.BTT_DONATE.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image
Me.BTT_DONATE.Image = Global.SCrawler.My.Resources.Resources.HeartPic_32
Me.BTT_DONATE.ImageTransparentColor = System.Drawing.Color.Magenta
Me.BTT_DONATE.Name = "BTT_DONATE"
Me.BTT_DONATE.Size = New System.Drawing.Size(23, 22)
Me.BTT_DONATE.ToolTipText = "Support"
'
'VideoListForm
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(584, 461)
Me.Controls.Add(Me.TP_CONTROLS)
Me.Controls.Add(Me.TOOLBAR_TOP)
Me.Controls.Add(Me.TOOLBAR_BOTTOM)
Me.Icon = Global.SCrawler.My.Resources.SiteYouTube.YouTubeIcon_32
Me.KeyPreview = True
Me.MinimumSize = New System.Drawing.Size(300, 200)
Me.Name = "VideoListForm"
Me.Text = "YouTube Downloader"
Me.TOOLBAR_BOTTOM.ResumeLayout(False)
Me.TOOLBAR_BOTTOM.PerformLayout()
Me.TOOLBAR_TOP.ResumeLayout(False)
Me.TOOLBAR_TOP.PerformLayout()
Me.ResumeLayout(False)
Me.PerformLayout()
End Sub
Private WithEvents TOOLBAR_BOTTOM As StatusStrip
Private WithEvents PR_MAIN As ToolStripProgressBar
Private WithEvents LBL_INFO As ToolStripStatusLabel
Protected WithEvents TP_CONTROLS As TableLayoutPanel
Private WithEvents TOOLBAR_TOP As ToolStrip
Private WithEvents BTT_DELETE As ToolStripButton
Private WithEvents BTT_CLEAR_DONE As ToolStripButton
Private WithEvents BTT_CLEAR_ALL As ToolStripButton
Private WithEvents BTT_SETTINGS As ToolStripButton
Private WithEvents SEP_1 As ToolStripSeparator
Private WithEvents SEP_LOG As ToolStripSeparator
Private WithEvents BTT_LOG As ToolStripButton
Private WithEvents BTT_STOP As ToolStripButton
Private WithEvents BTT_INFO As ToolStripButton
Private WithEvents BTT_DONATE As ToolStripButton
Protected WithEvents BTT_ADD As PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick
Protected WithEvents BTT_ADD_PLS_ARR As PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick
Protected WithEvents BTT_ADD_NO_SHORTS As PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick
Protected WithEvents BTT_ADD_SHORTS_ONLY As PersonalUtilities.Forms.Controls.KeyClick.ToolStripMenuItemKeyClick
Protected WithEvents MENU_ADD As ToolStripDropDownButton
Protected WithEvents BTT_DOWN As ToolStripButton
End Class
End Namespace

View File

@@ -0,0 +1,369 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="SEP_2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="SEP_3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="MENU_ADD_SEP_1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="TOOLBAR_BOTTOM.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="TOOLBAR_TOP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>177, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="BTT_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN1SURBVEhLrZVJTFNRFIafQhgD1OBUpiiKYg22AopFKggK
FdRYQUEZgsqgGBAChaiYRlG2RuPOuCDGGDcG48phgcQog0KFV4QKKZ2wSIJxf83vuc8SWRAw8E7yp23u
yf/de95/X4Wlyu+eT4f/fR8sJL7mbVt+cSOVWcUyB3U4/EUHvUiy6HDKliVBvG3LL26SMKRiQd0CQj8K
CO8XEPnZF5WuXPkAGlHFwnoErOtfhU2D/vQ7FM2efPkASQTgO481+yNxJAwZoxtwe6ZEPoCWALHmAOwZ
USDHGkHz34p7s1XyAc6LGpZsUSDXGomzk9tRZdfg0a86+QCN4j6m/xaFUvsO1DgS0ehMxZNfxv8DLJbz
OZX2p/8uscej1pGMlikdbnqy0fGzCWufBi4q5fPgDmmHWXMZp3znjepw0pqJMlsOap3HcdV9Cnc8ZfQ9
GdfcB3DLk4O2aT06ZpvweNYogR7O1uHuTAVuTRej2V1AI8xDjb0Qys5gSABuHvqBMt4rIGrQD2qKIU+K
YSIW5+w7ccWZgutTB8lAj/bpXAlw83s2melQ5dDg9EQcssY2Qm0JRfSAHxTkU2gx/APwnXNzvqi2hFCz
Evle83pXClrdmWjz6AmQjRvfM2F0p9GzSEL5pAonxjcjfXQ9EsQQRAz6QtEnIJAuZf6XeYC8ER1iyFxD
O8iyKqUYVjrUaHDtxbWpDLSS6VV3OoyuNNQ796Ca1krtKhwb34QDdFLJfMAX/DJy81WvBRj65gHOWA9B
OxJOMYxCsS0edfQwmygpLWTITRtdqZIaaFTVNBKepqPjMUj7uh47hoOh/OSDEBpxQJcA4RWpkwDv5wEu
iYnMKKYy02gpM41dYCZrNTN9q6LPi8wkXmYPflwi872otKtRNLkNuePRaHGWIb8n43eFuJ+ViFpWREol
aYdIn0m9WiYBeEwXiticeFO72MIqHbtQZIvDETplCp22xlEkrS0qHtOlijeaxAZ2mp5LzlgkkuhGbzEH
otx2UjLxti2//gJqWPZYhPSi42/TcErKWat3xiutv4AKttsShihKyhqKM/9vKJjL+UqLm9SJxSx6wB8K
imHQOwE+byglZhkB5ylh3DyAdr6ax/AlAXpkBBRT/AJp5wJdIOEF6RkBumUEFAwbpJEYekl0gQxdpLdy
ASjL3GhBLZlzQfgD9Y2tq0N6ki0AAAAASUVORK5CYII=
</value>
</data>
<data name="BTT_ADD_PLS_ARR.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN5SURBVEhLrZVJTFNRFIafljBIgBqcymAU54oWGSRCK1oU
KqixAoIyiMqgGBAChYCaOsed0bgzLogxxo3RuHJYqDEqKFD1tUItKZ2gaIJxf8nvuc8SWRAw8E7yp03u
zf+de95/3xNmquCbis6QWwpMJb4W2Db74kaJFjXT9+mw+7MOBpFk1aHImS1BAttmX9xE80XNFrwREPle
QPRHAbE9Qaj25skHSBbVLOqDgMUf52FFXwiSxEi0+gvkA6QRgHeeYAlBsi0KO/qX4srPMvkAmWIiS7CE
Is2mRK49hua/GjfHauQDHBeTWapViTx7LI4MrUONKwl3fzfIB2gWM5jhexzKXRtQ505GsycD93+b/g8w
Xc4ndLQna7zMtR717lS0Detw0Z+Dzl8tWPQgbFqpHoV3Sh1mT2Sc8p3fr8NBux4VzlzUe/aj3VeEq/4K
+p+KDt92XPLn4vKoAZ1jLbg3ZpJAd8YacONnFS6NlqLVV0gjzEedqxiqx+GQANw88h1lvEtAXF8wNBRD
nhTjYAKOuTbijCcdZ4d3koEB10bzJMDFkRwy06HGnYRDg2uQPbAMGmsk4nuDoSSfYqvxH4B3zs35osYa
QZtVKAiYN3rTcc6nx2W/gQA5OD+ih8mnpWeRgsohNQ44ViKrfwk2iRGI6QuCsltAGF3Kgs+TAPk2HZaT
eRJ1kG1XSTGsdmvQ5N2KjuEdOEem7b4smLxaNHrSUEtr5S419jlWYDudVDLvDQK/jNx83nMBxu5JgMP2
Xdhmi6YYxqHUuR4N9DBbKCltZMhNm70ZkppoVLU0Ep6mvY7l0H5bgg1fw6H6pEAEjTj0lQDhGekxAd5O
ApwSU5nJqmVmezkzfz/BzI5aZh6sod+TzCyeZrd/nCLzrah2aVAytBZ5jni0eSpQ1K0frxJ1rEzMZCUk
LSnzC6mH1JXJJACP6VQRmxDfdN3axqrdm1HiXIM9dMp0Om2du0Ram1Y8pjMV33hBbGKH6LnkDsQihW70
KksYKp0HJZPAttkXNzGLdSxnIEZ60fG3aTQl5Yg9MOO51l9AFdtijUIcJWUhxZl/Gwoncj7X4iYNYimL
7w2BkmK44LUAxQtKiUVGwHFRy7h5KHU+n8fwKQE+yAgopfiFUecCXSDhCekhAd7ICCj8apRGYuwi0QUy
viK9lAtAWeZGU2rGnAvCHy5drfKWDYjrAAAAAElFTkSuQmCC
</value>
</data>
<data name="BTT_ADD_NO_SHORTS.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN9SURBVEhLrZVZSFRRGMdvKa6oE5Y1bpTtRY1N5pB407Tu
TFrRpJXlgpVLTWiJTlIZli0QPUTLW/QgEdFLFD21PFREZYtONTON08jsOiYYvp/4953LSD6Iht0P/jBw
Dv/fd77zP3eE6SrqekR39I0ITCa+Ft428+JGOouWFfWJ2PpFhMFKsonY4y6WIeFtMy9ukvdVy+JeC0h8
JyD5o4C0z5GoD5QoBxCtWpb0XsC8j7OwsC8a2dZEnAyVKQcoJADvPMsSDa09CYWO+bg4UqUcQLLqWJYl
BhvsKuidqTT/Jbg+2qAc4JBVZDk2FUqcaTjgWY4GbzbujDUrB2h1bGWGH+mo9q6EyadFqz8P98bM/waY
KufjMjn0v6u8K9Dky0H7oIjzIQndv9ow937slFI/jO+WOywezzjlu9QhYrezCDVuPZr8O3EquAeXQjX0
Oweng5vQFdLjwrAB3aNtuDtqlkG3R5txbaQOXcOVOBkspxGWwuTdB/WjeMgAbp74ljLeIyC9LwoaiiFP
inEgCwe9q3Hcr8OZwc1kYMDl4RIZcH5IIjMRDb5s7B1YiuL+BdDYEpHRGwUV+eyzGf8CeOfcnC9qbAm0
WY2ysPmJgA4dwSJcCBkIIOHsUBHMwXy6i/Wo9azCLtciFDhSsMaagNS+SKg+CIilR1n2ZQKg1C4ik8yz
qYNip1qOYb1Pg5ZALk4PFqKDTE8FC2AO5OOEfwMaaa3auwo7XAuxiU4qm/dGgj9Gbj7rmQDjhwmA/c4t
2GhPphimo9K9As10mW2UlHYy5KatgTxZLTSqRhoJT9N2Vybyv6dg5bd4qD9FIIFGHPNSgPCU9IgAbyYA
jg4UMLNHzzqD1axz8DDrGmpkXaEGdnHoCLviPsZu/TxK5rmo92pQ4VmGElcG2v01qLXt+F3nMLAqm8Qq
rBLTk6SvpM+kHonJAB7TySI2Lr7ppqed1fvWosK9FNvolDo6rclXIa9NKR7T6YpvvOpuYXvpXvT9aVhP
L3qxJRa17t2ySXjbzIubnHOZmNSfKn/o+Nc0mZJywBme8f8WN+nsr2PrbElIp6TMoTjz/4by8Zz/b3GT
Znsly+iNhopiGPdKQMRzSolFQcAhq55x8xjqfDaP4RMCvFcQUEnxi6XOBXpAwmPSAwK8VhBQ/s0oj8TY
Q6IHZHxJeqEUgLLMjSbVtDkXhD9St6/+w21JdAAAAABJRU5ErkJggg==
</value>
</data>
<data name="BTT_ADD_SHORTS_ONLY.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN9SURBVEhLrZVZSFRRGMdvKa6oE5Y1bpTtRY1N5pB407Tu
TFrRpJXlgpVLTWiJTlIZli0QPUTLW/QgEdFLFD21PFREZYtONTON08jsOiYYvp/4953LSD6Iht0P/jBw
Dv/fd77zP3eE6SrqekR39I0ITCa+Ft428+JGOouWFfWJ2PpFhMFKsonY4y6WIeFtMy9ukvdVy+JeC0h8
JyD5o4C0z5GoD5QoBxCtWpb0XsC8j7OwsC8a2dZEnAyVKQcoJADvPMsSDa09CYWO+bg4UqUcQLLqWJYl
BhvsKuidqTT/Jbg+2qAc4JBVZDk2FUqcaTjgWY4GbzbujDUrB2h1bGWGH+mo9q6EyadFqz8P98bM/waY
KufjMjn0v6u8K9Dky0H7oIjzIQndv9ow937slFI/jO+WOywezzjlu9QhYrezCDVuPZr8O3EquAeXQjX0
Oweng5vQFdLjwrAB3aNtuDtqlkG3R5txbaQOXcOVOBkspxGWwuTdB/WjeMgAbp74ljLeIyC9LwoaiiFP
inEgCwe9q3Hcr8OZwc1kYMDl4RIZcH5IIjMRDb5s7B1YiuL+BdDYEpHRGwUV+eyzGf8CeOfcnC9qbAm0
WY2ysPmJgA4dwSJcCBkIIOHsUBHMwXy6i/Wo9azCLtciFDhSsMaagNS+SKg+CIilR1n2ZQKg1C4ik8yz
qYNip1qOYb1Pg5ZALk4PFqKDTE8FC2AO5OOEfwMaaa3auwo7XAuxiU4qm/dGgj9Gbj7rmQDjhwmA/c4t
2GhPphimo9K9As10mW2UlHYy5KatgTxZLTSqRhoJT9N2Vybyv6dg5bd4qD9FIIFGHPNSgPCU9IgAbyYA
jg4UMLNHzzqD1axz8DDrGmpkXaEGdnHoCLviPsZu/TxK5rmo92pQ4VmGElcG2v01qLXt+F3nMLAqm8Qq
rBLTk6SvpM+kHonJAB7TySI2Lr7ppqed1fvWosK9FNvolDo6rclXIa9NKR7T6YpvvOpuYXvpXvT9aVhP
L3qxJRa17t2ySXjbzIubnHOZmNSfKn/o+Nc0mZJywBme8f8WN+nsr2PrbElIp6TMoTjz/4by8Zz/b3GT
Znsly+iNhopiGPdKQMRzSolFQcAhq55x8xjqfDaP4RMCvFcQUEnxi6XOBXpAwmPSAwK8VhBQ/s0oj8TY
Q6IHZHxJeqEUgLLMjSbVtDkXhD9St6/+w21JdAAAAABJRU5ErkJggg==
</value>
</data>
<data name="MENU_ADD.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN8SURBVEhLrZVZSJRRGIZ/U1wSdcK2caMsW6nR3Chm1LRZ
UosmTS2XNpc0tEQnaUPMiugmiu6iC4mIbsLoquXCJCpbdMx/XKapcVbHAqP7E2/f+RvJC9Gw/4MXBs7h
fb7znff8I8xXwTcDu0JuBWI28TX/toUXN8owp7DcAQ20gxoYRJJFgwP2PAni37bw4ibbP6Wwxb0CIt8I
iH4vIPZjEGrc+fIB1GIKi3orYNn7AKwaCEGyGIkzviL5ANkE4J0nmkOwbTgKOaMrcPl7hXwArZjBEs2h
SB9WQG+Nofmvxc2pWvkAx0Q1S7MokG+NxaHx9ah1JOPuzyb5AC0ju5jhcxwqHRvR4NyGFtcO3P9p+jfA
XDmfVv2I7leFYwManWlo82rQ4dOh60crlj4Im1PKR+FdUod50xmnfBeMarDfmosqux6Nrr046zmAK74q
+p2Gc54sXPLp0TlpQNdUK+5NmSTQnakm3PhejUuT5TjjKaYRFqDBUQpldzj+XCKZR76mjPcJiBsIhopi
yJNi/JKIo47NOOXKxHnvTjIw4OpkvgTomNCRmQa1zmSUfElC3thKqCyRiO8PhoJ8Si3GvwDeOTfniypL
BG1WoshvftqdiQueXHT6DATQ4eJELkweNd1FKo6Mb8I+22pkjy7HFjECMQNBULwTEEaPsmhwBqBgWIME
Mk+mDvKsSimGNU4Vmt0ZOOfNwQUyPevJhsmtxmlXOupordKxCXtsq5BFJ5XM+4PAHyM3D3gmwPhuBuCg
dRe2D0dTDONQbt+AJrrMVkpKGxly0xb3DknNNKo6GglPU6EtAeqR5dg4FA7lh0BE0IhDewQIT0ndBHg1
A1Bvy2Imu461uytZu+c46/DWsY6JWtbpPcGufT3Jbn+rJ/MM1DhUKBtfh3xbPNpcVTgsFv6qHtGzClHL
ykg6kvYT6SOpT8skAI/pbBGbFt90y97GapxbUWZPwm46ZSadtsFZJq3NKR7T+YpvvP61mZXQvejHYpFK
L3qNOQxH7PslE/+2hRc3af/cwHRjMdKHjn9Noykph6z+Gf9vSYDRapZiiUIcJWUJxZn/NxRP5/x/i5s0
WcpZfH8IFBTDxS8FBD6nlJhlBBwTdYybh1Lni3gMnxDgrYyAcopfGHUu0AMSHpMeEqBXRkDxkFEaibGP
RA/I2EN6IReAssyNZtW8OReE31w2r8aW2OYjAAAAAElFTkSuQmCC
</value>
</data>
<data name="BTT_STOP.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVFSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcQBQgv01tK6
oSgvUrRgSwUdI2pGxRUUX1CiGI3RRONLsmQftg/bhy0zmXFLdFk2JkjJmMCmCE4wvOmwllL6Cpe9JAv0
7H9KqzOWjSf55fae85z/8+9zzr2XQ6M3Pz/KnJDwSduyZcM3JJKPN4nFr2E4wj/5PzGkVKp+k0jaR5Yu
7bmWmGjAUBQI80/S6DOZ+Lfz878aamggo5cukbv19b4bKlVrlkCwEtORc1mhY4Bh3rZt3/6YPX+eTF+8
SIbLytwfJifXSKKjYzE9V6R1xYqPBg8eJI9OnSKjJ08SK5ItR46QJpWqXSYQvImUkEVG1OoNELewFy4Q
FmvZxkYyfeIEGdRqPd+IxR8gRQgiOG0ikZWKP6qvJ4+PHSNWJI2fPUv6Ghp8N5TKn6QCQRISnyuCthTY
ysut1DkVn4Y4e/gwmYYxb2UlMcfF9SNNBQSclvj4y8NVVWQUBSzAevQosWHBxJkz5AHa1aJSdabx+clI
9hcZkssLxsvKrFPnzhEWZqZhisW66QMHyOSePaRJqXTuEImuIrUICDn65ctfb1Io2rt37fI9QdIYGIeb
CeyJCy1zHDpE2lAkk89Pucsw+WMGg23q9Gl/S1g4ZtFetq6OTEHcnJnpTuLxPoewEcgA3XBOJCMSJaNI
p2XHDmLbu5fYa2vJxP79xIliHggN1tb6utTqew9LSqzs8eN+xyzmWOSyNTVPxVN4vMvQqwKpAfFw4A9u
plCY8oNc3nG/osJnr64mDuAymYgbAl4U8+7bR6bgdooK457FvV8c7e1QKDwyPp+KU+erwGLw7KgGgqsU
Cle1pKd32rZuJY6dO4kLeIxG4oXDSRScxAZOlpQQ7/r1xKtWEzfoyMryZggEV7B+N6DOeeAF8WBwV8fG
prbIZJ392dkz7m3biEujIS6GIU6xmDgFAuKMjCTORYvIIJ/va05I8KhiYuiGVoM08DKYVzwY/nbdlsl6
xyFoh9gEcAAq7CcigvSkp/9lSE7+DvnvAylYkLg/bJWVJptabbHzeC+KAzrWl5g4Y9ZqH6bEx5dgSTRY
mLjXaDzkzM112uF+PvEx8BhYUlNJj07X/86aNRlY+p+vFX+4jMZGx8aNLntU1AviDvSetouKj4Lh8HDS
B37OyPD1lpY+MKhUtE3zF/Hs3n1sorDQHcq5QyQiTwoL/36QlOSj4kMB8W7QAdoZZraX/pP5iuAoNtpz
cz12Pt8v/FxbliwhA0VFv59eu7are/PmcUtKCrkP0TvgFvgRmEHb6tWzvxgM93JlMvqCfPaqd1dVNVDx
iVDicXFkYN26P2oYpgWptYVpae/2Fxc/HEDvg+KtoBk0AbNSOdtVWtr9mVZLN54LwjjuLVusEzExoZ1D
vFoub0aiCdCNFO7PyXmrR68fuSeVPhX/HnwLroNemWzmjl4/iNzlgMux63QDbokkpHMTw9xEUk1APPil
4h7Iy1P1lJaO3JRKff8W/zosjNyRSmfMGs0Y8vJBLKeromL7uEbjckE06LyvoODPvaHFg8Gty8nJwsYO
305PJ9cC4uasrNkvNZonRStXfoqcuQKIxc1lZcetxcWeIZXKR53XKRStGJ9PPBhcY3a2nLYD3wyfWa2e
vQrnr/B4FzGnA3MtQoQxCQnR3Xr9F4+Kix1X8vJw+sLrMM4APp2nSfME93p5+Xu/6nRjt7RaZ2FSEv0W
6IEY0OP6dC39EQMUYFPgutDH/yVAjyY9OZvBGyDkA7cIUMf0Y02v9H4hQU3Q9/+rAWjBgDEO5x9IKtl+
4dDtOAAAAABJRU5ErkJggg==
</value>
</data>
<data name="BTT_DELETE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lFs3
FceLFC3YgqBjRM2ouILiC0oUozGauPiSLNmH7cP2YctMZtwSXdzGhFE3J5ABAg4XBHRYS+l74bKXZJGe
/U9pdcay8SS/3N5znvN//n3OuffyaAwUFkaZEhI+ur5s2eg1mezDDVLpSxiO8E/+T4yoVOxvMtmNsaVL
+y8nJlZgKAqE+SdpDBmNwp7Cwi9GmpvJ+PnzpLOpyXeNZTtyRaKVmI6cywodwwzzunXr1gfcmTNk5tw5
MlpZ6X4/ObleFh0di+m5Ih0rVnxwd/9+cv/ECTJ+/DixINl86BBpZdkbcpHoVaSELDKmVr8BcTN39izh
sJZraSEzx46Ru1qt5yup9D2kiEEE77pEYqHi95uayIMjR4gFSZOnT5Pe5mbfNZXqpwyRKAmJTxVBW4qs
VVUW6pyKz0CcO3iQzMCYt6aGmOLi7iCNBSJee3z8hdHaWjKOAmZgOXyYWLHAfuoUuYV2tbNsV7pQmIxk
f5ERhaJosrLSMv3uu4SDmRmY4rBuZt8+MrVrF2lVqZzbJJJLSC0BYp5++fKXW5XKGzd37PA9RNIEmIQb
O/bEhZY5Dhwg11EkWyhMucUwhRMVFdbpkyf9LeHgmEN7ucZGMg1xU3a2O0kg+BTCBiAHdMN5kYxEkowi
XeZt24h1925ia2gg9r17iRPFPBAabGjwdavVg/fKyizc0aN+xxzmOORy9fWPxVMEggvQqwVpAfFw4A9+
tlic8p1C0dlTXe2z1dURB3AZjcQNAS+KeffsIdNwO02Fcc/h3i+O9nYqlR65UEjFqfNUsBg8OaqB4KvE
4tT2zMwu6+bNxLF9O3EBj8FAvHA4hYJT2MCpsjLiXbeOeNVq4gadubneLJHoItbvBNS5ADwjHgx+Tmxs
Wrtc3jWUk/PIvWULcWk0xMUwxCmVEqdIRJyRkcS5aBEZFAp9bQkJHjYmhm5oHUgHz4N5xYPhb1ePXD4w
CUEbxOzAAaiwn4gI0p+Z+VdFcvI3yH8HZIAFifvDWlNjtKrVZptA8Kw4oGNDiYmPTFrtvZT4+DIsiQYL
E/caDAec+flOG9zPJz4BHgBzWhrp1+nuvLlqVRaW/udrxR8ug6HFsX69yxYV9Yy4A72n7aLi42A0PJwM
gR+ysnwD5eW/VrAsbdP8RTw7dx6xFxe7Qzl3SCTkYXHx37eSknxUfCQg3gc6gYlhZgfoP5mvCI5iiy0/
32MTCv3CT7VlyRIyXFLy+8k1a7r7Nm6cNKekkF8g2gtugh9pAUpOzuzPFRWD+XI5fUE+edW7a2ubqbg9
lHhcHBleu/aPeoZpR2pDcXr6W3dKS+8No/dB8Q7QBlppEZVqtru8vO8TrZZuPB+E8dybNlnsMTGhnUO8
TqFoQ6IR0I0U783Le61frx8bzMh4LP4tuAqugIHU1Ee9ev1d5C4HfJ5Npxt2y2QhnRsZ5nsk1QfEg18q
/r6CAra/vHzs64wM37/FvwwLI70oYNJoJpBXCGJ53dXVWyc1GpcLokHnQ0VFf+4OLR4MfmNeXi42drQn
M5NcDoibcnNnP9doHpasXPkxcuYKIBa3VVYetZSWem6zrI86b1QqOzA+n3gw+IbVqxW0HVexzqRWz16C
8xcEgnOY04G5FiHCmISE6D69/rP7paWOiwUFOH3hjRhngJDO06R5gn+lqurt2zrdxE2t1lmclES/BXog
BfS4Pl5Lf8QAJdgQuC708X8O0KNJT85G8AoI+cAtAtQx/VjTK71fSFAT9P3/YgBaMGCMx/sHyjLY+hqD
P/QAAAAASUVORK5CYII=
</value>
</data>
<data name="BTT_CLEAR_DONE.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lFs3
FceLFC3YgqBjRM2ouILiC0oUozGauPiSLNmH7cP2YctMZtwSXdzGhFE3J5ABAg4XBHRYS+l74bKXZJGe
/U9pdcay8SS/3N5znvN//n3OuffyaAwUFkaZEhI+ur5s2eg1mezDDVLpSxiO8E/+T4yoVOxvMtmNsaVL
+y8nJlZgKAqE+SdpDBmNwp7Cwi9GmpvJ+PnzpLOpyXeNZTtyRaKVmI6cywodwwzzunXr1gfcmTNk5tw5
MlpZ6X4/ObleFh0di+m5Ih0rVnxwd/9+cv/ECTJ+/DixINl86BBpZdkbcpHoVaSELDKmVr8BcTN39izh
sJZraSEzx46Ru1qt5yup9D2kiEEE77pEYqHi95uayIMjR4gFSZOnT5Pe5mbfNZXqpwyRKAmJTxVBW4qs
VVUW6pyKz0CcO3iQzMCYt6aGmOLi7iCNBSJee3z8hdHaWjKOAmZgOXyYWLHAfuoUuYV2tbNsV7pQmIxk
f5ERhaJosrLSMv3uu4SDmRmY4rBuZt8+MrVrF2lVqZzbJJJLSC0BYp5++fKXW5XKGzd37PA9RNIEmIQb
O/bEhZY5Dhwg11EkWyhMucUwhRMVFdbpkyf9LeHgmEN7ucZGMg1xU3a2O0kg+BTCBiAHdMN5kYxEkowi
XeZt24h1925ia2gg9r17iRPFPBAabGjwdavVg/fKyizc0aN+xxzmOORy9fWPxVMEggvQqwVpAfFw4A9+
tlic8p1C0dlTXe2z1dURB3AZjcQNAS+KeffsIdNwO02Fcc/h3i+O9nYqlR65UEjFqfNUsBg8OaqB4KvE
4tT2zMwu6+bNxLF9O3EBj8FAvHA4hYJT2MCpsjLiXbeOeNVq4gadubneLJHoItbvBNS5ADwjHgx+Tmxs
Wrtc3jWUk/PIvWULcWk0xMUwxCmVEqdIRJyRkcS5aBEZFAp9bQkJHjYmhm5oHUgHz4N5xYPhb1ePXD4w
CUEbxOzAAaiwn4gI0p+Z+VdFcvI3yH8HZIAFifvDWlNjtKrVZptA8Kw4oGNDiYmPTFrtvZT4+DIsiQYL
E/caDAec+flOG9zPJz4BHgBzWhrp1+nuvLlqVRaW/udrxR8ug6HFsX69yxYV9Yy4A72n7aLi42A0PJwM
gR+ysnwD5eW/VrAsbdP8RTw7dx6xFxe7Qzl3SCTkYXHx37eSknxUfCQg3gc6gYlhZgfoP5mvCI5iiy0/
32MTCv3CT7VlyRIyXFLy+8k1a7r7Nm6cNKekkF8g2gtugh9pAUpOzuzPFRWD+XI5fUE+edW7a2ubqbg9
lHhcHBleu/aPeoZpR2pDcXr6W3dKS+8No/dB8Q7QBlppEZVqtru8vO8TrZZuPB+E8dybNlnsMTGhnUO8
TqFoQ6IR0I0U783Le61frx8bzMh4LP4tuAqugIHU1Ee9ev1d5C4HfJ5Npxt2y2QhnRsZ5nsk1QfEg18q
/r6CAra/vHzs64wM37/FvwwLI70oYNJoJpBXCGJ53dXVWyc1GpcLokHnQ0VFf+4OLR4MfmNeXi42drQn
M5NcDoibcnNnP9doHpasXPkxcuYKIBa3VVYetZSWem6zrI86b1QqOzA+n3gw+IbVqxW0HVexzqRWz16C
8xcEgnOY04G5FiHCmISE6D69/rP7paWOiwUFOH3hjRhngJDO06R5gn+lqurt2zrdxE2t1lmclES/BXog
BfS4Pl5Lf8QAJdgQuC708X8O0KNJT85G8AoI+cAtAtQx/VjTK71fSFAT9P3/YgBaMGCMx/sHyjLY+hqD
P/QAAAAASUVORK5CYII=
</value>
</data>
<data name="BTT_CLEAR_ALL.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVDSURBVEhLjZVtTFNXGMcLQmdHO6AdarLSOcTxXqC3lFs3
FceLFC3YgqBjRM2ouILiC0oUozGauPiSLNmH7cP2YctMZtwSXdzGhFE3J5ABAg4XBHRYS+l74bKXZJGe
/U9pdcay8SS/3N5znvN//n3OuffyaAwUFkaZEhI+ur5s2eg1mezDDVLpSxiO8E/+T4yoVOxvMtmNsaVL
+y8nJlZgKAqE+SdpDBmNwp7Cwi9GmpvJ+PnzpLOpyXeNZTtyRaKVmI6cywodwwzzunXr1gfcmTNk5tw5
MlpZ6X4/ObleFh0di+m5Ih0rVnxwd/9+cv/ECTJ+/DixINl86BBpZdkbcpHoVaSELDKmVr8BcTN39izh
sJZraSEzx46Ru1qt5yup9D2kiEEE77pEYqHi95uayIMjR4gFSZOnT5Pe5mbfNZXqpwyRKAmJTxVBW4qs
VVUW6pyKz0CcO3iQzMCYt6aGmOLi7iCNBSJee3z8hdHaWjKOAmZgOXyYWLHAfuoUuYV2tbNsV7pQmIxk
f5ERhaJosrLSMv3uu4SDmRmY4rBuZt8+MrVrF2lVqZzbJJJLSC0BYp5++fKXW5XKGzd37PA9RNIEmIQb
O/bEhZY5Dhwg11EkWyhMucUwhRMVFdbpkyf9LeHgmEN7ucZGMg1xU3a2O0kg+BTCBiAHdMN5kYxEkowi
XeZt24h1925ia2gg9r17iRPFPBAabGjwdavVg/fKyizc0aN+xxzmOORy9fWPxVMEggvQqwVpAfFw4A9+
tlic8p1C0dlTXe2z1dURB3AZjcQNAS+KeffsIdNwO02Fcc/h3i+O9nYqlR65UEjFqfNUsBg8OaqB4KvE
4tT2zMwu6+bNxLF9O3EBj8FAvHA4hYJT2MCpsjLiXbeOeNVq4gadubneLJHoItbvBNS5ADwjHgx+Tmxs
Wrtc3jWUk/PIvWULcWk0xMUwxCmVEqdIRJyRkcS5aBEZFAp9bQkJHjYmhm5oHUgHz4N5xYPhb1ePXD4w
CUEbxOzAAaiwn4gI0p+Z+VdFcvI3yH8HZIAFifvDWlNjtKrVZptA8Kw4oGNDiYmPTFrtvZT4+DIsiQYL
E/caDAec+flOG9zPJz4BHgBzWhrp1+nuvLlqVRaW/udrxR8ug6HFsX69yxYV9Yy4A72n7aLi42A0PJwM
gR+ysnwD5eW/VrAsbdP8RTw7dx6xFxe7Qzl3SCTkYXHx37eSknxUfCQg3gc6gYlhZgfoP5mvCI5iiy0/
32MTCv3CT7VlyRIyXFLy+8k1a7r7Nm6cNKekkF8g2gtugh9pAUpOzuzPFRWD+XI5fUE+edW7a2ubqbg9
lHhcHBleu/aPeoZpR2pDcXr6W3dKS+8No/dB8Q7QBlppEZVqtru8vO8TrZZuPB+E8dybNlnsMTGhnUO8
TqFoQ6IR0I0U783Le61frx8bzMh4LP4tuAqugIHU1Ee9ev1d5C4HfJ5Npxt2y2QhnRsZ5nsk1QfEg18q
/r6CAra/vHzs64wM37/FvwwLI70oYNJoJpBXCGJ53dXVWyc1GpcLokHnQ0VFf+4OLR4MfmNeXi42drQn
M5NcDoibcnNnP9doHpasXPkxcuYKIBa3VVYetZSWem6zrI86b1QqOzA+n3gw+IbVqxW0HVexzqRWz16C
8xcEgnOY04G5FiHCmISE6D69/rP7paWOiwUFOH3hjRhngJDO06R5gn+lqurt2zrdxE2t1lmclES/BXog
BfS4Pl5Lf8QAJdgQuC708X8O0KNJT85G8AoI+cAtAtQx/VjTK71fSFAT9P3/YgBaMGCMx/sHyjLY+hqD
P/QAAAAASUVORK5CYII=
</value>
</data>
<data name="BTT_LOG.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFmSURBVFhH1dc/K4VhHMbxJ5EFEQbFiERKCotIrMJIiYEi
pbwCZcOqJC9AikUWiqRkJYtSRDbESMT3V07dna7zHHru+9T51me+Ts//E+V7LRjFFAZRiZzUhDVc4/vX
B47Rh6D14Aqp4XQ36ECQ2nALNezaQjG8Vo5DqMF0bxiA1+bwCTWoLMFbNTiDGsrkABXw0jDsKldDmdyj
HokrwCrUSBz7wXbRJs4eLkdQI9m0I3ENeIAaiGN3QjMSZ4fxv+ffnKIKibOnmhqI84V5eMleOHY41VAm
9k7wdgtW4wRqSHlCP7y2AjWmbMB7Y7DzqgZdz2iF9zrxCDXq2oU9uLz31+tgAcHahhp1DSFY9pGhRl29
CFYXxrMoQ7BmsZfFPkoRpHWow+56hX26BWkRatR1gRIEaQLvUMMpOyhCkBpxBzWcMoOgLUMNm0vUIWj2
ebaJF7jj5+hGTiqE/f+bxDRGUIt8LIp+AC/GHt3tQnwvAAAAAElFTkSuQmCC
</value>
</data>
</root>

View File

@@ -0,0 +1,501 @@
' Copyright (C) 2023 Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports PersonalUtilities.Tools
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Toolbars
Imports PersonalUtilities.Forms.Controls.KeyClick
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Functions.Messaging
Imports SCrawler.API.YouTube
Imports SCrawler.API.YouTube.Base
Imports SCrawler.API.YouTube.Controls
Imports SCrawler.API.YouTube.Objects
Namespace DownloadObjects.STDownloader
Public Class VideoListForm : Implements IDesignXMLContainer
#Region "Declarations"
Private ReadOnly MyView As FormView
Private ReadOnly MyProgress As MyProgress
Protected WithEvents MyJob As JobThread(Of MediaItem)
Public Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
Public Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
Public Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
Private ReadOnly ControlsDownloaded As New FPredicate(Of MediaItem)(Function(i) i.MyContainer.MediaState = Plugin.UserMediaStates.Downloaded)
Private ReadOnly ControlsChecked As Predicate(Of MediaItem) = Function(i) i.Checked
Private ReadOnly CNT_PROCESSOR As TableControlsProcessor
Protected AppMode As Boolean = True
#End Region
#Region "Initializer"
Public Sub New()
InitializeComponent()
CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS)
MyView = New FormView(Me)
MyProgress = New MyProgress(TOOLBAR_BOTTOM, PR_MAIN, LBL_INFO)
MyJob = New JobThread(Of MediaItem)
End Sub
#End Region
#Region "Form handlers"
Protected Overridable Sub VideoListForm_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not LicenseManager.UsageMode = LicenseUsageMode.Designtime Then
If MyYouTubeSettings Is Nothing Then MyYouTubeSettings = New YouTubeSettings
DesignXML = MyYouTubeSettings.DesignXml
If MyCache Is Nothing Then MyCache = New CacheKeeper(YouTubeFunctions.YouTubeCachePathRoot)
End If
If AppMode Then
If Now.Month.ValueBetween(6, 8) Then Text = "SCrawler: Happy LGBT Pride Month! :-)"
MyNotificator = New YTNotificator(Me)
MyDownloaderSettings = MyYouTubeSettings
End If
With MyView : .Import() : .SetFormSize() : End With
BTT_DELETE.Enabled = False
If Not AppMode Then
BTT_SETTINGS.Visible = False
SEP_1.Visible = False
SEP_LOG.Visible = False
BTT_LOG.Visible = False
BTT_INFO.Visible = False
BTT_DONATE.Visible = False
End If
MyProgress.Visible = False
LoadData()
End Sub
Protected Overridable Sub VideoListForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
If Not AppMode Then e.Cancel = True : Hide()
End Sub
Protected Overridable Sub VideoListForm_Disposed(sender As Object, e As EventArgs) Handles Me.Disposed
MyView.Dispose()
MyCache.DisposeIfReady()
If AppMode Then
MyNotificator.Clear()
If Not MyMainLOG.IsEmptyString Then SaveLogToFile()
End If
If Not MyYouTubeSettings Is Nothing Then MyYouTubeSettings.Close()
End Sub
Private Sub VideoListForm_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
Dim b As Boolean = True
Select Case e.KeyCode
Case Keys.Insert : BTT_ADD.PerformClick()
Case Keys.F5 : BTT_DOWN.PerformClick()
Case Else : b = False
End Select
If b Then e.Handled = True
End Sub
#End Region
#Region "Refill, save list"
Protected Sub LoadData()
Dim c As List(Of IYouTubeMediaContainer) = LoadData_GetFiles()
If c.ListExists Then
c.Sort(New ContainerDateComparer)
SuspendLayout()
For i% = c.Count - 1 To 0 Step -1 : ControlCreateAndAdd(c(i), True, i = 0) : Next
ResumeLayout(False)
PerformLayout()
End If
End Sub
Protected Overridable Function LoadData_GetFiles() As List(Of IYouTubeMediaContainer)
Try
Dim l As New List(Of IYouTubeMediaContainer)
Dim path As SFile = DownloaderDataFolderYouTube
If path.Exists(SFO.Path, False) Then
Dim files As List(Of SFile) = SFile.GetFiles(path, "*.xml",, EDP.ReturnValue)
If files.Count > 0 Then files.ForEach(Sub(f) l.Add(YouTubeFunctions.CreateContainer(f)))
End If
If l.Count > 0 Then l.RemoveAll(Function(c) c Is Nothing)
If l.Count > 0 Then l.ListDisposeRemoveAll(Function(c) Not c.Exists)
Return l
Catch ex As Exception
Dim e As EDP = EDP.LogMessageValue
If Not ex.HelpLink.IsEmptyString AndAlso ex.HelpLink = NameOf(YouTubeFunctions.CreateContainer) Then e = EDP.SendToLog + EDP.ReturnValue
Return ErrorsDescriber.Execute(e, ex, "VideoListForm.LoadData_GetFiles", New List(Of IYouTubeMediaContainer))
End Try
End Function
#End Region
#Region "Controls"
Protected Sub ControlCreateAndAdd(ByVal Container As IYouTubeMediaContainer, Optional ByVal DisableDownload As Boolean = False,
Optional ByVal PerformClick As Boolean = True)
ControlInvokeFast(TP_CONTROLS, Sub()
With TP_CONTROLS
.SuspendLayout()
If DisableDownload Or Not MyDownloaderSettings.DownloadAutomatically Then Container.Save()
'.AutoScroll = True
'.HorizontalScroll.Visible = False
.RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 60))
.RowCount = .RowStyles.Count
OffsetControls(0, True)
Dim cnt As New MediaItem(Container) With {.Dock = DockStyle.Fill, .Margin = New Padding(0)}
AddHandler cnt.FileDownloaded, AddressOf MediaControl_FileDownloaded
AddHandler cnt.Removal, AddressOf MediaControl_Removal
AddHandler cnt.DownloadAgain, AddressOf MediaControl_DownloadAgain
AddHandler cnt.DownloadRequested, AddressOf MediaControl_DownloadRequested
AddHandler cnt.CheckedChanged, AddressOf MediaControl_CheckedChanged
AddHandler cnt.Click, AddressOf CNT_PROCESSOR.MediaItem_Click
AddHandler cnt.KeyDown, AddressOf CNT_PROCESSOR.MediaItem_KeyDown
.Controls.Add(cnt, 0, 0)
.Controls.Cast(Of ISupportInitialize).ToList.ForEach(Sub(_cnt) _cnt.EndInit())
.ScrollControlIntoView(cnt)
cnt.Select()
RefillColors()
'.AutoScroll = False
'.AutoScroll = True
.ResumeLayout()
.PerformLayout()
UpdateScrolls(Me, Nothing)
If PerformClick Then cnt.PerformClick()
If Not DisableDownload And MyDownloaderSettings.DownloadAutomatically Then AddToDownload(cnt, True)
End With
End Sub, EDP.None)
End Sub
#Region "Controls rendering"
Private Overloads Sub OffsetControls()
Try
With TP_CONTROLS
If .Controls.Count > 0 Then
Dim i%, ri%
Dim cntIndx% = -1
Dim cnt As Control
For i = .Controls.Count - 1 To 0 Step -1
cnt = .Controls(i)
If Not cnt Is Nothing Then cntIndx += 1 : .SetCellPosition(cnt, New TableLayoutPanelCellPosition(0, cntIndx))
Next
For i = .RowStyles.Count - 1 To 0 Step -1
If Not .GetControlFromPosition(0, i) Is Nothing Then
If i + 1 < .RowStyles.Count - 1 Then
For ri = .RowStyles.Count - 1 To i + 1 Step -1 : .RowStyles.RemoveAt(i) : Next
.RowStyles.Add(New RowStyle(SizeType.AutoSize))
.RowCount = .RowStyles.Count
End If
Exit For
End If
Next
Else
.RowStyles.Clear()
.RowCount = 0
.RowStyles.Add(New RowStyle(SizeType.AutoSize))
.RowCount = .RowStyles.Count
End If
End With
Catch
End Try
End Sub
Private Overloads Sub OffsetControls(ByVal ReflectedRow As Integer, ByVal Add As Boolean)
ControlInvokeFast(TP_CONTROLS, Sub()
Dim offset% = IIf(Add, 1, -1)
Dim cnt As Control
With TP_CONTROLS
If .RowStyles.Count > 1 Then
For i% = .RowStyles.Count - 1 To ReflectedRow Step -1
cnt = .GetControlFromPosition(0, i)
If Not cnt Is Nothing Then .SetCellPosition(cnt, New TableLayoutPanelCellPosition(0, i + offset))
Next
End If
End With
End Sub, EDP.None)
End Sub
Private Sub RefillColors()
ControlInvokeFast(TP_CONTROLS, Sub()
With TP_CONTROLS
If .Controls.Count > 0 Then
Dim i% = 0
Dim c As Color
For Each cnt As MediaItem In .Controls
i += 1
If (i Mod 2) = 0 Then c = SystemColors.ControlLight Else c = SystemColors.Window
cnt.BackColor = c
Next
End If
End With
End Sub, EDP.None)
End Sub
Private Sub UpdateScrolls(sender As Object, e As EventArgs) Handles TP_CONTROLS.StyleChanged, Me.ResizeEnd, Me.SizeChanged
ControlInvokeFast(TP_CONTROLS, Sub()
With TP_CONTROLS
.SuspendLayout()
.Padding = New Padding(0, 0, .VerticalScroll.Visible.BoolToInteger * 3, 0)
.HorizontalScroll.Visible = False
.HorizontalScroll.Enabled = False
.ResumeLayout()
.PerformLayout()
End With
End Sub, EDP.None)
End Sub
#End Region
#Region "Toolbar controls handlers"
Protected Overridable Sub BTT_SETTINGS_Click(sender As Object, e As EventArgs) Handles BTT_SETTINGS.Click
MyYouTubeSettings.ShowForm(AppMode)
End Sub
Protected Overridable Sub BTT_ADD_KeyClick(ByVal Sender As ToolStripMenuItemKeyClick, ByVal e As KeyClickEventArgs) Handles BTT_ADD.KeyClick, BTT_ADD_PLS_ARR.KeyClick,
BTT_ADD_NO_SHORTS.KeyClick, BTT_ADD_SHORTS_ONLY.KeyClick
Dim pForm As ParsingProgressForm = Nothing
Try
Dim useCookies As Boolean = MyYouTubeSettings.DefaultUseCookies
Dim disableDown As Boolean = e.Shift
If e.Control Then useCookies = True
Dim useCookiesParse As Boolean? = Nothing
If useCookies Then useCookiesParse = True
Dim c As IYouTubeMediaContainer = Nothing
Dim url$ = String.Empty
Dim GetDefault As Boolean = True
Dim GetShorts As Boolean = True
If Sender.Tag = "pls" Then
Using pf As New PlaylistArrayForm With {.DesignXML = DesignXML}
pf.ShowDialog()
If pf.DialogResult = DialogResult.OK Then
With pf.URLs
If .Count > 0 Then
pForm = New ParsingProgressForm
pForm.Show()
pForm.SetInitialValues(.Count, "Parsing playlists...")
Dim containers As New List(Of IYouTubeMediaContainer)
For Each u$ In .Self : containers.Add(YouTubeFunctions.Parse(u, useCookiesParse, pForm.Token, pForm.MyProgress, True, False)) : pForm.MyProgress.Perform() : Next
pForm.Dispose()
If containers.Count > 0 Then containers.ListDisposeRemoveAll(Function(cc) cc.HasError Or Not cc.Exists)
If containers.Count > 0 Then
c = New Channel With {.UserTitle = IIf(pf.IsOneArtist, containers(0).UserTitle, "Playlists")}
c.Elements.AddRange(containers)
End If
End If
End With
End If
End Using
Else
Select Case CStr(Sender.Tag)
Case "ans" : GetShorts = False
Case "as" : GetDefault = False : GetShorts = True
End Select
url = BufferText
If url.IsEmptyString OrElse Not YouTubeFunctions.IsMyUrl(url) Then url = InputBoxE("Enter a valid URL to the YouTube video:", "YouTube link")
End If
If Not c Is Nothing OrElse YouTubeFunctions.IsMyUrl(url) Then
If c Is Nothing Then
pForm = New ParsingProgressForm
pForm.Show()
pForm.SetInitialValues(1, "Parsing data...")
c = YouTubeFunctions.Parse(url, useCookiesParse, pForm.Token, pForm.MyProgress, GetDefault, GetShorts)
pForm.Dispose()
End If
If Not c Is Nothing Then
Dim f As Form
Select Case c.ObjectType
Case YouTubeMediaType.Single : f = New VideoOptionsForm(c)
Case YouTubeMediaType.Channel, YouTubeMediaType.PlayList
If c.IsMusic Then
f = New MusicPlaylistsForm(c)
Else
f = New VideoOptionsForm(c)
End If
Case Else : c.Dispose() : Throw New ArgumentException($"Object type {c.ObjectType} not implemented", "IYouTubeMediaContainer.ObjectType")
End Select
If Not f Is Nothing Then
If TypeOf f Is IDesignXMLContainer Then DirectCast(f, IDesignXMLContainer).DesignXML = DesignXML
f.ShowDialog()
If f.DialogResult = DialogResult.OK Then ControlCreateAndAdd(c, disableDown)
f.Dispose()
End If
End If
End If
Catch oex As OperationCanceledException
Catch dex As ObjectDisposedException
Catch ex As Exception
ErrorsDescriber.Execute(EDP.LogMessageValue, ex, "VideoListForm.Add")
UpdateLogButton()
Finally
If Not pForm Is Nothing Then pForm.Dispose()
End Try
End Sub
Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
With TP_CONTROLS
If .Controls.Count > 0 Then
For Each cnt As MediaItem In .Controls
If Not cnt.MyContainer.MediaState = Plugin.UserMediaStates.Downloaded And Not cnt.Pending Then AddToDownload(cnt, False)
Next
End If
End With
StartDownloading()
End Sub
Private Sub BTT_STOP_Click(sender As Object, e As EventArgs) Handles BTT_STOP.Click
ControlInvoke(TOOLBAR_TOP, BTT_STOP, Sub() BTT_STOP.Enabled = False, EDP.SendToLog)
MyJob.Cancel()
End Sub
Private Sub BTT_DELETE_Click(sender As Object, e As EventArgs) Handles BTT_DELETE.Click
RemoveControls(ControlsChecked)
End Sub
Protected Overridable Sub BTT_CLEAR_DONE_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR_DONE.Click
RemoveControls(ControlsDownloaded)
End Sub
Protected Overridable Sub BTT_CLEAR_ALL_Click(sender As Object, e As EventArgs) Handles BTT_CLEAR_ALL.Click
RemoveControls()
End Sub
Private Sub BTT_LOG_Click(sender As Object, e As EventArgs) Handles BTT_LOG.Click
MyMainLOG_ShowForm(DesignXML,,,, AddressOf UpdateLogButton)
End Sub
Friend Sub UpdateLogButton()
If AppMode Then MyMainLOG_UpdateLogButton(BTT_LOG, TOOLBAR_TOP)
End Sub
Private Sub BTT_DONATE_Click(sender As Object, e As EventArgs) Handles BTT_DONATE.Click
Try : Process.Start("https://github.com/AAndyProgram/SCrawler/blob/main/HowToSupport.md") : Catch : End Try
End Sub
Private Sub BTT_INFO_Click(sender As Object, e As EventArgs) Handles BTT_INFO.Click
Try
MsgBoxE({$"YouTube Downloader v{My.Application.Info.Version}" & vbCr &
$"Address: https://github.com/AAndyProgram/SCrawler" & vbCr &
"Created by Greek LGBT person Andy (Gay)",
"Program information"},,,,
{"OK", New MsgBoxButton("Go to site") With {.CallBack = Sub(r, n, b) Process.Start("https://github.com/AAndyProgram/SCrawler/releases")}})
Catch
End Try
End Sub
Protected Overloads Sub RemoveControls(Optional ByVal Predicate As Predicate(Of MediaItem) = Nothing)
ControlInvokeFast(TP_CONTROLS, Sub()
With TP_CONTROLS
If .Controls.Count > 0 Then
Dim i%
Dim rCnt As New List(Of Integer)
Dim predicateExists As Boolean = Not Predicate Is Nothing
For i = 0 To .Controls.Count - 1
If Not predicateExists OrElse Predicate.Invoke(.Controls(i)) Then rCnt.Add(i)
Next
If rCnt.Count > 0 Then
Dim cnt As MediaItem
For i = rCnt.Count - 1 To 0 Step -1
cnt = .Controls(rCnt(i))
.Controls.RemoveAt(rCnt(i))
If Not cnt.MyContainer Is Nothing Then cnt.MyContainer.Delete(False)
cnt.Dispose()
Next
End If
End If
If .Controls.Count > 0 Then
OffsetControls()
Else
.RowStyles.Clear()
.RowStyles.Add(New RowStyle(SizeType.AutoSize))
.RowCount = 1
End If
End With
UpdateScrolls(Nothing, Nothing)
End Sub, EDP.None)
End Sub
Private Overloads Sub RemoveControls(ByVal CNT As MediaItem)
ControlInvokeFast(TP_CONTROLS, Sub()
If Not CNT Is Nothing Then TP_CONTROLS.Controls.Remove(CNT) : OffsetControls()
End Sub, EDP.None)
End Sub
#End Region
#Region "Media controls' handlers"
Private Sub MediaControl_FileDownloaded(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
If MyDownloaderSettings.ShowNotifications Then MyNotificator.ShowNotification(Container.ToString(), Container.ThumbnailFile)
If MyDownloaderSettings.RemoveDownloadedAutomatically Then RemoveControls(Sender)
End Sub
Private Sub MediaControl_Removal(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
RemoveControls(Sender)
End Sub
Private Sub MediaControl_DownloadAgain(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
If Not Container.URL.IsEmptyString Then BufferText = Container.URL : BTT_ADD.PerformClick()
End Sub
Private Sub MediaControl_DownloadRequested(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
AddToDownload(Sender, True)
End Sub
Private Sub MediaControl_CheckedChanged(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
With TP_CONTROLS.Controls
ControlInvokeFast(TOOLBAR_TOP, BTT_DELETE,
Sub() BTT_DELETE.Enabled = .Count > 0 AndAlso .Cast(Of MediaItem).ListExists(Function(cnt) cnt.Checked), EDP.None)
End With
End Sub
#End Region
#End Region
#Region "Downloading"
Protected Overridable Sub MyJob_Started(ByVal Sender As Object, ByVal e As EventArgs) Handles MyJob.Started
End Sub
Protected Overridable Sub MyJob_Finished(ByVal Sender As Object, ByVal e As EventArgs) Handles MyJob.Finished
UpdateLogButton()
End Sub
Protected Sub AddToDownload(ByRef Item As MediaItem, ByVal RunThread As Boolean)
Dim hc% = Item.MyContainer.GetHashCode
If MyJob.Count = 0 OrElse Not MyJob.Items.Exists(Function(i) i.MyContainer.GetHashCode = hc) Then
'TODELETE: YT video downloader 'Item.Pending'
'Item.Pending = True
MyJob.Add(Item)
Item.AddToQueue()
If RunThread Then StartDownloading()
End If
End Sub
Private Sub StartDownloading()
If Not MyJob.Working And MyJob.Count > 0 Then
EnableDownloadButtons(True)
MyJob.StartThread(AddressOf DownloadData)
End If
End Sub
Private Sub EnableDownloadButtons(ByVal Downloading As Boolean)
ControlInvoke(TOOLBAR_TOP, BTT_DOWN, Sub()
BTT_DOWN.Enabled = Not Downloading
BTT_STOP.Enabled = Downloading
End Sub, EDP.SendToLog)
End Sub
Private ReadOnly PNumProv As New ANumbers With {.FormatOptions = ANumbers.Options.GroupIntegral}
Private Sub DownloadData()
Try
MyJob.Start()
Const nf As ANumbers.Formats = ANumbers.Formats.Number
Dim t As New List(Of Task)
Dim i%
Dim __item As MediaItem
Dim Indexes As New List(Of Integer)
Dim maxJobCount% = MyDownloaderSettings.MaxJobsCount
If maxJobCount <= 0 Then maxJobCount = 1
MyProgress.Visible = True
MyProgress.Maximum = MyJob.Count
Do While MyJob.Count > 0 And Not MyJob.IsCancellationRequested
i = -1
Indexes.Clear()
For Each __item In MyJob.Items
i += 1
If i <= maxJobCount - 1 Then
Indexes.Add(i)
t.Add(Task.Run(Sub() __item.Download(MyJob.Token)))
Else
Exit For
End If
Next
If t.Count > 0 Then
MyProgress.Information = $"Downloading {t.Count.NumToString(nf, PNumProv)}/{MyJob.Count.NumToString(nf, PNumProv)}"
MyProgress.InformationTemporary = MyProgress.Information
Task.WaitAll(t.ToArray)
MyProgress.Perform(t.Count)
If Indexes.Count > 0 Then
For i = Indexes.Count - 1 To 0 Step -1
MyJob.Item(Indexes(i)).Pending = False
MyJob.Items.RemoveAt(Indexes(i))
Next
End If
t.Clear()
End If
Loop
Indexes.Clear()
MyProgress.Done()
MyProgress.InformationTemporary = "Download completed"
Catch aoex As ArgumentOutOfRangeException
Catch oex As OperationCanceledException
MyProgress.InformationTemporary = "Download canceled"
Catch ex As Exception
MyProgress.InformationTemporary = "Download error"
ErrorsDescriber.Execute(EDP.SendToLog, ex, "[VideoListForm.DownloadData]")
Finally
MyJob.Finish()
EnableDownloadButtons(False)
End Try
End Sub
#End Region
End Class
End Namespace

Some files were not shown because too many files have changed in this diff Show More