├── .gitattributes
├── .github
├── FUNDING.yml
└── workflows
│ └── build.yml
├── res
├── MediathekView.ico
└── MediathekView_256x256.png
├── src
├── main
│ ├── resources
│ │ ├── splash.png
│ │ ├── splash@2x.png
│ │ ├── mediathek
│ │ │ ├── res
│ │ │ │ ├── sender
│ │ │ │ │ ├── ard.png
│ │ │ │ │ ├── br.png
│ │ │ │ │ ├── dw.png
│ │ │ │ │ ├── hr.png
│ │ │ │ │ ├── mdr.png
│ │ │ │ │ ├── ndr.png
│ │ │ │ │ ├── orf.png
│ │ │ │ │ ├── rbb.png
│ │ │ │ │ ├── sr.png
│ │ │ │ │ ├── srf.png
│ │ │ │ │ ├── swr.png
│ │ │ │ │ ├── wdr.png
│ │ │ │ │ ├── zdf.png
│ │ │ │ │ ├── 3sat.png
│ │ │ │ │ ├── kika.png
│ │ │ │ │ ├── rbtv.jpg
│ │ │ │ │ ├── arte-de.png
│ │ │ │ │ ├── arte-en.png
│ │ │ │ │ ├── arte-es.png
│ │ │ │ │ ├── arte-fr.png
│ │ │ │ │ ├── arte-it.png
│ │ │ │ │ ├── arte-pl.png
│ │ │ │ │ ├── funk_net.png
│ │ │ │ │ ├── phoenix.png
│ │ │ │ │ ├── zdf-tivi.png
│ │ │ │ │ └── srf-podcast.png
│ │ │ │ ├── MediathekView.png
│ │ │ │ ├── programm
│ │ │ │ │ ├── tray.png
│ │ │ │ │ ├── achtung.png
│ │ │ │ │ ├── tab-film.png
│ │ │ │ │ ├── button-add.png
│ │ │ │ │ ├── button-del.png
│ │ │ │ │ ├── menue-help.png
│ │ │ │ │ ├── tabelle-aus.png
│ │ │ │ │ ├── tabelle-ein.png
│ │ │ │ │ ├── tray-fehler.png
│ │ │ │ │ ├── button-move-up.png
│ │ │ │ │ ├── button-remove.png
│ │ │ │ │ ├── dialog-ein-sw.png
│ │ │ │ │ ├── tab-download.png
│ │ │ │ │ ├── tray-download.png
│ │ │ │ │ ├── button-move-down.png
│ │ │ │ │ └── menue-blacklist.png
│ │ │ │ ├── MediathekView_k.png
│ │ │ │ └── muster
│ │ │ │ │ ├── button-add.png
│ │ │ │ │ ├── button-del.png
│ │ │ │ │ ├── button-help.png
│ │ │ │ │ ├── button-clear.png
│ │ │ │ │ ├── button-remove.png
│ │ │ │ │ ├── button-file-open.png
│ │ │ │ │ ├── button-move-down.png
│ │ │ │ │ ├── button-move-up.png
│ │ │ │ │ ├── button-aktualisieren.png
│ │ │ │ │ └── button-blacklist-aus.png
│ │ │ └── file
│ │ │ │ ├── hilfetext_beenden.txt
│ │ │ │ ├── hilfetext_geo.txt
│ │ │ │ ├── hilfetext_reset.txt
│ │ │ │ ├── hilfetext_editDownloadProg.txt
│ │ │ │ ├── hilfetext_standardPset.txt
│ │ │ │ ├── hilfetext_reset_set.txt
│ │ │ │ └── hilfetext_blacklist.txt
│ │ ├── icons
│ │ │ ├── countries
│ │ │ │ ├── 003-austria.png
│ │ │ │ ├── 162-germany.png
│ │ │ │ ├── 195-france.png
│ │ │ │ ├── 205-switzerland.png
│ │ │ │ └── 259-european-union.png
│ │ │ ├── fontawesome
│ │ │ │ ├── minus.svg
│ │ │ │ ├── circle-half-stroke.svg
│ │ │ │ ├── caret-down.svg
│ │ │ │ ├── ellipsis-vertical.svg
│ │ │ │ ├── plus.svg
│ │ │ │ ├── check.svg
│ │ │ │ ├── arrow-down.svg
│ │ │ │ ├── arrow-up.svg
│ │ │ │ ├── triangle-exclamation.svg
│ │ │ │ ├── xmark.svg
│ │ │ │ ├── folder-open.svg
│ │ │ │ ├── circle-question.svg
│ │ │ │ ├── envelope-open-text.svg
│ │ │ │ └── pen-to-square.svg
│ │ │ └── sender
│ │ │ │ └── ard.svg
│ │ ├── raven
│ │ │ └── toast
│ │ │ │ └── svg
│ │ │ │ ├── info.svg
│ │ │ │ ├── success.svg
│ │ │ │ ├── warning.svg
│ │ │ │ ├── close.svg
│ │ │ │ └── error.svg
│ │ └── log4j2.xml
│ ├── java
│ │ ├── mediathek
│ │ │ ├── gui
│ │ │ │ ├── messages
│ │ │ │ │ ├── BaseEvent.java
│ │ │ │ │ ├── ShowSettingsDialogEvent.kt
│ │ │ │ │ ├── TimerEvent.java
│ │ │ │ │ ├── StartEvent.java
│ │ │ │ │ ├── TrayIconEvent.java
│ │ │ │ │ ├── ButtonStartEvent.java
│ │ │ │ │ ├── DarkModeChangeEvent.java
│ │ │ │ │ ├── DownloadStartEvent.java
│ │ │ │ │ ├── FontSizeChangedEvent.java
│ │ │ │ │ ├── GeoStateChangedEvent.java
│ │ │ │ │ ├── RestartDownloadEvent.java
│ │ │ │ │ ├── FilmListReadStartEvent.java
│ │ │ │ │ ├── FilmListReadStopEvent.java
│ │ │ │ │ ├── FilmListWriteStartEvent.java
│ │ │ │ │ ├── FilmListWriteStopEvent.java
│ │ │ │ │ ├── ProgramSetChangedEvent.java
│ │ │ │ │ ├── ReplaceListChangedEvent.java
│ │ │ │ │ ├── AboListChangedEvent.java
│ │ │ │ │ ├── DownloadFinishedEvent.java
│ │ │ │ │ ├── DownloadListChangedEvent.java
│ │ │ │ │ ├── BlacklistChangedEvent.java
│ │ │ │ │ ├── DownloadProgressChangedEvent.java
│ │ │ │ │ ├── ProgramLocationChangedEvent.java
│ │ │ │ │ ├── SenderIconStyleChangedEvent.java
│ │ │ │ │ ├── ToolBarIconSizeChangedEvent.java
│ │ │ │ │ ├── DownloadQueueRankChangedEvent.java
│ │ │ │ │ ├── FilmListImportTypeChangedEvent.java
│ │ │ │ │ ├── NotificationCenterChangeEvent.java
│ │ │ │ │ ├── TabVisualSettingsChangedEvent.java
│ │ │ │ │ ├── UpdateStatusBarLeftDisplayEvent.java
│ │ │ │ │ ├── DownloadInfoUpdateAvailableEvent.java
│ │ │ │ │ ├── ParallelDownloadNumberChangedEvent.java
│ │ │ │ │ ├── history
│ │ │ │ │ │ ├── AboHistoryChangedEvent.java
│ │ │ │ │ │ ├── DownloadHistoryChangedEvent.java
│ │ │ │ │ │ └── HistoryChangedEvent.java
│ │ │ │ │ ├── TableModelChangeEvent.kt
│ │ │ │ │ ├── InstallTabSwitchListenerEvent.java
│ │ │ │ │ ├── DownloadRateLimitChangedEvent.java
│ │ │ │ │ ├── UpdateStateChangedEvent.java
│ │ │ │ │ └── ReloadTableDataEvent.java
│ │ │ │ ├── duplicates
│ │ │ │ │ ├── FilmStatistics.java
│ │ │ │ │ ├── BigSenderPenaltyComparator.java
│ │ │ │ │ └── CommonStatsEvaluationTask.java
│ │ │ │ ├── dialog
│ │ │ │ │ ├── ButtonFlowPanel.kt
│ │ │ │ │ ├── ButtonPanel.kt
│ │ │ │ │ ├── reset
│ │ │ │ │ │ └── ResetSettingsDialog.java
│ │ │ │ │ └── StandardCloseDialog.java
│ │ │ │ ├── filmInformation
│ │ │ │ │ ├── DisabledCheckBox.java
│ │ │ │ │ └── HtmlMultilineLabel.java
│ │ │ │ ├── PanelVorlage.java
│ │ │ │ ├── history
│ │ │ │ │ ├── AboHistoryDialog.java
│ │ │ │ │ ├── ResetAboHistoryAction.kt
│ │ │ │ │ ├── ResetDownloadHistoryAction.kt
│ │ │ │ │ └── MVUsedUrlTableFormat.java
│ │ │ │ ├── actions
│ │ │ │ │ ├── ShowProgramInfosAction.java
│ │ │ │ │ ├── SearchProgramUpdateAction.java
│ │ │ │ │ ├── StopDownloadsAction.java
│ │ │ │ │ ├── StopAllDownloadsAction.java
│ │ │ │ │ ├── StopAllWaitingDownloadsAction.java
│ │ │ │ │ ├── StartAllDownloadsTimedAction.java
│ │ │ │ │ ├── DisposeDialogAction.java
│ │ │ │ │ ├── ShowAboHistoryAction.java
│ │ │ │ │ ├── QuitAction.java
│ │ │ │ │ ├── EditDownloadAction.java
│ │ │ │ │ ├── ShowDuplicateStatisticsAction.java
│ │ │ │ │ ├── AdvanceDownloadsAction.java
│ │ │ │ │ ├── DeleteDownloadAction.java
│ │ │ │ │ ├── OpenTargetFolderAction.java
│ │ │ │ │ ├── StartDownloadsAction.java
│ │ │ │ │ ├── CleanupDownloadListAction.java
│ │ │ │ │ ├── DeferDownloadsAction.java
│ │ │ │ │ ├── ManageBookmarkAction.java
│ │ │ │ │ ├── ResetSettingsAction.java
│ │ │ │ │ ├── StartAllDownloadsAction.java
│ │ │ │ │ ├── DeleteDownloadsAction.java
│ │ │ │ │ ├── PlayDownloadAction.java
│ │ │ │ │ ├── LoadFilmListAction.java
│ │ │ │ │ ├── MemoryMonitorAction.java
│ │ │ │ │ ├── SettingsAction.java
│ │ │ │ │ ├── RefreshDownloadListAction.java
│ │ │ │ │ ├── ShowFilmInformationAction.java
│ │ │ │ │ └── DeleteLocalFilmlistAction.java
│ │ │ │ ├── tabs
│ │ │ │ │ ├── tab_film
│ │ │ │ │ │ ├── searchfilters
│ │ │ │ │ │ │ ├── FinalStagePatternFilter.java
│ │ │ │ │ │ │ ├── FinalStageFilterNoPattern.java
│ │ │ │ │ │ │ ├── FinalStagePatternFilterWithDescription.java
│ │ │ │ │ │ │ └── FinalStageFilterNoPatternWithDescription.java
│ │ │ │ │ │ ├── OnlineSearchProviders.kt
│ │ │ │ │ │ ├── SearchFieldData.kt
│ │ │ │ │ │ └── SearchControlFieldMode.kt
│ │ │ │ │ ├── tab_downloads
│ │ │ │ │ │ ├── AboLabel.java
│ │ │ │ │ │ ├── FailedDownloadsInfoLabel.java
│ │ │ │ │ │ ├── ManualDownloadsInfoLabel.java
│ │ │ │ │ │ ├── ActiveDownloadsInfoLabel.java
│ │ │ │ │ │ ├── FinishedDownloadsInfoLabel.java
│ │ │ │ │ │ ├── WaitingDownloadsInfoLabel.java
│ │ │ │ │ │ └── TotalDownloadsLabel.java
│ │ │ │ │ └── tab_livestreams
│ │ │ │ │ │ ├── services
│ │ │ │ │ │ ├── StreamInfo.kt
│ │ │ │ │ │ ├── StreamService.kt
│ │ │ │ │ │ ├── ShowService.kt
│ │ │ │ │ │ ├── ShowsResponse.kt
│ │ │ │ │ │ └── ShowInfo.kt
│ │ │ │ │ │ ├── LivestreamEntry.kt
│ │ │ │ │ │ └── SenderUtils.kt
│ │ │ │ ├── tasks
│ │ │ │ │ ├── BlacklistFilterWorker.java
│ │ │ │ │ └── RefreshAboWorker.java
│ │ │ │ ├── dialogEinstellungen
│ │ │ │ │ ├── allgemein
│ │ │ │ │ │ ├── TextFieldConfigWriter.java
│ │ │ │ │ │ └── TimedDocumentListener.java
│ │ │ │ │ ├── PanelNotifications.jfd
│ │ │ │ │ └── PanelPset.jfd
│ │ │ │ ├── expiration
│ │ │ │ │ └── ExpiryInfo.kt
│ │ │ │ ├── bandwidth
│ │ │ │ │ └── WriteConfigComponentListener.kt
│ │ │ │ └── bookmark
│ │ │ │ │ └── BookmarkAddedAtComparator.java
│ │ │ ├── tool
│ │ │ │ ├── TABS.java
│ │ │ │ ├── FilmListUpdateType.java
│ │ │ │ ├── notification
│ │ │ │ │ ├── MessageType.java
│ │ │ │ │ ├── NotificationMessage.kt
│ │ │ │ │ ├── INotificationCenter.kt
│ │ │ │ │ ├── NullNotificationCenter.kt
│ │ │ │ │ ├── MacNotificationCenter.kt
│ │ │ │ │ └── GenericNotificationCenter.kt
│ │ │ │ ├── InputStreamProgressMonitor.java
│ │ │ │ ├── sender_icon_cache
│ │ │ │ │ └── SenderIconSize.kt
│ │ │ │ ├── cellrenderer
│ │ │ │ │ ├── SenderCacheKey.java
│ │ │ │ │ ├── SelfEvictingSenderIconCache.java
│ │ │ │ │ └── CellRendererColor.java
│ │ │ │ ├── FilterDTO.java
│ │ │ │ ├── DarkModeFactory.kt
│ │ │ │ ├── SenderListComboBoxModel.java
│ │ │ │ ├── LightModeFactory.kt
│ │ │ │ ├── datum
│ │ │ │ │ ├── Datum.java
│ │ │ │ │ └── DatumFilm.java
│ │ │ │ ├── CopyToClipboardAction.kt
│ │ │ │ ├── NoSelectionErrorDialog.java
│ │ │ │ ├── SVGIconUtilities.java
│ │ │ │ ├── models
│ │ │ │ │ ├── NonEditableTableModel.java
│ │ │ │ │ └── TModelColor.java
│ │ │ │ ├── table
│ │ │ │ │ ├── MVProgTable.java
│ │ │ │ │ └── MVPsetTable.java
│ │ │ │ ├── TrailerTeaserChecker.kt
│ │ │ │ ├── CustomConversionHandler.java
│ │ │ │ ├── MVC.java
│ │ │ │ ├── episodes
│ │ │ │ │ └── SeasonEpisode.java
│ │ │ │ ├── affinity
│ │ │ │ │ ├── IAffinity.kt
│ │ │ │ │ ├── Affinity.kt
│ │ │ │ │ └── NullAffinity.kt
│ │ │ │ ├── GermanStringSorter.java
│ │ │ │ ├── Ipify.kt
│ │ │ │ ├── ttml
│ │ │ │ │ ├── ITtmlParser.java
│ │ │ │ │ └── ITtmlExporter.java
│ │ │ │ ├── EventListWithEmptyFirstEntry.java
│ │ │ │ ├── UIProgressState.java
│ │ │ │ ├── MessageBus.kt
│ │ │ │ └── FilmSize.java
│ │ │ ├── daten
│ │ │ │ ├── Country.java
│ │ │ │ ├── abo
│ │ │ │ │ ├── FilmLengthState.kt
│ │ │ │ │ └── AboTags.kt
│ │ │ │ ├── blacklist
│ │ │ │ │ └── BlacklistTags.kt
│ │ │ │ ├── DatenFilmFlags.java
│ │ │ │ ├── DownloadStartInfo.java
│ │ │ │ ├── FilmResolution.java
│ │ │ │ └── IndexedFilmList.java
│ │ │ ├── filmlisten
│ │ │ │ ├── IAction.java
│ │ │ │ ├── FilmListDownloadType.java
│ │ │ │ ├── reader
│ │ │ │ │ ├── IDateFilter.kt
│ │ │ │ │ ├── NoOpDateFilter.kt
│ │ │ │ │ └── DateFilter.kt
│ │ │ │ └── IDownloadAction.java
│ │ │ ├── update
│ │ │ │ └── ServerProgramInformation.kt
│ │ │ ├── filmeSuchen
│ │ │ │ ├── ListenerFilmeLaden.java
│ │ │ │ └── ListenerFilmeLadenEvent.java
│ │ │ ├── controller
│ │ │ │ ├── history
│ │ │ │ │ └── SeenHistoryShutdownHook.kt
│ │ │ │ └── starter
│ │ │ │ │ └── HttpDownloadState.java
│ │ │ ├── mainwindow
│ │ │ │ ├── SelectedListItemsLabel.java
│ │ │ │ ├── ListSelectedItemsProperty.java
│ │ │ │ ├── PositionSavingTabbedPane.java
│ │ │ │ └── FixedRedrawStatusBar.java
│ │ │ ├── res
│ │ │ │ └── GetIcon.java
│ │ │ ├── config
│ │ │ │ └── ApplicationType.kt
│ │ │ └── swing
│ │ │ │ ├── NoIconMenuItem.java
│ │ │ │ └── JIkonliSafeButton.kt
│ │ └── raven
│ │ │ └── toast
│ │ │ ├── ToastClientProperties.java
│ │ │ └── util
│ │ │ └── UIUtils.java
│ └── kotlin
│ │ ├── mediathek
│ │ ├── mainwindow
│ │ │ └── Log4jShutdownHookThread.kt
│ │ ├── gui
│ │ │ └── actions
│ │ │ │ ├── ResetFilterDialogPosition.kt
│ │ │ │ ├── CreateNewAboAction.kt
│ │ │ │ ├── ShowAboutAction.kt
│ │ │ │ ├── ShowBandwidthUsageAction.kt
│ │ │ │ ├── ManageAboAction.kt
│ │ │ │ └── export
│ │ │ │ └── DiskSpaceUtil.kt
│ │ ├── tool
│ │ │ └── dns
│ │ │ │ └── IPvPreferenceMode.kt
│ │ └── windows
│ │ │ ├── WinFlags.kt
│ │ │ └── MediathekGuiWindows.kt
│ │ └── feed
│ │ ├── FeedMessage.kt
│ │ └── Feed.kt
└── test
│ ├── kotlin
│ ├── mediathek
│ │ ├── tool
│ │ │ ├── dns
│ │ │ │ └── IPvPreferenceModeTest.kt
│ │ │ ├── FileUtilsTest.kt
│ │ │ ├── VersionTest.kt
│ │ │ └── TrailerTeaserCheckerTest.kt
│ │ └── daten
│ │ │ ├── blacklist
│ │ │ └── BlacklistTagsTest.kt
│ │ │ └── abo
│ │ │ └── AboTagsTest.kt
│ └── feed
│ │ └── RSSFeedParserTest.kt
│ ├── resources
│ └── log4j2.xml
│ └── java
│ └── mediathek
│ ├── tool
│ ├── LanguageCodeTest.java
│ ├── ttml
│ │ └── TimedTextMarkupLanguageParserTest.java
│ ├── SingleInstanceTest.java
│ └── table
│ │ └── MVTableTest.java
│ ├── config
│ └── MVConfigTest.java
│ └── controller
│ └── history
│ └── MVUsedUrlTest.java
├── .install4j
├── MediathekView@x16.png
├── MediathekView@x32.png
├── MediathekView@x48.png
└── MediathekView@x128.png
├── installers
└── mac
│ └── MediathekView.icns
├── maven-repository
├── airsquared
│ └── JMacNotification
│ │ ├── 1.1
│ │ ├── JMacNotification-1.1.jar
│ │ ├── _remote.repositories
│ │ └── JMacNotification-1.1.pom
│ │ └── maven-metadata-local.xml
└── com
│ └── formdev
│ └── jformdesigner-annotations
│ ├── 1.0
│ ├── jformdesigner-annotations-1.0.jar
│ ├── _remote.repositories
│ └── jformdesigner-annotations-1.0.pom
│ └── maven-metadata-local.xml
├── .mvn
└── wrapper
│ └── maven-wrapper.properties
└── .gitignore
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.exe filter=lfs diff=lfs merge=lfs -text
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: ['https://www.paypal.me/MediathekView', 'https://mediathekview.de/spenden/']
2 |
--------------------------------------------------------------------------------
/res/MediathekView.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/res/MediathekView.ico
--------------------------------------------------------------------------------
/res/MediathekView_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/res/MediathekView_256x256.png
--------------------------------------------------------------------------------
/src/main/resources/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/splash.png
--------------------------------------------------------------------------------
/.install4j/MediathekView@x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/.install4j/MediathekView@x16.png
--------------------------------------------------------------------------------
/.install4j/MediathekView@x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/.install4j/MediathekView@x32.png
--------------------------------------------------------------------------------
/.install4j/MediathekView@x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/.install4j/MediathekView@x48.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/BaseEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/splash@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/splash@2x.png
--------------------------------------------------------------------------------
/.install4j/MediathekView@x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/.install4j/MediathekView@x128.png
--------------------------------------------------------------------------------
/installers/mac/MediathekView.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/installers/mac/MediathekView.icns
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/TABS.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | public enum TABS {
4 | TAB_FILME, TAB_DOWNLOADS
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/Country.java:
--------------------------------------------------------------------------------
1 | package mediathek.daten;
2 |
3 | public enum Country {
4 | DE, AT, CH, EU, FR, OTHER
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/FilmListUpdateType.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | public enum FilmListUpdateType {MANUAL, AUTOMATIC}
4 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/abo/FilmLengthState.kt:
--------------------------------------------------------------------------------
1 | package mediathek.daten.abo
2 |
3 | enum class FilmLengthState {
4 | MINIMUM, MAXIMUM
5 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ShowSettingsDialogEvent.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages
2 |
3 | class ShowSettingsDialogEvent : BaseEvent()
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/TimerEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class TimerEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmlisten/IAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.filmlisten;
2 |
3 | interface IAction {
4 | void onFinished(boolean ok);
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/StartEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 |
4 | public class StartEvent extends BaseEvent {
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/TrayIconEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class TrayIconEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmlisten/FilmListDownloadType.java:
--------------------------------------------------------------------------------
1 | package mediathek.filmlisten;
2 |
3 | public enum FilmListDownloadType {FULL, DIFF_ONLY}
4 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/ard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/ard.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/br.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/br.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/dw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/dw.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/hr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/hr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/mdr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/mdr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/ndr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/ndr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/orf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/orf.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/rbb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/rbb.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/sr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/sr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/srf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/srf.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/swr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/swr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/wdr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/wdr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/zdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/zdf.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ButtonStartEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class ButtonStartEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/countries/003-austria.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/icons/countries/003-austria.png
--------------------------------------------------------------------------------
/src/main/resources/icons/countries/162-germany.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/icons/countries/162-germany.png
--------------------------------------------------------------------------------
/src/main/resources/icons/countries/195-france.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/icons/countries/195-france.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/MediathekView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/MediathekView.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tray.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/3sat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/3sat.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/kika.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/kika.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/rbtv.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/rbtv.jpg
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DarkModeChangeEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DarkModeChangeEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadStartEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadStartEvent extends BaseEvent {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/FontSizeChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class FontSizeChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/GeoStateChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class GeoStateChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/RestartDownloadEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class RestartDownloadEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/notification/MessageType.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.notification;
2 |
3 | public enum MessageType {
4 | INFO,
5 | ERROR
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/MediathekView_k.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/MediathekView_k.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/arte-de.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/arte-de.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/arte-en.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/arte-en.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/arte-es.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/arte-es.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/arte-fr.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/arte-fr.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/arte-it.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/arte-it.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/arte-pl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/arte-pl.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/funk_net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/funk_net.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/phoenix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/phoenix.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/zdf-tivi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/zdf-tivi.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/duplicates/FilmStatistics.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.duplicates;
2 |
3 | public record FilmStatistics(String sender, long count) {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/FilmListReadStartEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class FilmListReadStartEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/FilmListReadStopEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class FilmListReadStopEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/FilmListWriteStartEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class FilmListWriteStartEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/FilmListWriteStopEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class FilmListWriteStopEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ProgramSetChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class ProgramSetChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ReplaceListChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class ReplaceListChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/countries/205-switzerland.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/icons/countries/205-switzerland.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-add.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-del.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-help.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/achtung.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/achtung.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tab-film.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tab-film.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/sender/srf-podcast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/sender/srf-podcast.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/AboListChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class AboListChangedEvent extends ReloadTableDataEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadFinishedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadFinishedEvent extends BaseEvent {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadListChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadListChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/icons/countries/259-european-union.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/icons/countries/259-european-union.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-clear.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-remove.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/button-add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/button-add.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/button-del.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/button-del.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/menue-help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/menue-help.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tabelle-aus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tabelle-aus.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tabelle-ein.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tabelle-ein.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tray-fehler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tray-fehler.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/BlacklistChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class BlacklistChangedEvent extends ReloadTableDataEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadProgressChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadProgressChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ProgramLocationChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class ProgramLocationChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/SenderIconStyleChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class SenderIconStyleChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ToolBarIconSizeChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class ToolBarIconSizeChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-file-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-file-open.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-move-down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-move-down.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-move-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-move-up.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/button-move-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/button-move-up.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/button-remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/button-remove.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/dialog-ein-sw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/dialog-ein-sw.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tab-download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tab-download.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/tray-download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/tray-download.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadQueueRankChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadQueueRankChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/FilmListImportTypeChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class FilmListImportTypeChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/NotificationCenterChangeEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class NotificationCenterChangeEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/TabVisualSettingsChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class TabVisualSettingsChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/button-move-down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/button-move-down.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/programm/menue-blacklist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/programm/menue-blacklist.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/UpdateStatusBarLeftDisplayEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class UpdateStatusBarLeftDisplayEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-aktualisieren.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-aktualisieren.png
--------------------------------------------------------------------------------
/src/main/resources/mediathek/res/muster/button-blacklist-aus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/src/main/resources/mediathek/res/muster/button-blacklist-aus.png
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadInfoUpdateAvailableEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadInfoUpdateAvailableEvent extends BaseEvent {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ParallelDownloadNumberChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class ParallelDownloadNumberChangedEvent extends BaseEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/history/AboHistoryChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages.history;
2 |
3 | public class AboHistoryChangedEvent extends HistoryChangedEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/InputStreamProgressMonitor.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | public interface InputStreamProgressMonitor {
4 | void progress(long bytesRead, long size);
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/sender_icon_cache/SenderIconSize.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.sender_icon_cache
2 |
3 | internal enum class SenderIconSize(val height: Int) {
4 | SMALL(16), LARGE(32);
5 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/history/DownloadHistoryChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages.history;
2 |
3 | public class DownloadHistoryChangedEvent extends HistoryChangedEvent {
4 | }
5 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_beenden.txt:
--------------------------------------------------------------------------------
1 |
2 | Damit unter Linux das Herunterfahren des Rechners
3 | funktioniert, muss der User diesen Aufruf
4 | ausführen dürfen:
5 |
6 | shutdown -h now
7 |
--------------------------------------------------------------------------------
/maven-repository/airsquared/JMacNotification/1.1/JMacNotification-1.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/maven-repository/airsquared/JMacNotification/1.1/JMacNotification-1.1.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | wrapperVersion=3.3.4
2 | distributionType=only-script
3 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
4 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmlisten/reader/IDateFilter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.filmlisten.reader
2 |
3 | import mediathek.daten.DatenFilm
4 |
5 | internal interface IDateFilter {
6 | fun filter(film: DatenFilm)
7 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/cellrenderer/SenderCacheKey.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.cellrenderer;
2 |
3 | import java.awt.*;
4 |
5 | record SenderCacheKey(String sender, Dimension cellDimension) {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/TableModelChangeEvent.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages
2 |
3 | data class TableModelChangeEvent(@JvmField val active: Boolean, @JvmField val fromSearchField: Boolean) : BaseEvent()
4 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/history/HistoryChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages.history;
2 |
3 | import mediathek.gui.messages.BaseEvent;
4 |
5 | public class HistoryChangedEvent extends BaseEvent {
6 | }
7 |
--------------------------------------------------------------------------------
/maven-repository/com/formdev/jformdesigner-annotations/1.0/jformdesigner-annotations-1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mediathekview/MediathekView/HEAD/maven-repository/com/formdev/jformdesigner-annotations/1.0/jformdesigner-annotations-1.0.jar
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/notification/NotificationMessage.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.notification
2 |
3 | open class NotificationMessage {
4 | lateinit var title: String
5 | lateinit var type: MessageType
6 | lateinit var message: String
7 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmlisten/IDownloadAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.filmlisten;
2 |
3 | import mediathek.daten.ListeFilme;
4 |
5 | interface IDownloadAction {
6 | boolean performDownload(String dateiUrl, ListeFilme listeFilme, int days);
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialog/ButtonFlowPanel.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.dialog
2 |
3 | import java.awt.FlowLayout
4 | import javax.swing.JPanel
5 |
6 | class ButtonFlowPanel : JPanel() {
7 | init {
8 | layout = FlowLayout()
9 | }
10 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/FilterDTO.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import java.util.UUID;
4 |
5 | public record FilterDTO(UUID id, String name) {
6 | @Override
7 | public String toString() {
8 | return name;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/InstallTabSwitchListenerEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class InstallTabSwitchListenerEvent extends BaseEvent {
4 | public enum INSTALL_TYPE {INSTALL, REMOVE}
5 |
6 | public INSTALL_TYPE event;
7 | }
8 |
--------------------------------------------------------------------------------
/maven-repository/airsquared/JMacNotification/1.1/_remote.repositories:
--------------------------------------------------------------------------------
1 | #NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
2 | #Fri Dec 03 16:02:37 CET 2021
3 | JMacNotification-1.1.pom>=
4 | JMacNotification-1.1.jar>=
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/filmInformation/DisabledCheckBox.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.filmInformation;
2 |
3 | import javax.swing.*;
4 |
5 | public class DisabledCheckBox extends JCheckBox {
6 | public DisabledCheckBox() {
7 | setEnabled(false);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/maven-repository/com/formdev/jformdesigner-annotations/1.0/_remote.repositories:
--------------------------------------------------------------------------------
1 | #NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
2 | #Tue Apr 08 14:58:20 CEST 2025
3 | jformdesigner-annotations-1.0.jar>=
4 | jformdesigner-annotations-1.0.pom>=
5 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/DownloadRateLimitChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | public class DownloadRateLimitChangedEvent extends BaseEvent {
4 | /**
5 | * new limit in KBytes
6 | */
7 | public int newLimit;
8 | public boolean active;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/notification/INotificationCenter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.notification
2 |
3 | import java.io.Closeable
4 |
5 | /**
6 | * Interface for the platform specific notification implementation
7 | */
8 | interface INotificationCenter : Closeable {
9 | fun displayNotification(msg: NotificationMessage)
10 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/notification/NullNotificationCenter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.notification
2 |
3 | /**
4 | * A notification center which does nothing. Used when notifications are deactivated.
5 | */
6 | class NullNotificationCenter : INotificationCenter {
7 | override fun displayNotification(msg: NotificationMessage) {}
8 | override fun close() {}
9 | }
--------------------------------------------------------------------------------
/src/main/resources/raven/toast/svg/info.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/test/kotlin/mediathek/tool/dns/IPvPreferenceModeTest.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.dns
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 |
6 | class IPvPreferenceModeTest {
7 |
8 | @Test
9 | fun fromString() {
10 | val r = IPvPreferenceMode.fromString("ip_v6_only")
11 | assertEquals(IPvPreferenceMode.IPV6_ONLY, r)
12 | }
13 | }
--------------------------------------------------------------------------------
/src/main/resources/raven/toast/svg/success.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/maven-repository/airsquared/JMacNotification/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | airsquared
4 | JMacNotification
5 |
6 | 1.1
7 |
8 | 1.1
9 |
10 | 20211203150237
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/update/ServerProgramInformation.kt:
--------------------------------------------------------------------------------
1 | package mediathek.update
2 |
3 | import mediathek.tool.Version
4 |
5 | data class ServerProgramInformation(val version: Version) {
6 | class ParserTags {
7 | companion object {
8 | const val INFO = "Info"
9 | const val VERSION = "Program_Version"
10 | const val INFO_NO = "number"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/maven-repository/com/formdev/jformdesigner-annotations/maven-metadata-local.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.formdev
4 | jformdesigner-annotations
5 |
6 | 1.0
7 |
8 | 1.0
9 |
10 | 20250408125820
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | dist/javadoc
3 | /.gradle/
4 | /bin/
5 | /.checkstyle
6 | .classpath
7 | .project
8 | .settings/
9 | *.build
10 | MediathekView.exe
11 | res/Icons/Sender
12 | /.idea/
13 | /.nb-gradle/
14 | /src/main/resources/version.properties
15 | deploy.key
16 | RepoZugang.properties
17 | /target/
18 | /dependency-reduced-pom.xml
19 | *.iml
20 | /install4j*/
21 | /res/macOS/bin
22 | `/.vs/
23 | /javafx_sdk/mac/aarch64/javafx-sdk/
24 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/UpdateStateChangedEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.messages;
2 |
3 | /**
4 | *
5 | * @author Klaus
6 | */
7 | public class UpdateStateChangedEvent extends BaseEvent {
8 | private final boolean new_state;
9 |
10 | public UpdateStateChangedEvent(boolean new_state) {
11 | this.new_state = new_state;
12 | }
13 |
14 | public boolean isActive() {
15 | return new_state;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/mainwindow/Log4jShutdownHookThread.kt:
--------------------------------------------------------------------------------
1 | package mediathek.mainwindow
2 |
3 | import mediathek.tool.Log4jShutdownCallbackRegistry.Companion.execute
4 |
5 | /**
6 | * Gracefully shutdown config and log.
7 | * This may be necessary in case the app is not properly quit.
8 | */
9 | class Log4jShutdownHookThread : Thread() {
10 | override fun run() {
11 | //shut down log4j
12 | execute()
13 | }
14 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialog/ButtonPanel.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.dialog
2 |
3 | import java.awt.BorderLayout
4 | import javax.swing.JPanel
5 | import javax.swing.border.EmptyBorder
6 |
7 | /**
8 | * Placeholder {@link JPanel} with an empty border.
9 | * Used for button panels in a dialog.
10 | */
11 | class ButtonPanel : JPanel() {
12 | init {
13 | layout = BorderLayout()
14 | border = EmptyBorder(0, 10, 10, 10)
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/DarkModeFactory.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import com.formdev.flatlaf.FlatDarkLaf
4 | import com.formdev.flatlaf.themes.FlatMacDarkLaf
5 | import org.apache.commons.lang3.SystemUtils
6 | import javax.swing.LookAndFeel
7 |
8 | object DarkModeFactory {
9 | @JvmStatic
10 | val lookAndFeel: LookAndFeel
11 | get() {
12 | return if (SystemUtils.IS_OS_MAC_OSX) FlatMacDarkLaf() else FlatDarkLaf()
13 | }
14 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/SenderListComboBoxModel.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import ca.odell.glazedlists.swing.DefaultEventComboBoxModel;
4 | import mediathek.config.Daten;
5 |
6 | public class SenderListComboBoxModel extends DefaultEventComboBoxModel {
7 |
8 | public SenderListComboBoxModel() {
9 | super(new EventListWithEmptyFirstEntry(Daten.getInstance().getAllSendersList()));
10 | setSelectedItem("");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/LightModeFactory.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import com.formdev.flatlaf.FlatLightLaf
4 | import com.formdev.flatlaf.themes.FlatMacLightLaf
5 | import org.apache.commons.lang3.SystemUtils
6 | import javax.swing.LookAndFeel
7 |
8 | object LightModeFactory {
9 | @JvmStatic
10 | val lookAndFeel: LookAndFeel
11 | get() {
12 | return if (SystemUtils.IS_OS_MAC_OSX) FlatMacLightLaf() else FlatLightLaf()
13 | }
14 | }
--------------------------------------------------------------------------------
/src/main/kotlin/feed/FeedMessage.kt:
--------------------------------------------------------------------------------
1 | package feed
2 |
3 | /*
4 | * A RSS message
5 | */
6 | data class FeedMessage(
7 | val title: String, val description: String, val link: String, val author: String,
8 | val guid: String
9 | ) {
10 | override fun toString(): String {
11 | return ("FeedMessage [title=" + title + ", description=" + description
12 | + ", link=" + link + ", author=" + author + ", guid=" + guid
13 | + "]")
14 | }
15 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/PanelVorlage.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui;
2 |
3 | import mediathek.config.Daten;
4 |
5 | import javax.swing.*;
6 |
7 | public abstract class PanelVorlage extends JPanel {
8 | protected final Daten daten;
9 | protected boolean stopBeob;
10 | protected final JFrame parentComponent;
11 |
12 | public PanelVorlage(Daten daten, JFrame pparentComponent) {
13 | this.daten = daten;
14 | parentComponent = pparentComponent;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/kotlin/mediathek/daten/blacklist/BlacklistTagsTest.kt:
--------------------------------------------------------------------------------
1 | package mediathek.daten.blacklist
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Assertions.assertTrue
5 | import org.junit.jupiter.api.Test
6 |
7 | class BlacklistTagsTest {
8 |
9 | @Test
10 | fun fromXmlTag() {
11 | val r = BlacklistTags.fromXmlTag("black-sender")
12 | assertTrue(r.isPresent)
13 | assertEquals(r.get(), BlacklistTags.SENDER)
14 | }
15 | }
--------------------------------------------------------------------------------
/src/main/resources/raven/toast/svg/warning.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/history/AboHistoryDialog.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.history;
2 |
3 | import mediathek.gui.dialog.StandardCloseDialog;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 |
8 | public class AboHistoryDialog extends StandardCloseDialog {
9 | public AboHistoryDialog(Frame owner) {
10 | super(owner, "Abo-Historie", true);
11 | }
12 |
13 | @Override
14 | public JComponent createContentPanel() {
15 | return new PanelErledigteUrls();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/test/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/datum/Datum.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.datum;
2 |
3 | import java.util.Date;
4 |
5 | public class Datum extends Date {
6 | public Datum() {
7 | super();
8 | }
9 |
10 | public Datum(long l) {
11 | super(l);
12 | }
13 |
14 | @Override
15 | public String toString() {
16 | if (getTime() == 0) {
17 | return "";
18 | } else {
19 | return DateUtil.FORMATTER.format(DateUtil.convertToLocalDate(this));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/resources/raven/toast/svg/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/CopyToClipboardAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import java.awt.event.ActionEvent
4 | import javax.swing.AbstractAction
5 |
6 | class CopyToClipboardAction(private val webSiteUrl: String) : AbstractAction() {
7 | init {
8 | putValue(NAME, "In Zwischenablage kopieren")
9 | }
10 |
11 | override fun actionPerformed(e: ActionEvent) {
12 | try {
13 | GuiFunktionen.copyToClipboard(webSiteUrl)
14 | } catch (ignored: Exception) {
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/main/kotlin/feed/Feed.kt:
--------------------------------------------------------------------------------
1 | package feed
2 |
3 | class Feed(
4 | val title: String, val link: String, val description: String, val language: String,
5 | val copyright: String, val pubDate: String
6 | ) {
7 | val messages: ArrayList = ArrayList()
8 | override fun toString(): String {
9 | return ("Feed [copyright=" + copyright + ", description=" + description
10 | + ", language=" + language + ", link=" + link + ", pubDate="
11 | + pubDate + ", title=" + title + "]")
12 | }
13 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmlisten/reader/NoOpDateFilter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.filmlisten.reader
2 |
3 | import mediathek.daten.DatenFilm
4 | import mediathek.daten.ListeFilme
5 |
6 | internal class NoOpDateFilter(listeFilme: ListeFilme) : IDateFilter {
7 | private val listeFilme: ListeFilme
8 |
9 | override fun filter(film: DatenFilm) {
10 | // just add the film objet to the list as we are not supposed to do any filtering
11 | listeFilme.add(film)
12 | }
13 |
14 | init {
15 | this.listeFilme = listeFilme
16 | }
17 | }
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/gui/actions/ResetFilterDialogPosition.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions
2 |
3 | import mediathek.mainwindow.MediathekGui
4 | import java.awt.event.ActionEvent
5 | import javax.swing.AbstractAction
6 |
7 | class ResetFilterDialogPosition(private val mediathekGui: MediathekGui) : AbstractAction() {
8 | init {
9 | putValue(NAME, "Filterdialog-Position zurücksetzen")
10 | }
11 |
12 | override fun actionPerformed(e: ActionEvent) {
13 | mediathekGui.tabFilme?.swingFilterDialog?.setLocation(100, 100)
14 | }
15 | }
--------------------------------------------------------------------------------
/maven-repository/airsquared/JMacNotification/1.1/JMacNotification-1.1.pom:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | airsquared
6 | JMacNotification
7 | 1.1
8 | POM was created from install:install-file
9 |
10 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmeSuchen/ListenerFilmeLaden.java:
--------------------------------------------------------------------------------
1 | package mediathek.filmeSuchen;
2 |
3 | import java.util.EventListener;
4 |
5 | public class ListenerFilmeLaden implements EventListener {
6 | public void start(ListenerFilmeLadenEvent e) {
7 | }
8 |
9 | public void progress(ListenerFilmeLadenEvent e) {
10 | }
11 |
12 | public void fertig(ListenerFilmeLadenEvent e) {
13 | }
14 |
15 | public void fertigOnlyOne(ListenerFilmeLadenEvent e) {
16 | // dient dem Melden des ersten Mal Laden der Filmliste beim ProgStart
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/ShowProgramInfosAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.update.ProgrammUpdateSuchen;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 |
8 | public class ShowProgramInfosAction extends AbstractAction {
9 | public ShowProgramInfosAction() {
10 | putValue(Action.NAME,"Programminfos anzeigen...");
11 | }
12 |
13 | @Override
14 | public void actionPerformed(ActionEvent e) {
15 | new ProgrammUpdateSuchen().checkVersion(false, true, false, false);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/controller/history/SeenHistoryShutdownHook.kt:
--------------------------------------------------------------------------------
1 | package mediathek.controller.history
2 |
3 | import java.sql.Connection
4 |
5 | /**
6 | * Shutdown hook implementation to close a SQL connection if it is still open at program end.
7 | */
8 | class SeenHistoryShutdownHook(private val connection: Connection?) : Thread() {
9 | override fun run() {
10 | if (connection == null)
11 | return
12 | else {
13 | if (!connection.isClosed) {
14 | connection.close()
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmeSuchen/ListenerFilmeLadenEvent.java:
--------------------------------------------------------------------------------
1 | package mediathek.filmeSuchen;
2 |
3 | public class ListenerFilmeLadenEvent {
4 |
5 | public String senderUrl;
6 | public String text;
7 | public int max;
8 | public int progress;
9 | public final boolean fehler;
10 |
11 | public ListenerFilmeLadenEvent(String ssender, String ttext, int mmax, int pprogress, boolean ffehler) {
12 | senderUrl = ssender;
13 | text = ttext;
14 | max = mmax;
15 | progress = pprogress;
16 | fehler = ffehler;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/SearchProgramUpdateAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.update.ProgrammUpdateSuchen;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 |
8 | public class SearchProgramUpdateAction extends AbstractAction {
9 | public SearchProgramUpdateAction() {
10 | putValue(Action.NAME, "Nach Update suchen...");
11 | }
12 |
13 | @Override
14 | public void actionPerformed(ActionEvent e) {
15 | new ProgrammUpdateSuchen().checkVersion(true, false, false, false);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/maven-repository/com/formdev/jformdesigner-annotations/1.0/jformdesigner-annotations-1.0.pom:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | com.formdev
6 | jformdesigner-annotations
7 | 1.0
8 | POM was created from install:install-file
9 |
10 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/NoSelectionErrorDialog.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import mediathek.config.Konstanten;
4 | import org.jetbrains.annotations.Nullable;
5 |
6 | import javax.swing.*;
7 | import java.awt.*;
8 |
9 | public class NoSelectionErrorDialog {
10 |
11 | public static void show(@Nullable Component parent) {
12 | JOptionPane.showMessageDialog(parent, "Der Befehl kann nicht ausgeführt werden.\n" +
13 | "Sie haben keinen Tabelleneintrag ausgewählt.",
14 | Konstanten.PROGRAMMNAME, JOptionPane.ERROR_MESSAGE);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/blacklist/BlacklistTags.kt:
--------------------------------------------------------------------------------
1 | package mediathek.daten.blacklist
2 |
3 | import java.util.*
4 |
5 | enum class BlacklistTags(val index: Int, val xmlName: String) {
6 | SENDER(0, "black-sender"),
7 | THEMA(1, "black-thema"),
8 | TITEL(2, "black-titel"),
9 | THEMA_TITEL(3, "black-thema-titel");
10 |
11 | companion object {
12 | @JvmStatic
13 | fun fromXmlTag(tag: String): Optional {
14 | return Arrays.stream(entries.toTypedArray()).filter { e: BlacklistTags -> e.xmlName == tag }.findAny()
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/test/java/mediathek/tool/LanguageCodeTest.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import java.util.EnumSet;
6 |
7 | import static org.junit.jupiter.api.Assertions.assertFalse;
8 |
9 | class LanguageCodeTest {
10 | /**
11 | * Test if all codes can be converted to 3 letter code and there is no exception.
12 | */
13 | @Test
14 | void testConversion() {
15 | for (var code : EnumSet.allOf(LanguageCode.class)) {
16 | var out = code.getISO3Language();
17 | assertFalse(out.isEmpty());
18 | }
19 |
20 | }
21 | }
--------------------------------------------------------------------------------
/src/main/java/raven/toast/ToastClientProperties.java:
--------------------------------------------------------------------------------
1 | package raven.toast;
2 |
3 | public interface ToastClientProperties {
4 | String TOAST_ICON = "Toast.icon";
5 | String TOAST_COMPONENT = "Toast.component";
6 | String TOAST_SHOW_CLOSE_BUTTON = "Toast.showCloseButton";
7 | String TOAST_CLOSE_CALLBACK = "Toast.closeCallback";
8 | String TOAST_CLOSE_ICON = "Toast.closeIcon";
9 | String TOAST_SUCCESS_ICON = "Toast.success.icon";
10 | String TOAST_INFO_ICON = "Toast.info.icon";
11 | String TOAST_WARNING_ICON = "Toast.warning.icon";
12 | String TOAST_ERROR_ICON = "Toast.error.icon";
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialog/reset/ResetSettingsDialog.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.dialog.reset;
2 |
3 | import mediathek.config.Daten;
4 | import mediathek.gui.dialog.StandardCloseDialog;
5 |
6 | import javax.swing.*;
7 | import java.awt.*;
8 |
9 | public class ResetSettingsDialog extends StandardCloseDialog {
10 | public ResetSettingsDialog(Frame owner, Daten daten) {
11 | super(owner, "Programm zurücksetzen", true);
12 | setResizable(false);
13 | }
14 |
15 | @Override
16 | public JComponent createContentPanel() {
17 | return new ResetSettingsPanel(null);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/searchfilters/FinalStagePatternFilter.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_film.searchfilters;
2 |
3 | import mediathek.daten.DatenFilm;
4 | import mediathek.tool.Filter;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | import java.util.function.Predicate;
8 |
9 | public record FinalStagePatternFilter(@NotNull String[] searchStr) implements Predicate {
10 | @Override
11 | public boolean test(@NotNull DatenFilm film) {
12 | return Filter.pruefen(searchStr, film.getThema())
13 | || Filter.pruefen(searchStr, film.getTitle());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/SVGIconUtilities.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import com.formdev.flatlaf.extras.FlatSVGIcon;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | public class SVGIconUtilities {
7 | public static FlatSVGIcon createSVGIcon(@NotNull String resource) {
8 | return createSVGIcon(resource, 16f);
9 | }
10 |
11 | public static FlatSVGIcon createSVGIcon(@NotNull String resource, float height) {
12 | FlatSVGIcon icon = new FlatSVGIcon(resource);
13 | float scaleFactor = (1f / icon.getIconHeight()) * height;
14 | return icon.derive(scaleFactor);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/resources/raven/toast/svg/error.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/test/java/mediathek/config/MVConfigTest.java:
--------------------------------------------------------------------------------
1 | package mediathek.config;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertFalse;
6 | import static org.junit.jupiter.api.Assertions.assertTrue;
7 |
8 | class MVConfigTest {
9 |
10 | @Test
11 | void enum_find_invalid() {
12 | var res = MVConfig.Configs.find("blaXblubb");
13 | assertFalse(res);
14 | }
15 |
16 | @Test
17 | void enum_find_valid() {
18 | var res = MVConfig.Configs.find(MVConfig.Configs.SYSTEM_BLACKLIST_ZUKUNFT_NICHT_ANZEIGEN.cValue);
19 | assertTrue(res);
20 | }
21 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/models/NonEditableTableModel.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.models;
2 |
3 | import javax.swing.table.DefaultTableModel;
4 |
5 | /**
6 | * Simple extension of DefaultTableModel which prevents cell from being editable
7 | */
8 | public class NonEditableTableModel extends DefaultTableModel {
9 | public NonEditableTableModel() {
10 | super();
11 | }
12 |
13 | public NonEditableTableModel(Object[][] data, Object[] columnNames) {
14 | super(data, columnNames);
15 | }
16 |
17 | @Override
18 | public boolean isCellEditable(int i, int j) {
19 | return false;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/notification/MacNotificationCenter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.notification
2 |
3 | import airsquared.JMacNotification.NSUserNotification
4 | import java.io.IOException
5 |
6 | class MacNotificationCenter : INotificationCenter {
7 | override fun displayNotification(msg: NotificationMessage) {
8 | val notification = NSUserNotification()
9 | notification.title = msg.title
10 | notification.informativeText = msg.message
11 | notification.hasReplyButton = false
12 | notification.show()
13 | }
14 |
15 | @Throws(IOException::class)
16 | override fun close() {
17 | }
18 | }
--------------------------------------------------------------------------------
/src/test/kotlin/mediathek/daten/abo/AboTagsTest.kt:
--------------------------------------------------------------------------------
1 | package mediathek.daten.abo
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Assertions.assertTrue
5 | import org.junit.jupiter.api.Test
6 |
7 | class AboTagsTest {
8 |
9 | @Test
10 | fun fromXmlTag() {
11 | val r = AboTags.fromXmlTag("Sender")
12 | assertTrue(r.isPresent)
13 | assertEquals(r.get(), AboTags.SENDER)
14 | }
15 |
16 | @Test
17 | fun fromIndex() {
18 | val r = AboTags.fromIndex(DatenAbo.ABO_NR)
19 | assertTrue(r.isPresent)
20 | assertEquals(r.get(), AboTags.NR)
21 | }
22 | }
--------------------------------------------------------------------------------
/src/test/java/mediathek/tool/ttml/TimedTextMarkupLanguageParserTest.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.ttml;
2 |
3 | import mediathek.tool.ttml.parsers.EbuTimedTextMarkupLanguageParser;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static org.junit.jupiter.api.Assertions.assertThrows;
7 |
8 | class TimedTextMarkupLanguageParserTest {
9 | @Test
10 | void getSubtitleList() {
11 | try (TimedTextMarkupLanguageParser parser = new EbuTimedTextMarkupLanguageParser()) {
12 | var list = parser.getSubtitleList();
13 | assertThrows(UnsupportedOperationException.class, () -> list.add(new Subtitle()));
14 | }}
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/cellrenderer/SelfEvictingSenderIconCache.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.cellrenderer;
2 |
3 | import mediathek.tool.timer.TimerPool;
4 |
5 | import javax.swing.*;
6 | import java.util.concurrent.ConcurrentHashMap;
7 | import java.util.concurrent.TimeUnit;
8 |
9 | /**
10 | * A cache for sender icons at a specific cell dimension.
11 | * Will get cleared periodically.
12 | */
13 | public class SelfEvictingSenderIconCache extends ConcurrentHashMap {
14 | public SelfEvictingSenderIconCache() {
15 | TimerPool.getTimerPool().scheduleAtFixedRate(this::clear, 5, 5, TimeUnit.MINUTES);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/models/TModelColor.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.models;
2 |
3 | import mediathek.config.MVColor;
4 | import mediathek.tool.MVC;
5 |
6 | public class TModelColor extends NonEditableTableModel {
7 | public TModelColor(Object[][] data) {
8 | super(data, new String[]{"Beschreibung", "Farbe"});
9 | }
10 |
11 | @Override
12 | public Class> getColumnClass(int columnIndex) {
13 | Class> result;
14 | if (columnIndex == MVColor.MVC_COLOR) {
15 | result = MVC.class;
16 | } else {
17 | result = String.class;
18 | }
19 | return result;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/StopDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 |
8 | public class StopDownloadsAction extends AbstractAction {
9 | private final GuiDownloads guiDownloads;
10 |
11 | public StopDownloadsAction(GuiDownloads guiDownloads) {
12 | this.guiDownloads = guiDownloads;
13 | putValue(Action.NAME, "Ausgewählte Downloads stoppen");
14 | }
15 |
16 | @Override
17 | public void actionPerformed(ActionEvent e) {
18 | guiDownloads.stoppen(false);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_geo.txt:
--------------------------------------------------------------------------------
1 |
2 | Nicht alle Filme lassen sich im Ausland abrufen.
3 | Wenn geblockte Filme markiert werden sollen,
4 | kann man hier seinen Standort angeben.
5 |
6 | Der Download geogeblockter Sendungen
7 | bricht im Ausland sofort ab (Download
8 | "fehlerhaft"). MediathekView kennt nicht alle
9 | Muster für geogeblockte Sendungen. Ob ein
10 | fehlerhafter Download auf Geoblocking
11 | zurückzuführen ist, zeigt sich beim Klick auf
12 | den Link zur Sendung ("zur Website") ganz
13 | unten im Tab "Filme". Wenn die Sendung
14 | auch auf der Website des Senders nicht
15 | abgespielt werden kann, liegt fast immer
16 | Geoblocking vor.
17 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/StopAllDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 |
8 | public class StopAllDownloadsAction extends AbstractAction {
9 |
10 | private final GuiDownloads guiDownloads;
11 |
12 | public StopAllDownloadsAction(GuiDownloads guiDownloads) {
13 | this.guiDownloads = guiDownloads;
14 | putValue(Action.NAME, "Alle Downloads stoppen");
15 | }
16 |
17 | @Override
18 | public void actionPerformed(ActionEvent e) {
19 | guiDownloads.stoppen(true);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/gui/actions/CreateNewAboAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions
2 |
3 | import mediathek.daten.ListeAbo
4 | import mediathek.tool.SVGIconUtilities
5 | import java.awt.event.ActionEvent
6 | import javax.swing.AbstractAction
7 |
8 | class CreateNewAboAction(private val listeAbo: ListeAbo) : AbstractAction() {
9 | override fun actionPerformed(e: ActionEvent?) {
10 | listeAbo.addAbo("Neu", "", "", "")
11 | }
12 |
13 | init {
14 | putValue(NAME, "Abo anlegen...")
15 | putValue(SHORT_DESCRIPTION, "Abo anlegen")
16 | putValue(SMALL_ICON, SVGIconUtilities.createSVGIcon("icons/fontawesome/plus.svg"))
17 | }
18 | }
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/gui/actions/ShowAboutAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions
2 |
3 | import mediathek.gui.dialog.AboutDialog
4 | import mediathek.mainwindow.MediathekGui
5 | import mediathek.tool.GuiFunktionen
6 | import java.awt.event.ActionEvent
7 | import javax.swing.AbstractAction
8 |
9 | class ShowAboutAction : AbstractAction() {
10 | override fun actionPerformed(e: ActionEvent?) {
11 | val dialog = AboutDialog(MediathekGui.ui())
12 | GuiFunktionen.centerOnScreen(dialog, false)
13 | dialog.isVisible = true
14 | dialog.dispose()
15 | }
16 |
17 | init {
18 | putValue(NAME, "Über dieses Programm...")
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/tool/dns/IPvPreferenceMode.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.dns
2 |
3 | /**
4 | * Specifies, which IP addresses shall be used in DNS resolution.
5 | */
6 | enum class IPvPreferenceMode(val code: String) {
7 | SYSTEM("system"),
8 | IPV6_FIRST("ip_v6"),
9 | IPV4_FIRST("ip_v4"),
10 | IPV6_ONLY("ip_v6_only"),
11 | IPV4_ONLY("ip_v4_only");
12 |
13 | override fun toString(): String {
14 | return code
15 | }
16 |
17 | companion object {
18 | @JvmStatic
19 | fun fromString(ipMode: String): IPvPreferenceMode =
20 | entries.find { it.code == ipMode } ?: throw IllegalArgumentException("Unknown value $ipMode")
21 | }
22 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/StopAllWaitingDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 |
8 | public class StopAllWaitingDownloadsAction extends AbstractAction {
9 | private final GuiDownloads guiDownloads;
10 |
11 | public StopAllWaitingDownloadsAction(GuiDownloads guiDownloads) {
12 | this.guiDownloads = guiDownloads;
13 | putValue(Action.NAME, "Wartende Downloads stoppen");
14 | }
15 |
16 | @Override
17 | public void actionPerformed(ActionEvent e) {
18 | guiDownloads.stopAllWaitingDownloads();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/gui/actions/ShowBandwidthUsageAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions
2 |
3 | import mediathek.gui.bandwidth.BandwidthDialog
4 | import mediathek.mainwindow.MediathekGui
5 | import java.awt.event.ActionEvent
6 | import java.util.*
7 | import javax.swing.AbstractAction
8 |
9 | class ShowBandwidthUsageAction(private val mediathekGui: MediathekGui) : AbstractAction() {
10 | var dialogOptional = Optional.empty()
11 |
12 | init {
13 | putValue(NAME, "Bandbreitennutzung")
14 | }
15 |
16 | override fun actionPerformed(e: ActionEvent?) {
17 | val dialog = BandwidthDialog(mediathekGui, this)
18 | dialog.isVisible = true
19 | }
20 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/filmInformation/HtmlMultilineLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.filmInformation;
2 |
3 | import javax.swing.*;
4 |
5 | public class HtmlMultilineLabel extends JLabel {
6 | @Override
7 | public void setText(String text) {
8 | super.setText(prepareString(text));
9 | }
10 |
11 | private String prepareString(String text) {
12 | var newText = "";
13 | if (!text.startsWith("")) {
14 | newText += text;
15 | newText += "";
16 | }
17 | else
18 | newText = text;
19 |
20 | return newText;
21 | }
22 |
23 | public HtmlMultilineLabel() {
24 | super();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/StartAllDownloadsTimedAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 |
8 | public class StartAllDownloadsTimedAction extends AbstractAction {
9 | private final GuiDownloads guiDownloads;
10 |
11 | public StartAllDownloadsTimedAction(GuiDownloads guiDownloads) {
12 | this.guiDownloads = guiDownloads;
13 | putValue(Action.NAME, "Alle Downloads zeitverzögert starten...");
14 | }
15 |
16 | @Override
17 | public void actionPerformed(ActionEvent e) {
18 | guiDownloads.startAllDownloadsAtSpecificTime();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/minus.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/DisposeDialogAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import javax.swing.*;
4 | import java.awt.event.ActionEvent;
5 |
6 | /**
7 | * Generic action for disposing dialogs.
8 | */
9 | @SuppressWarnings("serial")
10 | public class DisposeDialogAction extends AbstractAction {
11 |
12 | private final JDialog dlg;
13 |
14 | public DisposeDialogAction(JDialog dlg, String description, String shortDescription) {
15 | super();
16 | putValue(NAME, description);
17 | putValue(SHORT_DESCRIPTION, shortDescription);
18 | this.dlg = dlg;
19 | }
20 |
21 | public void actionPerformed(ActionEvent e) {
22 | dlg.dispose();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/ShowAboHistoryAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.history.AboHistoryDialog;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class ShowAboHistoryAction extends AbstractAction {
10 | private final Frame owner;
11 |
12 | public ShowAboHistoryAction(Frame owner) {
13 | this.owner = owner;
14 |
15 | putValue(Action.NAME, "Abo-Historie anzeigen...");
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | AboHistoryDialog dialog = new AboHistoryDialog(owner);
21 | dialog.pack();
22 | dialog.setVisible(true);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tasks/BlacklistFilterWorker.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tasks;
2 |
3 | import mediathek.config.Daten;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class BlacklistFilterWorker extends SwingWorker {
9 |
10 | public BlacklistFilterWorker(@NotNull JLabel progLabel, @NotNull JProgressBar progressBar) {
11 | SwingUtilities.invokeLater(() -> {
12 | progLabel.setText("Blacklist anwenden");
13 | progressBar.setIndeterminate(true);
14 | });
15 | }
16 |
17 | @Override
18 | protected Void doInBackground() {
19 | Daten.getInstance().getListeBlacklist().filterListe();
20 |
21 | return null;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/QuitAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.mainwindow.MediathekGui;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 | import java.awt.event.KeyEvent;
8 |
9 | public class QuitAction extends AbstractAction {
10 | private final MediathekGui mediathekGui;
11 |
12 | public QuitAction(MediathekGui mediathekGui) {
13 | this.mediathekGui = mediathekGui;
14 | putValue(Action.NAME, "Beenden");
15 | putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q, KeyEvent.CTRL_DOWN_MASK));
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | mediathekGui.quitApplication();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/AboLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class AboLabel extends JLabel {
9 | public AboLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Anzahl der Abos in der Liste");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 |
13 | }
14 | private void process(@NotNull DownloadStartInfo info) {
15 | String abo = (info.num_abos == 1) ? "1 Abo" : info.num_abos + " Abos";
16 | setText(abo);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/circle-half-stroke.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tasks/RefreshAboWorker.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tasks;
2 |
3 | import mediathek.config.Daten;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class RefreshAboWorker extends SwingWorker {
9 |
10 | public RefreshAboWorker(@NotNull JLabel progLabel, @NotNull JProgressBar progressBar) {
11 | SwingUtilities.invokeLater(() -> {
12 | progLabel.setText("Abos eintragen");
13 | progressBar.setIndeterminate(true);
14 | });
15 | }
16 |
17 | @Override
18 | protected Void doInBackground() {
19 | var daten = Daten.getInstance();
20 | daten.getListeAbo().setAboFuerFilm(daten.getListeFilme(), false);
21 |
22 | return null;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/java/mediathek/tool/SingleInstanceTest.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertFalse;
6 | import static org.junit.jupiter.api.Assertions.assertTrue;
7 |
8 | class SingleInstanceTest {
9 | @Test
10 | void instance1_not_active() {
11 | try (var instance1 = new SingleInstance()) {
12 | assertFalse(instance1.isAppAlreadyActive());
13 | }
14 | }
15 |
16 | @Test
17 | void instance2_activity_test() {
18 | try (var instance1 = new SingleInstance();
19 | var instance2 = new SingleInstance()) {
20 | assertFalse(instance1.isAppAlreadyActive());
21 | assertTrue(instance2.isAppAlreadyActive());
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/EditDownloadAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.tool.SVGIconUtilities;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class EditDownloadAction extends AbstractAction {
10 | private final GuiDownloads guiDownloads;
11 |
12 | public EditDownloadAction(GuiDownloads guiDownloads) {
13 | this.guiDownloads = guiDownloads;
14 | putValue(Action.NAME, "Download ändern");
15 | putValue(Action.SMALL_ICON, SVGIconUtilities.createSVGIcon("icons/fontawesome/pen-to-square.svg"));
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | guiDownloads.editDownload();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/ShowDuplicateStatisticsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.duplicates.statistics.DuplicateStatisticsDialog;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 | import java.awt.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class ShowDuplicateStatisticsAction extends AbstractAction {
11 | private final Frame owner;
12 |
13 | public ShowDuplicateStatisticsAction(@NotNull Frame owner) {
14 | this.owner = owner;
15 | putValue(Action.NAME, "Film-Statistik anzeigen");
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | var dlg = new DuplicateStatisticsDialog(owner, this);
21 | dlg.setVisible(true);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialogEinstellungen/allgemein/TextFieldConfigWriter.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.dialogEinstellungen.allgemein;
2 |
3 | import mediathek.tool.ApplicationConfiguration;
4 |
5 | import javax.swing.*;
6 | import java.awt.event.ActionEvent;
7 | import java.awt.event.ActionListener;
8 |
9 | /**
10 | * Generic config writer for textfields.
11 | * Action will be performed on Swing EDT.
12 | */
13 | record TextFieldConfigWriter(JTextField control,
14 | String configPropertyKey) implements ActionListener {
15 |
16 | @Override
17 | public void actionPerformed(ActionEvent e) {
18 | final String controlText = control.getText();
19 | ApplicationConfiguration.getConfiguration().setProperty(configPropertyKey, controlText);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/table/MVProgTable.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.table;
2 |
3 | import mediathek.daten.DatenProg;
4 | import mediathek.tool.models.NonEditableTableModel;
5 |
6 | import java.util.Optional;
7 |
8 | public class MVProgTable extends MVTable {
9 | public MVProgTable() {
10 | super(DatenProg.MAX_ELEM, new boolean[DatenProg.MAX_ELEM],
11 | Optional.empty(),
12 | Optional.empty(),
13 | Optional.empty());
14 |
15 | setModel(new NonEditableTableModel(new Object[][]{}, DatenProg.COLUMN_NAMES));
16 | }
17 |
18 | @Override
19 | protected void spaltenAusschalten() {
20 | //do nothing
21 | }
22 |
23 | @Override
24 | public void calculateRowHeight() {
25 | // do nothing
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/caret-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/AdvanceDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.tool.SVGIconUtilities;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class AdvanceDownloadsAction extends AbstractAction {
10 | private final GuiDownloads guiDownloads;
11 |
12 | public AdvanceDownloadsAction(GuiDownloads guiDownloads) {
13 | this.guiDownloads = guiDownloads;
14 | putValue(Action.NAME, "Downloads vorziehen");
15 | putValue(Action.SMALL_ICON, SVGIconUtilities.createSVGIcon("icons/fontawesome/arrow-up.svg"));
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | guiDownloads.downloadsVorziehen();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/DeleteDownloadAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.tool.SVGIconUtilities;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class DeleteDownloadAction extends AbstractAction {
10 | private final GuiDownloads guiDownloads;
11 |
12 | public DeleteDownloadAction(GuiDownloads guiDownloads) {
13 | this.guiDownloads = guiDownloads;
14 | putValue(Action.SMALL_ICON, SVGIconUtilities.createSVGIcon("icons/fontawesome/xmark.svg"));
15 | putValue(Action.NAME, "gespeicherten Film (Datei) löschen");
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | guiDownloads.filmLoeschen_();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/OpenTargetFolderAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.tool.SVGIconUtilities;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class OpenTargetFolderAction extends AbstractAction {
10 | private final GuiDownloads guiDownloads;
11 |
12 | public OpenTargetFolderAction(GuiDownloads guiDownloads) {
13 | this.guiDownloads = guiDownloads;
14 | putValue(Action.NAME, "Zielordner öffnen");
15 | putValue(Action.SMALL_ICON, SVGIconUtilities.createSVGIcon("icons/fontawesome/folder-open.svg"));
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | guiDownloads.zielordnerOeffnen();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/StartDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.tool.SVGIconUtilities;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class StartDownloadsAction extends AbstractAction {
10 | private final GuiDownloads guiDownloads;
11 |
12 | public StartDownloadsAction(GuiDownloads guiDownloads) {
13 | this.guiDownloads = guiDownloads;
14 | putValue(Action.NAME, "Ausgewählte Downloads starten");
15 | putValue(Action.SMALL_ICON, SVGIconUtilities.createSVGIcon("icons/fontawesome/caret-down.svg"));
16 | }
17 |
18 | @Override
19 | public void actionPerformed(ActionEvent e) {
20 | guiDownloads.starten(false);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/OnlineSearchProviders.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_film
2 |
3 | enum class OnlineSearchProviders(private val displayName: String, val queryUrl: String) {
4 | BING("Bing", "https://www.bing.com/search?q="),
5 | DUCKDUCKGO("DuckDuckGo", "https://duckduckgo.com/?q="),
6 | GOOGLE("Google", "https://www.google.de/search?q="),
7 | IMDB("IMDB","https://www.imdb.com/find?q="),
8 | STARTPAGE("Startpage", "https://www.startpage.com/do/search?q="),
9 | MOVIEDB("The Movie Database", "https://www.themoviedb.org/search?language=de-DE&query="),
10 | TVDB("TheTVDB", "https://thetvdb.com/search?query="),
11 | YOUTUBE("YouTube", "https://www.youtube.com/results?search_query=");
12 |
13 | override fun toString(): String {
14 | return displayName
15 | }
16 | }
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/ellipsis-vertical.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/searchfilters/FinalStageFilterNoPattern.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_film.searchfilters;
2 |
3 | import mediathek.daten.DatenFilm;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.util.function.Predicate;
7 |
8 | public class FinalStageFilterNoPattern implements Predicate {
9 | private final String searchText;
10 |
11 | public FinalStageFilterNoPattern(@NotNull String[] searchStr) {
12 | this.searchText = searchStr[0];
13 | }
14 |
15 | @Override
16 | public boolean test(DatenFilm datenFilm) {
17 | // searchText cannot be empty as it is checked before
18 | return datenFilm.getThema().toLowerCase().contains(searchText)
19 | || datenFilm.getTitle().toLowerCase().contains(searchText);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_reset.txt:
--------------------------------------------------------------------------------
1 | "Einstellungen zum Abspielen/Aufzeichnen zurücksetzen"
2 |
3 | Damit werden alle Sets (auch eigene), die zum Abspielen
4 | und Aufzeichnen der Filme gebraucht werden, gelöscht.
5 | Anschließend werden die aktuellen Standardsets
6 | eingerichtet. Es kann dann direkt damit
7 | weitergearbeitet werden.
8 | Abos und Blacklist bleiben erhalten.
9 |
10 | Das sollte vor dem kompletten Zurücksetzen
11 | des Programms versucht werden.
12 |
13 |
14 | oder ==============================
15 |
16 | "Alle Einstellungen zurücksetzen"
17 |
18 | Damit wird das Programm in den
19 | Ursprungszustand zurückgesetzt.
20 |
21 | Es gehen ALLE Einstellungen verloren.
22 |
23 | Das Programm beendet sich und muss neu
24 | gestartet werden. Der neue Start beginnt
25 | mit dem Einrichtungsdialog.
26 |
27 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/mainwindow/SelectedListItemsLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.mainwindow;
2 |
3 | import javax.swing.*;
4 | import java.beans.PropertyChangeEvent;
5 | import java.beans.PropertyChangeListener;
6 |
7 | public class SelectedListItemsLabel extends JLabel implements PropertyChangeListener {
8 | public SelectedListItemsLabel(MediathekGui mediathekGui) {
9 | setText("0");
10 | setToolTipText("Ausgewählte Einträge der aktiven Tabelle");
11 | mediathekGui.selectedListItemsProperty.addSelectedItemsChangeListener(this);
12 | }
13 |
14 | @Override
15 | public void propertyChange(PropertyChangeEvent evt) {
16 | SwingUtilities.invokeLater(() -> {
17 | long items = (long) evt.getNewValue();
18 | setText(Long.toString(items));
19 | });
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_editDownloadProg.txt:
--------------------------------------------------------------------------------
1 |
2 | Der Programmaufruf wird von MediathekView in die einzelnen
3 | Teile (Programmschalter) zerlegt. Die einzelnen Programmschalter
4 | werden durch "<>" getrennt angegeben. Dadurch ist es
5 | möglich, auch Pfade mit Leerzeichen zu verwenden.
6 |
7 | Bei ÄNDERUNGEN des Programmaufrufs in diesem Dialog, muss diese Form
8 | verwendet werden.
9 |
10 | der Aufruf:
11 | PFAD/ffmpeg -i URL -c copy -bsf:a aac_adtstoasc ZIELPFAD/DATEI.mp4
12 |
13 | wird so angegeben:
14 | Pfad/ffmpeg<>-i<>URL<>-c<>copy<>-bsf:a<>aac_adtstoasc<>ZIELPFAD/DATEI.mp4
15 |
16 | Der Programmaufruf kann auch so (ohne <>) angegben werden:
17 | PFAD/ffmpeg -i URL -c copy -bsf:a aac_adtstoasc ZIELPFAD/DATEI.mp4
18 |
19 | Das funktioniert, kann dann aber bei Leerzeichen im Pfad zu Problemen
20 | führen.
21 |
22 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/TrailerTeaserChecker.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | /**
4 | * This class check if titel contains specific keywords.
5 | */
6 | class TrailerTeaserChecker {
7 | /**
8 | * Check if a string might belong to a trailer, teaser, etc.
9 | */
10 | fun check(content: String): Boolean {
11 | val lTitel = content.lowercase()
12 | return containsTrailer(lTitel) || containsTeaser(lTitel) || containsVorschau(lTitel)
13 | }
14 |
15 | private fun containsTrailer(titel: String): Boolean {
16 | return titel.contains("trailer")
17 | }
18 |
19 | private fun containsTeaser(titel: String): Boolean {
20 | return titel.contains("teaser")
21 | }
22 |
23 | private fun containsVorschau(titel: String): Boolean {
24 | return titel.contains("vorschau")
25 | }
26 | }
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/CustomConversionHandler.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import org.apache.commons.configuration2.convert.DefaultConversionHandler;
4 | import org.apache.commons.configuration2.interpol.ConfigurationInterpolator;
5 |
6 | import java.util.UUID;
7 |
8 | public class CustomConversionHandler extends DefaultConversionHandler {
9 |
10 |
11 |
12 | @Override
13 | @SuppressWarnings("unchecked")
14 | protected T convertValue(Object src, Class targetCls, ConfigurationInterpolator ci) {
15 | if (src == null) {
16 | return null;
17 | } else if (UUID.class.equals(targetCls)) {
18 | String uuidAsString = super.convertValue(src, String.class, ci);
19 | return (T) UUID.fromString(uuidAsString);
20 | } else {
21 | return super.convertValue(src, targetCls, ci);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/check.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/FailedDownloadsInfoLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class FailedDownloadsInfoLabel extends JLabel {
9 | public FailedDownloadsInfoLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Anzahl der fehlerhaften Downloads");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 | }
13 |
14 | private void process(@NotNull DownloadStartInfo info) {
15 | if (info.hasValues()) {
16 | setText(info.error + " fehlerhaft");
17 | } else
18 | setText("0 fehlerhaft");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/duplicates/BigSenderPenaltyComparator.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.duplicates;
2 |
3 | import mediathek.daten.DatenFilm;
4 |
5 | import java.util.Comparator;
6 |
7 | public class BigSenderPenaltyComparator implements Comparator {
8 | @Override
9 | public int compare(DatenFilm s1, DatenFilm s2) {
10 | // "ARD" und "ZDF" immer am Ende um die kleineren Mediatheken nicht zu benachteiligen
11 | final var s1_sender = s1.getSender();
12 | final var s2_sender = s2.getSender();
13 | if (s1_sender.equals("ARD") || s1_sender.equals("ZDF")) {
14 | return 1;
15 | }
16 | if (s2_sender.equals("ARD") || s2_sender.equals("ZDF")) {
17 | return -1;
18 | }
19 | // Alphabetisch sortieren für alle anderen
20 | return s1.compareTo(s2);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/filmlisten/reader/DateFilter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.filmlisten.reader
2 |
3 | import mediathek.daten.DatenFilm
4 | import mediathek.daten.ListeFilme
5 | import mediathek.tool.datum.DateUtil
6 | import java.time.LocalDate
7 |
8 | internal class DateFilter(private val listeFilme: ListeFilme, days: Long) : IDateFilter {
9 | private val cutoffDate: LocalDate = LocalDate.now().minusDays(days)
10 |
11 | private fun isBeforeOrEqual(date: LocalDate, compareToDate: LocalDate): Boolean {
12 | return !compareToDate.isAfter(date)
13 | }
14 |
15 | override fun filter(film: DatenFilm) {
16 | // do not filter livestreams
17 | val localDate = DateUtil.convertToLocalDate(film.datumFilm)
18 | if (film.isLivestream || isBeforeOrEqual(localDate, cutoffDate)) {
19 | listeFilme.add(film)
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/ManualDownloadsInfoLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class ManualDownloadsInfoLabel extends JLabel {
9 | public ManualDownloadsInfoLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Anzahl der manuellen Downloads in der Downloadliste");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 | }
13 |
14 | private void process(@NotNull DownloadStartInfo info) {
15 | String numDownloads = (info.num_downloads == 1) ? "1 Download" : info.num_downloads + " Downloads";
16 | setText(numDownloads);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/MVC.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import mediathek.config.MVConfig;
4 |
5 | import java.awt.*;
6 |
7 | public class MVC {
8 |
9 | private final String text;
10 | private final MVConfig.Configs config;
11 | public Color color = new Color(0);
12 | private Color colorReset = new Color(0);
13 | public MVC(MVConfig.Configs configs, Color color, String ttext) {
14 | this.config = configs;
15 | text = ttext;
16 | this.color = color;
17 | colorReset = color;
18 | }
19 |
20 | public MVConfig.Configs getConfig() {
21 | return config;
22 | }
23 |
24 | public String getText() {
25 | return text;
26 | }
27 |
28 | public void set(Color c) {
29 | color = c;
30 | }
31 |
32 | public void reset() {
33 | color = colorReset;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/arrow-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build and test
2 | on: [ push,pull_request ]
3 |
4 | jobs:
5 | build:
6 |
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - uses: actions/checkout@v4
11 | - name: Set up JDK 25
12 | uses: actions/setup-java@v4
13 | with:
14 | distribution: 'liberica'
15 | java-version: '25'
16 | java-package: jdk
17 | cache: 'maven'
18 | - name: Build and test with Maven
19 | run: mvn -B package
20 | - name: SonarCloud Scan
21 | run: mvn -B org.jacoco:jacoco-maven-plugin:prepare-agent sonar:sonar -Dsonar.projectKey=mediathekview_MediathekView -Dsonar.organization=mediathekview -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN
22 | env:
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
25 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/arrow-up.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/mainwindow/ListSelectedItemsProperty.java:
--------------------------------------------------------------------------------
1 | package mediathek.mainwindow;
2 |
3 | import java.beans.PropertyChangeListener;
4 | import java.beans.PropertyChangeSupport;
5 |
6 | public class ListSelectedItemsProperty {
7 | private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
8 | private long selectedItems;
9 |
10 | public ListSelectedItemsProperty(long selectedItems) {
11 | this.selectedItems = selectedItems;
12 | }
13 |
14 | public void addSelectedItemsChangeListener(PropertyChangeListener listener) {
15 | this.pcs.addPropertyChangeListener(listener);
16 | }
17 |
18 | public void setSelectedItems(long selectedItems) {
19 | long oldValue = this.selectedItems;
20 | this.selectedItems = selectedItems;
21 | this.pcs.firePropertyChange("sel_items", oldValue, selectedItems);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/history/ResetAboHistoryAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.history
2 |
3 | import mediathek.config.Daten
4 | import java.awt.event.ActionEvent
5 | import javax.swing.AbstractAction
6 | import javax.swing.JFrame
7 | import javax.swing.JOptionPane
8 |
9 | class ResetAboHistoryAction(private val owner: JFrame) : AbstractAction() {
10 | override fun actionPerformed(e: ActionEvent) {
11 | val ret = JOptionPane.showConfirmDialog(owner, """
12 | Sind Sie sicher dass Sie alle Einträge der Abo-Historie löschen wollen?
13 | Dies kann nicht rückgängig gemacht werden.
14 | """.trimIndent(), "Abo-Historie löschen", JOptionPane.YES_NO_OPTION)
15 | if (ret == JOptionPane.OK_OPTION) {
16 | Daten.getInstance().aboHistoryController.removeAll()
17 | }
18 | }
19 |
20 | init {
21 | putValue(NAME, "Abo-Historie zurücksetzen...")
22 | }
23 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/SearchFieldData.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_film
2 |
3 | import mediathek.tool.Filter
4 | import java.util.regex.Pattern
5 |
6 | @JvmRecord
7 | data class SearchFieldData(val searchFieldText: String, val searchMode: SearchControlFieldMode) {
8 | fun searchThroughDescriptions(): Boolean {
9 | return searchMode == SearchControlFieldMode.IRGENDWO
10 | }
11 |
12 | fun isEmpty(): Boolean {
13 | return searchFieldText.isEmpty()
14 | }
15 |
16 | fun evaluateThemaTitel(): Array {
17 | return if (Filter.isPattern(searchFieldText)) {
18 | arrayOf(searchFieldText)
19 | } else {
20 | Pattern.compile(",")
21 | .splitAsStream(searchFieldText).map { s: String -> s.lowercase() }
22 | .toArray { size -> arrayOfNulls(size) }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/CleanupDownloadListAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class CleanupDownloadListAction extends AbstractAction {
11 | private final GuiDownloads guiDownloads;
12 |
13 | public CleanupDownloadListAction(GuiDownloads guiDownloads) {
14 | this.guiDownloads = guiDownloads;
15 | putValue(Action.NAME, "Liste säubern");
16 | putValue(Action.SHORT_DESCRIPTION, "Liste säubern");
17 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(FontAwesomeSolid.ERASER));
18 | }
19 |
20 | @Override
21 | public void actionPerformed(ActionEvent e) {
22 | guiDownloads.cleanupDownloads();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/table/MVPsetTable.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.table;
2 |
3 | import mediathek.daten.DatenPset;
4 | import mediathek.tool.models.NonEditableTableModel;
5 |
6 | import java.util.Optional;
7 |
8 | public class MVPsetTable extends MVTable {
9 | public MVPsetTable() {
10 | super(DatenPset.MAX_ELEM, new boolean[DatenPset.MAX_ELEM],
11 | Optional.empty(),
12 | Optional.empty(),
13 | Optional.empty());
14 |
15 | setModel(new NonEditableTableModel(new Object[][]{}, DatenPset.COLUMN_NAMES));
16 | setRowSorter(null);
17 | setAutoCreateRowSorter(false); // Reihenfolge ist die Anzeige der Button!
18 | }
19 |
20 | @Override
21 | protected void spaltenAusschalten() {
22 | //do nothing
23 | }
24 |
25 | @Override
26 | public void calculateRowHeight() {
27 | // do nothing
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_standardPset.txt:
--------------------------------------------------------------------------------
1 |
2 | Hiermit können die Standardprogramme zum "Ansehen" und "Aufzeichnen"
3 | der Filme eingetragen werden. Werden die Pfade nicht automatisch erkannt,
4 | kann man sie auch per Hand auswählen.
5 |
6 | Der Zielpfad gibt an, wo Filme gespeichert werden sollen.
7 |
8 |
9 | Um alle Filme ansehen und aufzeichnen zu können, müssen mindestens
10 | diese Programme installiert sein:
11 |
12 | VLC
13 | Dieses Programm dient zum Ansehen und teilweise auch zum Aufzeichnen der Filme.
14 |
15 | ffmpeg
16 | Zum Aufzeichnen von Playlisten (URL endet mit "m3u8")
17 |
18 |
19 | Linux:
20 | Die Programme können über die Paketverwaltung eingespielt werden.
21 |
22 |
23 | Windows, OS X:
24 | Das Programm "ffmpeg" ist bereits in MediathekView integriert.
25 | Es muss bloss noch "VLC" aus dem Internet geladen werden:
26 |
27 |
28 | http://www.videolan.org
29 | http://ffmpeg.org
30 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/ActiveDownloadsInfoLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class ActiveDownloadsInfoLabel extends JLabel {
9 | public ActiveDownloadsInfoLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Anzahl der aktiven Downloads");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 | }
13 |
14 | private void process(@NotNull DownloadStartInfo info) {
15 | if (info.hasValues()) {
16 | var numDownloads = (info.running == 1) ? "1 läuft" : info.running + " laufen";
17 | setText(numDownloads);
18 | } else
19 | setText("0 laufen");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/FinishedDownloadsInfoLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class FinishedDownloadsInfoLabel extends JLabel {
9 | public FinishedDownloadsInfoLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Anzahl der abgeschlossenen Downloads");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 | }
13 |
14 | private void process(@NotNull DownloadStartInfo info) {
15 | if (info.hasValues()) {
16 | String fin = (info.finished == 1) ? "1 fertig" : info.finished + " fertig";
17 | setText(fin);
18 | } else
19 | setText("0 fertig");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/WaitingDownloadsInfoLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class WaitingDownloadsInfoLabel extends JLabel {
9 | public WaitingDownloadsInfoLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Anzahl der wartenden Downloads");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 | }
13 |
14 | private void process(@NotNull DownloadStartInfo info) {
15 | if (info.hasValues()) {
16 | String waiting = (info.initialized == 1) ? "1 wartet" : info.initialized + " warten";
17 | setText(waiting);
18 | } else
19 | setText("");
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_reset_set.txt:
--------------------------------------------------------------------------------
1 | ENTWEDER
2 | =========================================
3 | "Neue Sets hinzufügen"
4 |
5 | Die aktuellen Einstellungen werden damit nicht
6 | verändert. Die neuen Sets werden an die Liste der
7 | bestehenden Sets angehängt und sind danach noch
8 | nicht aktiv. Das muss dann noch geschehen:
9 |
10 | "Datei->Einstellungen->Set bearbeiten"
11 |
12 | Zum Aktivieren: Haken bei Speichern und Abspielen
13 | bei den neuen Sets setzen und bei den alten entfernen
14 | und die neuen Sets ganz nach oben Verschieben.
15 |
16 |
17 | ODER
18 | =========================================
19 | "Bestehende Sets durch die neuen ersetzen"
20 |
21 | Damit werden alle Sets (auch eigene), die zum Abspielen
22 | und Aufzeichnen der Filme gebraucht werden, gelöscht.
23 | Anschließend werden die aktuellen Standardsets
24 | eingerichtet. Es kann dann direkt damit
25 | weitergearbeitet werden.
26 |
27 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/DeferDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeRegular;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class DeferDownloadsAction extends AbstractAction {
11 | private final GuiDownloads guiDownloads;
12 |
13 | public DeferDownloadsAction(GuiDownloads guiDownloads) {
14 | this.guiDownloads = guiDownloads;
15 | putValue(Action.NAME, "Downloads zurückstellen");
16 | putValue(Action.SHORT_DESCRIPTION, "Downloads zurückstellen");
17 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(FontAwesomeRegular.CLOCK));
18 | }
19 |
20 | @Override
21 | public void actionPerformed(ActionEvent e) {
22 | guiDownloads.downloadLoeschen(false);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/ManageBookmarkAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.mainwindow.MediathekGui;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.materialdesign2.MaterialDesignF;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class ManageBookmarkAction extends AbstractAction {
11 | private final MediathekGui mediathekGui;
12 |
13 | public ManageBookmarkAction(MediathekGui mediathekGui) {
14 | this.mediathekGui = mediathekGui;
15 | putValue(Action.NAME, "Merkliste verwalten...");
16 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(MaterialDesignF.FILE_DOCUMENT));
17 | putValue(Action.SHORT_DESCRIPTION, "Merkliste verwalten");
18 | }
19 |
20 | @Override
21 | public void actionPerformed(ActionEvent e) {
22 | mediathekGui.tabFilme.showManageBookmarkWindow();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/ResetSettingsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.config.Daten;
4 | import mediathek.gui.dialog.reset.ResetSettingsDialog;
5 | import mediathek.tool.GuiFunktionen;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class ResetSettingsAction extends AbstractAction {
11 | private final JFrame owner;
12 | private final Daten daten;
13 |
14 | public ResetSettingsAction(JFrame parent, Daten daten) {
15 | super();
16 | owner = parent;
17 | this.daten = daten;
18 |
19 | putValue(NAME, "Einstellungen zurücksetzen...");
20 | }
21 |
22 | @Override
23 | public void actionPerformed(ActionEvent e) {
24 | ResetSettingsDialog dialog = new ResetSettingsDialog(owner, daten);
25 | GuiFunktionen.centerOnScreen(dialog, false);
26 | dialog.setVisible(true);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/StartAllDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class StartAllDownloadsAction extends AbstractAction {
11 | private final GuiDownloads guiDownloads;
12 |
13 | public StartAllDownloadsAction(GuiDownloads guiDownloads) {
14 | this.guiDownloads = guiDownloads;
15 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(FontAwesomeSolid.ANGLE_DOUBLE_DOWN));
16 | putValue(Action.SHORT_DESCRIPTION, "Alle Downloads starten");
17 | putValue(Action.NAME, "Alle Downloads starten");
18 | }
19 |
20 | @Override
21 | public void actionPerformed(ActionEvent e) {
22 | guiDownloads.starten(true);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/mainwindow/PositionSavingTabbedPane.java:
--------------------------------------------------------------------------------
1 | package mediathek.mainwindow;
2 |
3 | import mediathek.tool.ApplicationConfiguration;
4 |
5 | import javax.swing.*;
6 |
7 | public class PositionSavingTabbedPane extends JTabbedPane {
8 |
9 | public PositionSavingTabbedPane() {
10 | }
11 |
12 | public void installChangeListener() {
13 | addChangeListener(l -> saveTabPosition());
14 | }
15 |
16 | public void restoreSavedTabPosition() {
17 | var idx = ApplicationConfiguration.getConfiguration().getInt(Config.TAB_POSITION, -1);
18 | setSelectedIndex(Math.max(idx, 0));
19 | }
20 |
21 | private void saveTabPosition() {
22 | ApplicationConfiguration.getConfiguration().setProperty(Config.TAB_POSITION, getSelectedIndex());
23 | }
24 |
25 | private static class Config {
26 | public static final String TAB_POSITION = "app.ui.tab_position";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/DeleteDownloadsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeRegular;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class DeleteDownloadsAction extends AbstractAction {
11 | private final GuiDownloads guiDownloads;
12 |
13 | public DeleteDownloadsAction(GuiDownloads guiDownloads) {
14 | this.guiDownloads = guiDownloads;
15 | putValue(Action.NAME, "Downloads aus Liste entfernen");
16 | putValue(Action.SHORT_DESCRIPTION, "Downloads entfernen");
17 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(FontAwesomeRegular.TRASH_ALT));
18 | }
19 |
20 | @Override
21 | public void actionPerformed(ActionEvent e) {
22 | guiDownloads.downloadLoeschen(true);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/gui/actions/ManageAboAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions
2 |
3 | import mediathek.gui.abo.ManageAboDialog
4 | import mediathek.mainwindow.MediathekGui
5 | import mediathek.swing.IconUtils
6 | import org.kordamp.ikonli.materialdesign2.MaterialDesignD
7 | import java.awt.event.ActionEvent
8 | import javax.swing.AbstractAction
9 |
10 | class ManageAboAction : AbstractAction() {
11 | private var dialog: ManageAboDialog? = null
12 |
13 | fun closeDialog() {
14 | dialog?.dispose()
15 | }
16 |
17 | override fun actionPerformed(e: ActionEvent?) {
18 | dialog = ManageAboDialog(MediathekGui.ui())
19 | dialog!!.isVisible = true
20 | dialog = null
21 | }
22 |
23 | init {
24 | putValue(NAME, "Abos verwalten...")
25 | putValue(SMALL_ICON, IconUtils.windowBarSpecificToolbarIcon(MaterialDesignD.DATABASE))
26 | putValue(SHORT_DESCRIPTION, "Abos verwalten")
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/PlayDownloadAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 |
10 | public class PlayDownloadAction extends AbstractAction {
11 | private static final String ACTION_TEXT = "Gespeicherten Film abspielen";
12 | private final GuiDownloads guiDownloads;
13 |
14 | public PlayDownloadAction(GuiDownloads guiDownloads) {
15 | this.guiDownloads = guiDownloads;
16 | putValue(Action.NAME, ACTION_TEXT);
17 | putValue(Action.SHORT_DESCRIPTION, ACTION_TEXT);
18 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(FontAwesomeSolid.PLAY));
19 | }
20 |
21 | @Override
22 | public void actionPerformed(ActionEvent e) {
23 | guiDownloads.filmAbspielen();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/triangle-exclamation.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/xmark.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/folder-open.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialogEinstellungen/PanelNotifications.jfd:
--------------------------------------------------------------------------------
1 | JFDML JFormDesigner: "7.0.3.0.337" Java: "11.0.9.1" encoding: "UTF-8"
2 |
3 | new FormModel {
4 | contentType: "form/swing"
5 | root: new FormRoot {
6 | add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
7 | "$layoutConstraints": "hidemode 3"
8 | "$columnConstraints": "[fill][fill]"
9 | "$rowConstraints": "[]"
10 | } ) {
11 | name: "this"
12 | add( new FormComponent( "javax.swing.JCheckBox" ) {
13 | name: "cbShowNotifications"
14 | "text": "Benachrichtigungen anzeigen"
15 | "toolTipText": "Zeige Programminformationen als Benachrichtigungen in einem Popup-Fenster an."
16 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
17 | "value": "cell 0 0"
18 | } )
19 | }, new FormLayoutConstraints( null ) {
20 | "location": new java.awt.Point( 0, 0 )
21 | "size": new java.awt.Dimension( 400, 300 )
22 | } )
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_downloads/TotalDownloadsLabel.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_downloads;
2 |
3 | import mediathek.daten.DownloadStartInfo;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 |
8 | public class TotalDownloadsLabel extends JLabel {
9 | public TotalDownloadsLabel(@NotNull DownloadStartInfoProperty startInfoProperty) {
10 | setToolTipText("Gesamtzahl aller Downloads");
11 | startInfoProperty.addStartInfoChangeListener(evt -> SwingUtilities.invokeLater(() -> process((DownloadStartInfo) evt.getNewValue())));
12 | }
13 |
14 | private void process(@NotNull DownloadStartInfo info) {
15 | final int anz = info.total_num_download_list_entries;
16 | final int diff = anz - info.total_starts;
17 | String download = "Gesamtdownloads: " + anz;
18 | if (diff >= 1) {
19 | download += " (" + diff + " zurückgestellt)";
20 | }
21 | setText(download);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/episodes/SeasonEpisode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.episodes;
20 |
21 | public record SeasonEpisode(int season, int episode) {}
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/messages/ReloadTableDataEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.messages;
20 |
21 | public class ReloadTableDataEvent extends BaseEvent {
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/affinity/IAffinity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.affinity
20 |
21 | interface IAffinity {
22 | fun setDesiredCpuAffinity(numCpus: Int)
23 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/searchfilters/FinalStagePatternFilterWithDescription.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_film.searchfilters;
2 |
3 | import mediathek.daten.DatenFilm;
4 | import mediathek.tool.Filter;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | import java.util.function.Predicate;
8 |
9 | public record FinalStagePatternFilterWithDescription(@NotNull String[] searchStr) implements Predicate {
10 | @Override
11 | public boolean test(@NotNull DatenFilm film) {
12 | var result = searchDefault(film);
13 |
14 | // search description if available
15 | var description = film.getDescription();
16 | if (!description.isEmpty())
17 | result = Filter.pruefen(searchStr, description) || result;
18 |
19 | return result;
20 | }
21 |
22 | private boolean searchDefault(@NotNull DatenFilm film) {
23 | return Filter.pruefen(searchStr, film.getThema())
24 | || Filter.pruefen(searchStr, film.getTitle());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/res/GetIcon.java:
--------------------------------------------------------------------------------
1 | package mediathek.res;
2 |
3 | import javax.swing.*;
4 | import java.awt.*;
5 |
6 | public class GetIcon {
7 |
8 | private final static String PFAD_PROGRAMM = "/mediathek/res/programm/";
9 |
10 | public static ImageIcon getProgramIcon(String strIcon, int w, int h) {
11 | return getIcon(strIcon, PFAD_PROGRAMM, w, h);
12 | }
13 |
14 | public static ImageIcon getIcon(String strIcon, String path, int w, int h) {
15 | ImageIcon icon = getStandard(strIcon, path);
16 |
17 | if (w > 0 && h > 0) {
18 | if (icon.getIconWidth() != w || icon.getIconHeight() != h) {
19 | // nur dann macht es Sinn
20 | icon.setImage(icon.getImage().getScaledInstance(w, h, Image.SCALE_AREA_AVERAGING));
21 | }
22 | }
23 | return icon;
24 | }
25 |
26 | private static ImageIcon getStandard(String strIcon, String path) {
27 | return new ImageIcon(GetIcon.class.getResource(path + strIcon));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/GermanStringSorter.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import org.jetbrains.annotations.NotNull;
4 |
5 | import java.text.Collator;
6 | import java.util.Comparator;
7 | import java.util.Locale;
8 |
9 | public class GermanStringSorter implements Comparator {
10 |
11 | private static final Collator collator = Collator.getInstance(Locale.GERMANY);
12 | private static GermanStringSorter instance;
13 |
14 | private GermanStringSorter() {
15 | super();
16 | }
17 |
18 | public static GermanStringSorter getInstance() {
19 | if (instance == null) {
20 | instance = new GermanStringSorter();
21 | // ignore lower/upper case, but accept special characters in localised alphabetical order
22 | collator.setStrength(Collator.SECONDARY);
23 | }
24 | return instance;
25 | }
26 |
27 | @Override
28 | public int compare(@NotNull String o1, @NotNull String o2) {
29 | return collator.compare(o1, o2);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/history/ResetDownloadHistoryAction.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.history
2 |
3 | import mediathek.controller.history.SeenHistoryController
4 | import java.awt.event.ActionEvent
5 | import javax.swing.AbstractAction
6 | import javax.swing.JFrame
7 | import javax.swing.JOptionPane
8 |
9 | class ResetDownloadHistoryAction(private val owner: JFrame) : AbstractAction() {
10 | override fun actionPerformed(e: ActionEvent) {
11 | val ret = JOptionPane.showConfirmDialog(owner, """
12 | Sind Sie sicher dass Sie alle Einträge der Download-Historie löschen wollen?
13 | Dies kann nicht rückgängig gemacht werden.
14 | """.trimIndent(), "Download-Historie löschen", JOptionPane.YES_NO_OPTION)
15 | if (ret == JOptionPane.OK_OPTION) {
16 | val controller = SeenHistoryController()
17 | controller.use {
18 | controller.removeAll()
19 | }
20 | }
21 | }
22 |
23 | init {
24 | putValue(NAME, "Download-Historie zurücksetzen...")
25 | }
26 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/config/ApplicationType.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.config
20 |
21 | @Suppress("unused")
22 | enum class ApplicationType {
23 | NIGHTLY,
24 | PRODUCTION
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/controller/starter/HttpDownloadState.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.controller.starter;
20 |
21 | public enum HttpDownloadState {
22 |
23 | CANCEL, ERROR, DOWNLOAD
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/DatenFilmFlags.java:
--------------------------------------------------------------------------------
1 | package mediathek.daten;
2 |
3 | public enum DatenFilmFlags {
4 | /**
5 | * Is this film an audio version? (aka Hörfassung)
6 | */
7 | AUDIO_VERSION,
8 | /**
9 | * Flag indicating a trailer, teaser or german Vorschau.
10 | */
11 | TRAILER_TEASER,
12 | /**
13 | * Flag that this entry is in sign language (aka Gebärdensprache).
14 | */
15 | SIGN_LANGUAGE,
16 | /**
17 | * Indicates that entry is a livestream, not a regular movie.
18 | */
19 | LIVESTREAM,
20 | /**
21 | * Indicates that the film is "new" and has not been in the local filmlist before.
22 | */
23 | NEW_ENTRY,
24 | /**
25 | * Indicates that a film has "burned in" subtitles.
26 | */
27 | BURNED_IN_SUBTITLES,
28 | /**
29 | * Indicates that film contains a .m3u8 URL.
30 | */
31 | PLAYLIST,
32 | /**
33 | * Indicate that this film's URL is already existing hence this entry is a duplicate.
34 | */
35 | DUPLICATE
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/expiration/ExpiryInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package mediathek.gui.expiration
19 |
20 | import java.time.LocalDate
21 |
22 | @JvmRecord
23 | data class ExpiryInfo(val expiryDate: LocalDate?)
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/SearchControlFieldMode.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_film
20 |
21 | enum class SearchControlFieldMode {
22 | THEMA_TITEL, IRGENDWO, LUCENE
23 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/Ipify.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import java.io.IOException
4 | import java.net.URI
5 | import java.net.http.HttpClient
6 | import java.net.http.HttpRequest
7 | import java.net.http.HttpResponse
8 |
9 |
10 | object Ipify {
11 | /**
12 | * Get the public ip address through ipify's api.
13 | * @return The public ip address.
14 | * @throws IOException If there is an IO error.
15 | */
16 | @JvmStatic
17 | @get:Throws(IOException::class)
18 | val publicIp: String
19 | get() {
20 | val client: HttpClient = HttpClient.newBuilder()
21 | .version(HttpClient.Version.HTTP_2)
22 | .followRedirects(HttpClient.Redirect.ALWAYS)
23 | .build()
24 |
25 | val request = HttpRequest.newBuilder()
26 | .uri(URI.create("https://api64.ipify.org"))
27 | .build()
28 |
29 | val response = client.send(request, HttpResponse.BodyHandlers.ofString())
30 | return response.body()
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/windows/WinFlags.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.windows
20 |
21 | object WinFlags {
22 | const val ES_CONTINUOUS: Int = Int.MIN_VALUE
23 | const val ES_SYSTEM_REQUIRED: Int = 1
24 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/LoadFilmListAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.mainwindow.MediathekGui;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 | import java.awt.event.KeyEvent;
10 |
11 | public class LoadFilmListAction extends AbstractAction {
12 | private final MediathekGui mediathekGui;
13 |
14 | public LoadFilmListAction(MediathekGui mediathekGui) {
15 | this.mediathekGui = mediathekGui;
16 | putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
17 | putValue(Action.SMALL_ICON, IconUtils.windowBarSpecificToolbarIcon(FontAwesomeSolid.CLOUD_DOWNLOAD_ALT));
18 | putValue(Action.NAME, "Neue Filmliste laden...");
19 | putValue(Action.SHORT_DESCRIPTION, "Neue Filmliste laden");
20 | }
21 | @Override
22 | public void actionPerformed(ActionEvent e) {
23 | mediathekGui.performFilmListLoadOperation(false);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/ttml/ITtmlParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.ttml;
20 |
21 | import java.nio.file.Path;
22 |
23 | public interface ITtmlParser {
24 | boolean parse(Path ttmlFilePath);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/MemoryMonitorAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.dialog.MemoryMonitorDialog;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 | import java.awt.event.ActionEvent;
8 |
9 | public class MemoryMonitorAction extends AbstractAction {
10 | private MemoryMonitorDialog dialog;
11 | private final JFrame parent;
12 |
13 | public MemoryMonitorAction(@NotNull JFrame parent) {
14 | this.parent = parent;
15 | putValue(Action.NAME, "Speicherverbrauch anzeigen");
16 | }
17 |
18 | public void closeMemoryMonitor() {
19 | if (dialog != null) {
20 | dialog.dispose();
21 | dialog = null;
22 | }
23 | }
24 |
25 | public void showMemoryMonitor() {
26 | if (dialog == null)
27 | dialog = new MemoryMonitorDialog(parent);
28 | dialog.setVisible(true);
29 | }
30 |
31 | @Override
32 | public void actionPerformed(ActionEvent e) {
33 | showMemoryMonitor();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/SettingsAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.messages.ShowSettingsDialogEvent;
4 | import mediathek.swing.IconUtils;
5 | import mediathek.tool.MessageBus;
6 | import org.apache.commons.lang3.SystemUtils;
7 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
8 |
9 | import javax.swing.*;
10 | import java.awt.event.ActionEvent;
11 | import java.awt.event.KeyEvent;
12 |
13 | public class SettingsAction extends AbstractAction {
14 | public SettingsAction() {
15 | putValue(Action.NAME, "Einstellungen...");
16 | if (!SystemUtils.IS_OS_MAC_OSX)
17 | putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0));
18 | putValue(Action.SMALL_ICON, IconUtils.windowBarSpecificToolbarIcon(FontAwesomeSolid.COGS));
19 | putValue(Action.SHORT_DESCRIPTION, "Einstellungen öffnen");
20 | }
21 | @Override
22 | public void actionPerformed(ActionEvent e) {
23 | MessageBus.getMessageBus().publishAsync(new ShowSettingsDialogEvent());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/kotlin/mediathek/tool/FileUtilsTest.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import org.junit.jupiter.api.Assertions.assertEquals
4 | import org.junit.jupiter.api.Test
5 |
6 | internal class FileUtilsTest {
7 |
8 | @Test
9 | fun removeExtension() {
10 | val testStr = "file.jpeg"
11 | val result = FileUtils.removeExtension(testStr)
12 | assertEquals("file", result)
13 | }
14 |
15 | @Test
16 | fun humanReadableByteCountBinary_megabytes() {
17 | val bytes:Long = 25165824
18 | val result = FileUtils.humanReadableByteCountBinary(bytes)
19 |
20 | val expected = String.format("%.1f MiB", (bytes / FileUtils.ONE_MB.toDouble()));
21 | assertEquals(expected, result)
22 | }
23 |
24 | @Test
25 | fun humanReadableByteCountBinary_kilobytes() {
26 | val bytes:Long = 24*1024
27 | val result = FileUtils.humanReadableByteCountBinary(bytes)
28 |
29 | val expected = String.format("%.1f KiB", (bytes / FileUtils.ONE_KB.toDouble()));
30 | assertEquals(expected, result)
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/services/StreamInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams.services
20 |
21 | data class StreamInfo(
22 | val streamUrl: String = "",
23 | val name: String = ""
24 | )
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/DownloadStartInfo.java:
--------------------------------------------------------------------------------
1 | package mediathek.daten;
2 |
3 | public class DownloadStartInfo {
4 | /**
5 | * Size of the download list.
6 | */
7 | public int total_num_download_list_entries = 0;
8 | public int total_starts = 0;
9 | public int num_abos = 0;
10 | public int num_downloads = 0;
11 | /**
12 | * not yet started but initialized.
13 | */
14 | public int initialized = 0;
15 | public int running = 0;
16 | /**
17 | * finished without error.
18 | */
19 | public int finished = 0;
20 | /**
21 | * finished with error.
22 | */
23 | public int error = 0;
24 |
25 | /**
26 | * determine if it has non standard values.
27 | * @return true if data was changed
28 | */
29 | public boolean hasValues() {
30 | boolean result = false;
31 | if (total_starts > 0 || num_abos > 0 || num_downloads > 0 || initialized > 0 ||
32 | running > 0 || finished > 0 || error > 0)
33 | result = true;
34 |
35 | return result;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/RefreshDownloadListAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.gui.tabs.tab_downloads.GuiDownloads;
4 | import mediathek.swing.IconUtils;
5 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
6 |
7 | import javax.swing.*;
8 | import java.awt.event.ActionEvent;
9 | import java.awt.event.KeyEvent;
10 |
11 | public class RefreshDownloadListAction extends AbstractAction {
12 | private final GuiDownloads guiDownloads;
13 |
14 | public RefreshDownloadListAction(GuiDownloads guiDownloads) {
15 | this.guiDownloads = guiDownloads;
16 | putValue(Action.NAME, "Liste der Downloads aktualisieren");
17 | putValue(Action.SHORT_DESCRIPTION, "Downloadliste aktualisieren");
18 | putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_DOWN_MASK));
19 | putValue(Action.SMALL_ICON, IconUtils.toolbarIcon(FontAwesomeSolid.REDO_ALT));
20 | }
21 |
22 | @Override
23 | public void actionPerformed(ActionEvent e) {
24 | guiDownloads.updateDownloads();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/ttml/ITtmlExporter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.ttml;
20 |
21 | import java.nio.file.Path;
22 |
23 | public interface ITtmlExporter {
24 | void write(TimedTextMarkupLanguageParser parser, Path destinationPath);
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/circle-question.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/EventListWithEmptyFirstEntry.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import ca.odell.glazedlists.EventList;
4 | import ca.odell.glazedlists.TransformedList;
5 | import ca.odell.glazedlists.event.ListEvent;
6 |
7 | /**
8 | * Read-only event list which also containing an " " for a "select all" selection.
9 | */
10 | public class EventListWithEmptyFirstEntry extends TransformedList {
11 |
12 | public EventListWithEmptyFirstEntry(EventList sourceList) {
13 | super(sourceList);
14 | source.addListEventListener(this);
15 | }
16 |
17 | @Override
18 | protected boolean isWritable() {
19 | return false;
20 | }
21 |
22 | @Override
23 | public void listChanged(ListEvent listChanges) {
24 | updates.forwardEvent(listChanges);
25 | }
26 |
27 | @Override
28 | public String get(int index) {
29 | if (index == 0)
30 | return "";
31 | else
32 | return source.get(index - 1);
33 | }
34 |
35 | public int size() {
36 | return source.size() + 1;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/UIProgressState.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | public enum UIProgressState {
4 | INIT_FX("UI Toolkit initialisieren..."),
5 | FILE_CLEANUP("Dateien bereinigen..."),
6 | START_UI("Anwendungsklassen laden..."),
7 | LOAD_MAINWINDOW("Hauptfenster initialisieren..."),
8 | WAIT_FOR_HISTORY_DATA("Warte auf Abschluss des Ladens der History..."),
9 | CREATE_STATUS_BAR("Statusbar initialisieren..."),
10 | SETUP_FILM_LISTENERS("Listener initialisieren..."),
11 | LOAD_TABS("Tabs laden..."),
12 | LOAD_FILM_TAB("Filme-Tab laden"),
13 | LOAD_DOWNLOAD_TAB("Download-Tab laden"),
14 | ADD_TABS_TO_UI("Tabs zum UI hinzufügen"),
15 | CONFIGURE_TABS("Tabs konfigurieren"),
16 | INIT_MENUS("Menüs initialisieren..."),
17 | LOAD_MEMORY_MONITOR("Speichermonitor initialisieren..."),
18 | FINISHED("Anwendungsfenster wird geöffnet...");
19 |
20 | private final String title;
21 |
22 | UIProgressState(String title) {
23 | this.title = title;
24 | }
25 |
26 | @Override
27 | public String toString() {
28 | return title;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/ShowFilmInformationAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.mainwindow.MediathekGui;
4 | import mediathek.swing.IconUtils;
5 | import mediathek.tool.GuiFunktionen;
6 | import org.kordamp.ikonli.fontawesome6.FontAwesomeSolid;
7 |
8 | import javax.swing.*;
9 | import java.awt.event.ActionEvent;
10 | import java.awt.event.KeyEvent;
11 |
12 | public class ShowFilmInformationAction extends AbstractAction {
13 |
14 | public ShowFilmInformationAction() {
15 | putValue(Action.NAME, "Filminformation anzeigen");
16 | putValue(Action.SHORT_DESCRIPTION, "Filminformation anzeigen");
17 | putValue(Action.SMALL_ICON, IconUtils.windowBarSpecificToolbarIcon(FontAwesomeSolid.INFO_CIRCLE));
18 | putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_I, GuiFunktionen.getPlatformControlKey()));
19 | }
20 |
21 | @Override
22 | public void actionPerformed(ActionEvent e) {
23 | if (!MediathekGui.ui().getFilmInfoDialog().isVisible()) {
24 | MediathekGui.ui().getFilmInfoDialog().showInfo();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/kotlin/mediathek/tool/VersionTest.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import org.junit.jupiter.api.Assertions.assertFalse
4 | import org.junit.jupiter.api.Assertions.assertTrue
5 | import org.junit.jupiter.api.Test
6 |
7 | internal class VersionTest {
8 |
9 | @Test
10 | fun isOlderThan() {
11 | val v1 = Version(13,6,0)
12 | val v2 = Version(13,7,0)
13 |
14 | assertTrue { v1.isOlderThan(v2) }
15 | assertFalse { v2.isOlderThan(v1) }
16 | }
17 |
18 | @Test
19 | fun isInvalid() {
20 | val invVersion = Version.INVALID_VERSION
21 | assertTrue {invVersion.isInvalid() }
22 |
23 | val manInv = Version(0,0,0)
24 | assertTrue { manInv.isInvalid() }
25 |
26 | val t3 = Version(13,6,0)
27 | assertFalse { t3.isInvalid() }
28 | }
29 |
30 | @Test
31 | fun fromString() {
32 | val str = "13.7.0"
33 | val v = Version.fromString(str)
34 | assertTrue { v == Version(13,7,0) }
35 |
36 | val t2 = "13.6.0-SNAPSHOT"
37 | val v2 = Version.fromString(t2)
38 | assertTrue { v2 == Version(13,6,0) }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/FilmResolution.java:
--------------------------------------------------------------------------------
1 | package mediathek.daten;
2 |
3 | //FIXME convert indices to int!!
4 | public class FilmResolution {
5 | public enum Enum {
6 | LOW,
7 | NORMAL,
8 | HIGH_QUALITY;
9 |
10 | @Override
11 | public String toString() {
12 | return switch (super.toString()) {
13 | case "LOW" -> FilmResolution.LOW;
14 | case "NORMAL" -> FilmResolution.NORMAL;
15 | case "HIGH_QUALITY" -> FilmResolution.HIGH_QUALITY;
16 | default -> throw new IndexOutOfBoundsException("Illegal enum to string!");
17 | };
18 | }
19 |
20 | public static Enum fromLegacyString(String in) {
21 | return switch (in) {
22 | case FilmResolution.LOW -> LOW;
23 | case FilmResolution.HIGH_QUALITY -> HIGH_QUALITY;
24 | default -> NORMAL;
25 | };
26 | }
27 | }
28 |
29 | public static final String NORMAL = "normal";
30 | public static final String HIGH_QUALITY = "hd";
31 | public static final String LOW = "klein";
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/notification/GenericNotificationCenter.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool.notification
2 |
3 | import raven.toast.Notifications
4 | import javax.swing.SwingUtilities
5 |
6 | /**
7 | * Implements notification based on controlsfx JavaFX implemention.
8 | */
9 | class GenericNotificationCenter : INotificationCenter {
10 | override fun displayNotification(msg: NotificationMessage) {
11 | SwingUtilities.invokeLater {
12 | try {
13 | val ravenNotificationType: Notifications.Type = when (msg.type) {
14 | MessageType.INFO -> Notifications.Type.INFO
15 | MessageType.ERROR -> Notifications.Type.ERROR
16 | }
17 |
18 | val message = msg.title + "\n\n" + msg.message
19 | Notifications.getInstance()
20 | .show(ravenNotificationType, Notifications.Location.TOP_RIGHT, message)
21 | } catch (_: NullPointerException) {
22 | //the generic version might fail to display a notification with NPE
23 | }
24 | }
25 | }
26 |
27 | override fun close() {}
28 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/swing/NoIconMenuItem.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.swing;
20 |
21 | import javax.swing.*;
22 |
23 | public class NoIconMenuItem extends JMenuItem {
24 | public NoIconMenuItem(Action action) {
25 | super(action);
26 | setIcon(null);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/IndexedFilmList.java:
--------------------------------------------------------------------------------
1 | package mediathek.daten;
2 |
3 | import mediathek.config.StandardLocations;
4 | import org.apache.logging.log4j.LogManager;
5 | import org.apache.logging.log4j.Logger;
6 | import org.apache.lucene.index.DirectoryReader;
7 | import org.apache.lucene.store.Directory;
8 | import org.apache.lucene.store.MMapDirectory;
9 |
10 | public class IndexedFilmList extends ListeFilme {
11 | private static final Logger logger = LogManager.getLogger();
12 | private Directory luceneDirectory;
13 | private DirectoryReader reader;
14 |
15 | public IndexedFilmList() {
16 | try {
17 | luceneDirectory = new MMapDirectory(StandardLocations.getFilmIndexPath());
18 |
19 | } catch (Exception ex) {
20 | logger.error("Creation of Lucene index directory failed!", ex);
21 | }
22 | }
23 |
24 | public DirectoryReader getReader() {
25 | return reader;
26 | }
27 |
28 | public void setReader(DirectoryReader reader) {
29 | this.reader = reader;
30 | }
31 |
32 | public Directory getLuceneDirectory() {
33 | return luceneDirectory;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialogEinstellungen/PanelPset.jfd:
--------------------------------------------------------------------------------
1 | JFDML JFormDesigner: "8.2.4.0.393" Java: "21.0.3" encoding: "UTF-8"
2 |
3 | new FormModel {
4 | contentType: "form/swing"
5 | root: new FormRoot {
6 | add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
7 | "$layoutConstraints": "insets 5,hidemode 3,gap 5 5"
8 | "$columnConstraints": "[grow,fill]"
9 | "$rowConstraints": "[fill][grow,fill]"
10 | } ) {
11 | name: "this"
12 | add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
13 | name: "jPanelPset"
14 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
15 | "value": "cell 0 1"
16 | } )
17 | add( new FormComponent( "javax.swing.JCheckBox" ) {
18 | name: "jCheckBoxAlleEinstellungen"
19 | "text": "alle Einstellungen anzeigen"
20 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
21 | "value": "cell 0 0"
22 | } )
23 | }, new FormLayoutConstraints( null ) {
24 | "size": new java.awt.Dimension( 400, 300 )
25 | "location": new java.awt.Point( 0, 0 )
26 | } )
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/services/StreamService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams.services
20 |
21 | import retrofit2.http.GET
22 |
23 | interface StreamService {
24 | @GET("/v1/channelinfolist") // Anpassen!
25 | suspend fun getStreams(): Map
26 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/services/ShowService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams.services
20 |
21 | import retrofit2.http.GET
22 | import retrofit2.http.Path
23 |
24 |
25 | interface ShowService {
26 | @GET("/v1/shows/{key}")
27 | suspend fun getShow(@Path("key") key: String): ShowsResponse
28 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/actions/DeleteLocalFilmlistAction.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions;
2 |
3 | import mediathek.config.Konstanten;
4 | import mediathek.config.StandardLocations;
5 | import mediathek.mainwindow.MediathekGui;
6 | import mediathek.tool.FileUtils;
7 |
8 | import javax.swing.*;
9 | import java.awt.event.ActionEvent;
10 | import java.nio.file.Paths;
11 |
12 | public class DeleteLocalFilmlistAction extends AbstractAction {
13 | private final JFrame owner;
14 |
15 | public DeleteLocalFilmlistAction(MediathekGui parent) {
16 | super();
17 | owner = parent;
18 |
19 | putValue(NAME, "Lokale Filmliste löschen");
20 | }
21 |
22 | @Override
23 | public void actionPerformed(ActionEvent e) {
24 | var filmlistPathStr = StandardLocations.getFilmlistFilePathString();
25 | var fimlistPath = Paths.get(filmlistPathStr);
26 | FileUtils.moveToTrash(fimlistPath);
27 | JOptionPane.showMessageDialog(owner,
28 | "Filmliste wurde gelöscht.\nDas Programm wird nun beendet.",
29 | Konstanten.PROGRAMMNAME, JOptionPane.INFORMATION_MESSAGE);
30 | MediathekGui.ui().quitApplication();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/LivestreamEntry.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams
20 |
21 | import mediathek.gui.tabs.tab_livestreams.services.ShowInfo
22 |
23 | data class LivestreamEntry(
24 | val key: String,
25 | val streamName: String,
26 | val streamUrl: String,
27 | var show: ShowInfo? = null
28 | )
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_film/searchfilters/FinalStageFilterNoPatternWithDescription.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.tabs.tab_film.searchfilters;
2 |
3 | import mediathek.daten.DatenFilm;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import java.util.function.Predicate;
7 |
8 | public class FinalStageFilterNoPatternWithDescription implements Predicate {
9 | private final String searchText;
10 |
11 | public FinalStageFilterNoPatternWithDescription(@NotNull String[] searchStr) {
12 | this.searchText = searchStr[0];
13 | }
14 |
15 | @Override
16 | public boolean test(DatenFilm datenFilm) {
17 | var result = searchDefault(datenFilm);
18 |
19 | // search description if available
20 | var description = datenFilm.getDescription();
21 | if (!description.isEmpty()) {
22 | result = description.toLowerCase().contains(searchText) || result;
23 | }
24 |
25 | return result;
26 | }
27 |
28 | private boolean searchDefault(@NotNull DatenFilm film) {
29 | return film.getThema().toLowerCase().contains(searchText)
30 | || film.getTitle().toLowerCase().contains(searchText);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/services/ShowsResponse.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams.services
20 |
21 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties
22 |
23 | @JsonIgnoreProperties(ignoreUnknown = true)
24 | data class ShowsResponse(
25 | val shows: List = emptyList(),
26 | val error: String? = null
27 | )
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/MessageBus.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import mediathek.gui.messages.BaseEvent
4 | import net.engio.mbassy.bus.MBassador
5 | import net.engio.mbassy.bus.config.BusConfiguration
6 | import net.engio.mbassy.bus.config.Feature
7 | import net.engio.mbassy.bus.config.IBusConfiguration
8 | import net.engio.mbassy.bus.error.PublicationError
9 | import org.apache.logging.log4j.LogManager
10 |
11 | /**
12 | * The central message bus to dispatch notifications throughout the program
13 | */
14 | object MessageBus {
15 | @JvmStatic
16 | val messageBus: MBassador
17 | private val logger = LogManager.getLogger()
18 |
19 | init {
20 | logger.trace("Initializing message bus")
21 | messageBus = MBassador(BusConfiguration()
22 | .addFeature(Feature.SyncPubSub.Default())
23 | .addFeature(Feature.AsynchronousHandlerInvocation.Default())
24 | .addFeature(Feature.AsynchronousMessageDispatch.Default())
25 | .addPublicationErrorHandler { error: PublicationError ->
26 | logger.error(error.message, error.cause)
27 | }
28 | .setProperty(IBusConfiguration.Properties.BusId, "global bus"))
29 | }
30 | }
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/gui/actions/export/DiskSpaceUtil.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.actions.export
2 |
3 | import org.apache.logging.log4j.LogManager
4 | import java.io.File
5 | import java.nio.file.Files
6 |
7 | internal object DiskSpaceUtil {
8 | private val logger = LogManager.getLogger()
9 |
10 | /**
11 | * Check if there is more than 1 GB of free disk space available.
12 | */
13 | fun enoughDiskSpace(selectedFile: File): Boolean {
14 | try {
15 | var tempFileCreated = false
16 |
17 | if (!selectedFile.exists()) {
18 | selectedFile.createNewFile()
19 | tempFileCreated = true
20 | }
21 | val store = Files.getFileStore(selectedFile.toPath())
22 | val availFreeSpace = store.usableSpace / (1024 * 1024) //Megabyte
23 |
24 | if (tempFileCreated)
25 | selectedFile.delete()
26 |
27 | return availFreeSpace >= 1024
28 | }
29 | catch (e: Exception) {
30 | // in case of error pretend there is space available as it may fail on network drives
31 | logger.error("enoughDiskSpace failed!", e)
32 | return true
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/resources/mediathek/file/hilfetext_blacklist.txt:
--------------------------------------------------------------------------------
1 | Bei der Funktion "Blacklist" werden Filme, die den
2 | Angaben in einer Zeile in der Tabelle entsprechen,
3 | nicht angezeigt.
4 |
5 | Die Funktion "Whitelist" zeigt nur die Filme an, die
6 | den Angaben in einer Zeile in der Tabelle entsprechen.
7 |
8 | Beim Umschalten "Blacklist - Whitelist" werden genau
9 | die vorher nicht angezeigten Filme jetzt angezeigt.
10 |
11 | "Sender" "Thema" werden exakt verglichen.
12 | Der Titelfilter muss im Titel enthalten sein.
13 | Das Filterfeld "Thema/Titel" muss entweder im Filmthema
14 | oder im Filmtitel enthalten sein.
15 |
16 | Groß- und Kleinschreibung wird beim Filtern nicht beachtet.
17 |
18 | Im Feld "Titel" (dann wird im Titel gesucht) und "Thema/Titel"
19 | (dann wird in den Feldern Thema und Titel gesucht)
20 | kann auch mit regulären Ausdrücken gesucht
21 | werden. Diese müssen mit "#:" eingeleitet werden.
22 | Auch bei den regulären Ausdrücken wird nicht zwischen
23 | Groß- und Kleinschreibung unterschieden.
24 |
25 | #:Abend.*
26 | Das bedeutet z.B.: Es werden alle Filme gefiltert, die
27 | im jeweiligen Feld mit "Abend" (oder auch: "abend") beginnen.
28 |
29 | https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck
30 |
31 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/mainwindow/FixedRedrawStatusBar.java:
--------------------------------------------------------------------------------
1 | package mediathek.mainwindow;
2 |
3 | import org.jdesktop.swingx.JXStatusBar;
4 | import org.jetbrains.annotations.NotNull;
5 |
6 | import javax.swing.*;
7 | import java.awt.*;
8 |
9 | /**
10 | * This class tries to fix some redraw issues with JXStatusBar on removal.
11 | */
12 | public class FixedRedrawStatusBar extends JXStatusBar {
13 | public FixedRedrawStatusBar(@NotNull MediathekGui mediathekGui) {
14 | add(new SelectedListItemsLabel(mediathekGui));
15 | add(new FilmSizeInfoLabel(mediathekGui));
16 | add(new DownloadInformationLabel());
17 |
18 | add(new JPanel(), new Constraint(Constraint.ResizeBehavior.FILL));
19 | add(new FilmListCreationDateLabel());
20 | add(new FilmAgeLabel());
21 | }
22 |
23 | @Override
24 | public void remove(int index) {
25 | super.remove(index);
26 | this.revalidate();
27 | }
28 |
29 | @Override
30 | public void remove(Component comp) {
31 | super.remove(comp);
32 | this.revalidate();
33 | }
34 |
35 | @Override
36 | public void removeAll() {
37 | super.removeAll();
38 | this.revalidate();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialogEinstellungen/allgemein/TimedDocumentListener.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.dialogEinstellungen.allgemein;
2 |
3 | import javax.swing.*;
4 | import javax.swing.event.DocumentEvent;
5 | import javax.swing.event.DocumentListener;
6 | import java.awt.event.ActionListener;
7 |
8 | /**
9 | * Listens to changes in a Document and finally fires the assigned Action.
10 | * All operations will be performed on Swing EDT.
11 | */
12 | public final class TimedDocumentListener implements DocumentListener {
13 | private final Timer timer;
14 |
15 | public TimedDocumentListener(ActionListener taskPerformer) {
16 | timer = new Timer(1_000, taskPerformer);
17 | timer.setRepeats(false);
18 | }
19 |
20 | private void fireTimer() {
21 | if (timer.isRunning())
22 | timer.restart();
23 | else
24 | timer.start();
25 | }
26 |
27 | @Override
28 | public void insertUpdate(DocumentEvent e) {
29 | fireTimer();
30 | }
31 |
32 | @Override
33 | public void removeUpdate(DocumentEvent e) {
34 | fireTimer();
35 | }
36 |
37 | @Override
38 | public void changedUpdate(DocumentEvent e) {
39 | fireTimer();
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/affinity/Affinity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.affinity
20 |
21 | import org.apache.commons.lang3.SystemUtils
22 |
23 | /**
24 | * Utility class to set OS-specific CPU affinity.
25 | */
26 | object Affinity {
27 | @JvmStatic
28 | var affinityImpl: IAffinity = if (SystemUtils.IS_OS_WINDOWS)
29 | WindowsAffinity()
30 | else
31 | NullAffinity()
32 |
33 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/datum/DatumFilm.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.datum;
2 |
3 | import java.time.ZonedDateTime;
4 | import java.util.Date;
5 |
6 | public class DatumFilm extends Date {
7 | /**
8 | * When no date is specified in the film list, set to undefined for proper sorting.
9 | * Fictious date is 1.1.1900
10 | */
11 | public static final DatumFilm UNDEFINED_FILM_DATE = new DatumFilm(0, 0, 1);
12 | private ZonedDateTime zonedDateTime;
13 |
14 | public DatumFilm(long date) {
15 | super(date);
16 | convertToZonedDateTime();
17 | }
18 |
19 | public DatumFilm(int year, int month, int date) {
20 | super(year, month, date);
21 | convertToZonedDateTime();
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | if (this.equals(UNDEFINED_FILM_DATE)) {
27 | return "";
28 | }
29 | else {
30 | return DateUtil.FORMATTER.format(DateUtil.convertToLocalDate(this));
31 | }
32 | }
33 |
34 | public ZonedDateTime getZonedDateTime() {
35 | return zonedDateTime;
36 | }
37 |
38 | private void convertToZonedDateTime() {
39 | zonedDateTime = this.toInstant().atZone(DateUtil.MV_DEFAULT_TIMEZONE);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/cellrenderer/CellRendererColor.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool.cellrenderer;
2 |
3 | import mediathek.config.Daten;
4 | import mediathek.tool.MVC;
5 | import org.apache.logging.log4j.LogManager;
6 | import org.apache.logging.log4j.Logger;
7 |
8 | import javax.swing.*;
9 | import javax.swing.table.DefaultTableCellRenderer;
10 | import java.awt.*;
11 |
12 | public class CellRendererColor extends DefaultTableCellRenderer {
13 | private static final Logger logger = LogManager.getLogger();
14 |
15 | @Override
16 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
17 | boolean hasFocus, int row, int column) {
18 | super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
19 | final int r = table.convertRowIndexToModel(row);
20 |
21 | try {
22 | MVC color = Daten.mVColor.liste.get(r);
23 | setHorizontalAlignment(SwingConstants.CENTER);
24 | setBackground(color.color);
25 | setText("");
26 | } catch (IndexOutOfBoundsException ex) {
27 | logger.error("unable to get color", ex);
28 | }
29 | return this;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/kotlin/mediathek/tool/TrailerTeaserCheckerTest.kt:
--------------------------------------------------------------------------------
1 | package mediathek.tool
2 |
3 | import org.junit.jupiter.api.Assertions.assertFalse
4 | import org.junit.jupiter.api.Assertions.assertTrue
5 | import org.junit.jupiter.api.Test
6 |
7 | internal class TrailerTeaserCheckerTest {
8 |
9 | @Test
10 | fun successTest1() {
11 | val checker = TrailerTeaserChecker()
12 |
13 | val testStr = "TrAiLeR"
14 | assertTrue {checker.check(testStr)}
15 | }
16 |
17 | @Test
18 | fun successTest2() {
19 | val checker = TrailerTeaserChecker()
20 |
21 | val testStr = "TeAsEr"
22 | assertTrue {checker.check(testStr)}
23 | }
24 |
25 | @Test
26 | fun successTest3() {
27 | val checker = TrailerTeaserChecker()
28 |
29 | val testStr = "VoRsChAu"
30 | assertTrue {checker.check(testStr)}
31 |
32 | }
33 |
34 | @Test
35 | fun failTest1() {
36 | val checker = TrailerTeaserChecker()
37 |
38 | val testStr = "bla"
39 | assertFalse {checker.check(testStr)}
40 | }
41 |
42 | @Test
43 | fun failTest2() {
44 | val checker = TrailerTeaserChecker()
45 |
46 | val testStr = "BlA"
47 | assertFalse {checker.check(testStr)}
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/daten/abo/AboTags.kt:
--------------------------------------------------------------------------------
1 | package mediathek.daten.abo
2 |
3 | import java.util.*
4 |
5 | enum class AboTags(val index: Int, val xmlName: String) {
6 | NR(DatenAbo.ABO_NR, "Nr"),
7 | EINGESCHALTET(DatenAbo.ABO_EINGESCHALTET, "aktiv"),
8 | NAME(DatenAbo.ABO_NAME, "Name"),
9 | SENDER(DatenAbo.ABO_SENDER, "Sender"),
10 | THEMA(DatenAbo.ABO_THEMA, "Thema"),
11 | TITEL(DatenAbo.ABO_TITEL, "Titel"),
12 | THEMA_TITEL(DatenAbo.ABO_THEMA_TITEL, "Thema-Titel"),
13 | IRGENDWO(DatenAbo.ABO_IRGENDWO, "Irgendwo"),
14 | MINDESTDAUER(DatenAbo.ABO_MINDESTDAUER, "Mindestdauer"),
15 | MIN(DatenAbo.ABO_MIN, "min_max"),
16 | ZIELPFAD(DatenAbo.ABO_ZIELPFAD, "Zielpfad"),
17 | DOWN_DATUM(DatenAbo.ABO_DOWN_DATUM, "letztes_Abo"),
18 | PSET(DatenAbo.ABO_PSET, "Programmset");
19 |
20 | companion object {
21 | @JvmStatic
22 | fun fromXmlTag(tag: String): Optional {
23 | return Arrays.stream(entries.toTypedArray()).filter { e: AboTags -> e.xmlName == tag }.findAny()
24 | }
25 |
26 | @JvmStatic
27 | fun fromIndex(index: Int): Optional {
28 | return Arrays.stream(entries.toTypedArray()).filter { e: AboTags -> e.index == index }.findAny()
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/swing/JIkonliSafeButton.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.swing
20 |
21 | import javax.swing.Icon
22 | import javax.swing.JButton
23 |
24 | /**
25 | * Generates disabled icons automatically
26 | */
27 | class JIkonliSafeButton : JButton() {
28 | override fun setIcon(defaultIcon: Icon?) {
29 | super.setIcon(defaultIcon)
30 | disabledIcon = IconUtils.generateDisabledIcon(this.icon)
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/affinity/NullAffinity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.affinity
20 |
21 | import org.apache.logging.log4j.LogManager
22 |
23 | class NullAffinity : IAffinity {
24 | override fun setDesiredCpuAffinity(numCpus: Int) {
25 | logger.warn("This OS is not supported for setting cpu affinity")
26 | }
27 |
28 | companion object {
29 | private val logger = LogManager.getLogger()
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/SenderUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams
20 |
21 | class SenderUtils {
22 | companion object {
23 | /**
24 | * Remove soft hyphens and control characters from string.
25 | */
26 | @JvmStatic
27 | fun sanitizeName(name: String): String {
28 | return name.replace(Regex("[\\u00AD\\p{Cf}]"), "")
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/tool/FilmSize.java:
--------------------------------------------------------------------------------
1 | package mediathek.tool;
2 |
3 | import org.apache.logging.log4j.LogManager;
4 | import org.apache.logging.log4j.Logger;
5 | import org.jetbrains.annotations.NotNull;
6 |
7 | /**
8 | * Store film size in Megabytes.
9 | */
10 | public class FilmSize implements Comparable {
11 | private int size;
12 | private static final Logger logger = LogManager.getLogger();
13 |
14 | public FilmSize() {
15 | this.size = 0;
16 | }
17 |
18 | public void setSize(String strSize) {
19 | if (strSize.equalsIgnoreCase("<1")) {
20 | size = 1;
21 | }
22 |
23 | try {
24 | if (!strSize.isEmpty()) {
25 | size = Integer.parseInt(strSize);
26 | }
27 | } catch (NumberFormatException ex) {
28 | logger.error("String: {}", strSize,ex);
29 | size = 0;
30 | }
31 | }
32 |
33 | public Integer toInteger() {
34 | return (size == 0) ? 0 : size;
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return (size == 0) ? "" : Integer.toString(size);
40 | }
41 |
42 | @Override
43 | public int compareTo(@NotNull FilmSize other) {
44 | return (Integer.compare(size, other.size));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/duplicates/CommonStatsEvaluationTask.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.duplicates;
2 |
3 | import ca.odell.glazedlists.TransactionList;
4 | import mediathek.config.Daten;
5 | import mediathek.daten.DatenFilm;
6 |
7 | import java.util.Map;
8 | import java.util.stream.Collectors;
9 |
10 | public class CommonStatsEvaluationTask implements Runnable {
11 | @Override
12 | public void run() {
13 | final var films = Daten.getInstance().getListeFilme().parallelStream()
14 | .filter(f -> !f.isLivestream())
15 | .toList();
16 |
17 | var statisticsList = Daten.getInstance().getCommonStatistics();
18 |
19 | Map statisticsMap = films.parallelStream()
20 | .collect(Collectors.groupingBy(DatenFilm::getSender, Collectors.counting()));
21 | TransactionList tList = new TransactionList<>(statisticsList);
22 | statisticsList.getReadWriteLock().writeLock().lock();
23 | tList.beginEvent(true);
24 | tList.clear();
25 | for (var sender : statisticsMap.keySet()) {
26 | tList.add(new FilmStatistics(sender, statisticsMap.get(sender)));
27 | }
28 | tList.commitEvent();
29 | statisticsList.getReadWriteLock().writeLock().unlock();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/bandwidth/WriteConfigComponentListener.kt:
--------------------------------------------------------------------------------
1 | package mediathek.gui.bandwidth
2 |
3 | import org.apache.commons.configuration2.Configuration
4 | import org.apache.commons.configuration2.sync.LockMode
5 | import java.awt.event.ComponentAdapter
6 | import java.awt.event.ComponentEvent
7 | import javax.swing.JDialog
8 |
9 | internal class WriteConfigComponentListener(private val config: Configuration, private val dialog: JDialog) :
10 | ComponentAdapter() {
11 | override fun componentResized(e: ComponentEvent) {
12 | try {
13 | config.lock(LockMode.WRITE)
14 | val size = dialog.size
15 | config.setProperty(BandwidthDialog.CONFIG_WIDTH, size.width)
16 | config.setProperty(BandwidthDialog.CONFIG_HEIGHT, size.height)
17 | }
18 | finally {
19 | config.unlock(LockMode.WRITE)
20 | }
21 | }
22 |
23 | override fun componentMoved(e: ComponentEvent) {
24 | try {
25 | config.lock(LockMode.WRITE)
26 | val location = dialog.location
27 | config.setProperty(BandwidthDialog.CONFIG_X, location.x)
28 | config.setProperty(BandwidthDialog.CONFIG_Y, location.y)
29 | }
30 | finally {
31 | config.unlock(LockMode.WRITE)
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/resources/icons/sender/ard.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
--------------------------------------------------------------------------------
/src/test/java/mediathek/controller/history/MVUsedUrlTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.controller.history;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | import static org.junit.jupiter.api.Assertions.assertEquals;
24 |
25 | class MVUsedUrlTest {
26 |
27 | @Test
28 | void putzen() {
29 | var testStr = "g|a |###| b";
30 | var expected = "ga ### b";
31 | var result = MVUsedUrl.putzen(testStr);
32 | assertEquals(expected, result);
33 | }
34 | }
--------------------------------------------------------------------------------
/src/test/java/mediathek/tool/table/MVTableTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.tool.table;
20 |
21 | import org.junit.jupiter.api.Test;
22 |
23 | import static org.junit.jupiter.api.Assertions.assertEquals;
24 |
25 | class MVTableTest {
26 |
27 | @Test
28 | void countNumberOfColumns() {
29 | var count = MVTable.countNumberOfColumns("a,b,c,d");
30 | assertEquals(4, count);
31 |
32 | count = MVTable.countNumberOfColumns("a,b,c,d,e");
33 | assertEquals(5, count);
34 | }
35 | }
--------------------------------------------------------------------------------
/src/main/kotlin/mediathek/windows/MediathekGuiWindows.kt:
--------------------------------------------------------------------------------
1 | package mediathek.windows
2 |
3 | import mediathek.mainwindow.MediathekGui
4 | import mediathek.tool.notification.INotificationCenter
5 | import mediathek.tool.notification.WinNotificationCenter
6 | import mediathek.tool.threads.IndicatorThread
7 | import org.apache.logging.log4j.LogManager
8 | import java.io.IOException
9 |
10 | class MediathekGuiWindows : MediathekGui() {
11 | private val logger = LogManager.getLogger()
12 |
13 | override fun createDarkModeToggleButton() {
14 | //not used on Windows 10+, we are creating a menu bar action here
15 | }
16 |
17 | override fun createMenuBar() {
18 | super.createMenuBar()
19 | createDarkModeMenuAction()
20 | }
21 | override fun shutdownComputer() {
22 | val strShutdownCommand = arrayOf("shutdown.exe", "-s", "-t", "0")
23 | try {
24 | logger.info("Windows shutdown binary called.")
25 | Runtime.getRuntime().exec(strShutdownCommand)
26 | } catch (ex: IOException) {
27 | logger.error(ex)
28 | }
29 | }
30 |
31 | override fun createProgressIndicatorThread(): IndicatorThread {
32 | return TaskbarIndicatorThread(this)
33 | }
34 |
35 | override fun getNotificationCenter(): INotificationCenter {
36 | return WinNotificationCenter()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/envelope-open-text.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------
/src/test/kotlin/feed/RSSFeedParserTest.kt:
--------------------------------------------------------------------------------
1 | package feed
2 |
3 | import org.junit.jupiter.api.Assertions
4 | import org.junit.jupiter.api.Test
5 | import java.io.File
6 |
7 | internal class RSSFeedParserTest {
8 | @Test
9 | fun mvwTest() {
10 | try {
11 | File("src/test/resources/rss/mediathekviewweb.xml").inputStream().use {
12 | val parser = RSSFeedParser()
13 | val feed = parser.readFeed(it)
14 | Assertions.assertNotNull(feed)
15 | //println(feed);
16 | Assertions.assertNotNull(feed!!.messages)
17 | Assertions.assertFalse(feed.messages.isEmpty())
18 | for (message in feed.messages) {
19 | //println(message);
20 | Assertions.assertNotNull(message)
21 | Assertions.assertTrue(message.author.isBlank())
22 | Assertions.assertFalse(message.guid.isBlank())
23 | Assertions.assertFalse(message.link.isBlank())
24 | Assertions.assertFalse(message.description.isBlank())
25 | Assertions.assertFalse(message.title.isBlank())
26 | Assertions.assertTrue(message.guid.endsWith('='))
27 | }
28 | }
29 | } catch (e: Exception) {
30 | Assertions.fail(e)
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/tabs/tab_livestreams/services/ShowInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.tabs.tab_livestreams.services
20 |
21 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties
22 | import java.time.Instant
23 |
24 | @JsonIgnoreProperties(ignoreUnknown = true)
25 | data class ShowInfo(
26 | val title: String = "",
27 | val subtitle: String? = "",
28 | val description: String = "",
29 | val channel: String = "",
30 | val startTime: Instant = Instant.EPOCH,
31 | val endTime: Instant = Instant.EPOCH
32 | )
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/bookmark/BookmarkAddedAtComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025 derreisende77.
3 | * This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package mediathek.gui.bookmark;
20 |
21 | import java.util.Comparator;
22 |
23 | public class BookmarkAddedAtComparator implements Comparator {
24 |
25 | @Override
26 | public int compare(BookmarkData o1, BookmarkData o2) {
27 | var o1ba = o1.getBookmarkAdded();
28 | var o2ba = o2.getBookmarkAdded();
29 | if (o1ba == null || o2ba == null) {
30 | return 0;
31 | }
32 | return o1ba.compareTo(o2ba);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/dialog/StandardCloseDialog.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.dialog;
2 |
3 | import mediathek.gui.actions.DisposeDialogAction;
4 | import mediathek.tool.EscapeKeyHandler;
5 |
6 | import javax.swing.*;
7 | import java.awt.*;
8 |
9 | /**
10 | * A standard swing dialog template with a close button.
11 | */
12 | public abstract class StandardCloseDialog extends JDialog {
13 | public StandardCloseDialog(Frame owner, String title, boolean modal) {
14 | super(owner, title, modal);
15 | setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
16 | EscapeKeyHandler.installHandler(this, this::dispose);
17 |
18 | var contentPane = getContentPane();
19 | contentPane.setLayout(new BorderLayout());
20 | contentPane.add(createContentPanel(), BorderLayout.CENTER);
21 | var buttonPanel = new ButtonPanel();
22 | buttonPanel.add(createButtonPanel(),BorderLayout.EAST);
23 | contentPane.add(buttonPanel, BorderLayout.SOUTH);
24 | pack();
25 | }
26 |
27 | public abstract JComponent createContentPanel();
28 |
29 | public final ButtonFlowPanel createButtonPanel() {
30 | ButtonFlowPanel pnl = new ButtonFlowPanel();
31 | JButton btn = new JButton(new DisposeDialogAction(this, "Schließen", "Dialog schließen"));
32 | getRootPane().setDefaultButton(btn);
33 | pnl.add(btn);
34 | return pnl;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/mediathek/gui/history/MVUsedUrlTableFormat.java:
--------------------------------------------------------------------------------
1 | package mediathek.gui.history;
2 |
3 | import ca.odell.glazedlists.gui.TableFormat;
4 | import mediathek.controller.history.MVUsedUrl;
5 |
6 | public class MVUsedUrlTableFormat implements TableFormat {
7 | private static final int USED_URL_DATUM = 0;
8 | private static final int USED_URL_THEMA = 1;
9 | private static final int USED_URL_TITEL = 2;
10 | private static final int USED_URL_URL = 3;
11 |
12 | @Override
13 | public int getColumnCount() {
14 | return 4;
15 | }
16 |
17 | @Override
18 | public String getColumnName(int column) {
19 | return switch (column) {
20 | case USED_URL_DATUM -> "Datum";
21 | case USED_URL_THEMA -> "Thema";
22 | case USED_URL_TITEL -> "Titel";
23 | case USED_URL_URL -> "URL";
24 | default -> throw new IllegalStateException();
25 | };
26 | }
27 |
28 | @Override
29 | public Object getColumnValue(MVUsedUrl baseObject, int column) {
30 | return switch (column) {
31 | case USED_URL_DATUM -> baseObject.getDatum();
32 | case USED_URL_THEMA -> baseObject.getThema();
33 | case USED_URL_TITEL -> baseObject.getTitel();
34 | case USED_URL_URL -> baseObject.getUrl();
35 | default -> throw new IllegalStateException();
36 | };
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/raven/toast/util/UIUtils.java:
--------------------------------------------------------------------------------
1 | package raven.toast.util;
2 |
3 | import com.formdev.flatlaf.extras.FlatSVGIcon;
4 |
5 | import javax.swing.*;
6 | import java.awt.*;
7 |
8 | /**
9 | * @author Raven
10 | */
11 | public class UIUtils {
12 |
13 | public static Icon getIcon(String key, Icon defaultValue) {
14 | Icon icon = UIManager.getIcon(key);
15 | if (icon == null) {
16 | return defaultValue;
17 | }
18 | return icon;
19 | }
20 |
21 | public static Insets getInsets(String key, Insets defaultValue) {
22 | Insets insets = UIManager.getInsets(key);
23 | if (insets == null) {
24 | return defaultValue;
25 | }
26 | return insets;
27 | }
28 |
29 | public static String getString(String key, String defaultValue) {
30 | String string = UIManager.getString(key);
31 | if (string == null) {
32 | return defaultValue;
33 | }
34 | return string;
35 | }
36 |
37 | public static Icon createIcon(String path, Color color, float scale) {
38 | FlatSVGIcon icon = new FlatSVGIcon(path, scale);
39 | if (color != null) {
40 | FlatSVGIcon.ColorFilter colorFilter = new FlatSVGIcon.ColorFilter();
41 | colorFilter.add(new Color(150, 150, 150), color);
42 | icon.setColorFilter(colorFilter);
43 | }
44 | return icon;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/resources/icons/fontawesome/pen-to-square.svg:
--------------------------------------------------------------------------------
1 |
2 |
16 |
--------------------------------------------------------------------------------