├── .gitattributes ├── .gitignore ├── .idea └── .idea.Tailviewer │ └── .idea │ ├── .gitignore │ ├── encodings.xml │ ├── indexLayout.xml │ ├── riderModule.iml │ └── vcs.xml ├── .tfignore ├── CONTRIBUTING.md ├── Keys └── .gitignore ├── LICENSE ├── README.md ├── RestoreDeveloperKey.cmd ├── RestoreOfficialKey.cmd ├── Screenshot1.png ├── Screenshot2.png ├── Tailviewer-Complete.sln ├── Tailviewer-Complete.sln.DotSettings ├── Tailviewer.sln ├── Tailviewer.sln.DotSettings ├── docs ├── Architecture.md ├── BuildEvents.png ├── CreateProject.png ├── DebugSettings.png ├── DevelopingFileFormatPlugins.md ├── DevelopingPlugins.md ├── IdentifyingFileFormats.md ├── NugetPackage.png ├── PULL_REQUEST_TEMPLATE.md └── issue_template.md ├── examples └── Tailviewer.LogLevelPlugin │ ├── MyCustomLogEntryParserPlugin.cs │ ├── MyCustomLogLevelParser.cs │ ├── MyLogFileFormatMatcherPlugin.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── README.md │ ├── Tailviewer.LogLevelPlugin.csproj │ ├── TestData │ └── Example.mylog │ └── app.config ├── pack.cmd ├── playground ├── ControlPlayground │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── ControlPlayground.csproj │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── Themes │ │ └── Generic.xaml │ ├── TimelineControl.cs │ ├── TimelineControl.xaml │ └── packages.config ├── FileLogger │ ├── App.config │ ├── Application.cs │ ├── FileLogger.csproj │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Live │ ├── FileLogger.txt │ └── SQLiteLogger.db ├── LogFile2Playground │ ├── FilteredLogFile2.cs │ ├── ILogFile2.cs │ ├── ILogLineAccessor.cs │ ├── ILogLineCache.cs │ ├── LogFile2Playground.csproj │ ├── LogLineCache.cs │ ├── LogLineResponse.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── TextCanvas.cs │ ├── TextLogFile2.cs │ └── packages.config ├── Logger │ ├── App.config │ ├── Logger.csproj │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── LoggerCore │ ├── Generator.cs │ ├── LoggerApplication.cs │ ├── LoggerCore.csproj │ ├── LoggingEventTemplate.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── app.config │ └── packages.config ├── NewDesign │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── Colors.xaml │ ├── Dashboard │ │ ├── DashboardControl.cs │ │ ├── DashboardControl.xaml │ │ ├── DashboardViewModel.cs │ │ ├── ISidePanelViewModel.cs │ │ ├── Layout │ │ │ ├── HorizontalLayoutDataTemplate.xaml │ │ │ ├── HorizontalWidgetLayoutViewModel.cs │ │ │ ├── IWidgetLayoutViewModel.cs │ │ │ ├── VerticalLayoutDataTemplate.xaml │ │ │ ├── WidgetLayoutViewModel.cs │ │ │ └── WidgetStyle.xaml │ │ └── Widgets │ │ │ ├── AbstractWidgetViewModel.cs │ │ │ ├── Events │ │ │ ├── EventViewModel.cs │ │ │ ├── EventsDataTemplate.xaml │ │ │ └── EventsViewModel.cs │ │ │ ├── IWidgetViewModel.cs │ │ │ ├── LineCount │ │ │ ├── LineCountDataTemplate.xaml │ │ │ └── LineCountViewModel.cs │ │ │ ├── QuickInfos │ │ │ ├── INamedValueViewModel.cs │ │ │ ├── NamedValueViewModel.cs │ │ │ ├── QuickInfoViewModel.cs │ │ │ ├── QuickInfosDataTemplate.xaml │ │ │ └── QuickInfosViewModel.cs │ │ │ ├── Widget.cs │ │ │ ├── WidgetSidePanelDataTemplate.xaml │ │ │ └── WidgetSidePanelViewModel.cs │ ├── HorizontalWidgetLayoutViewModel.cs │ ├── IconConverter.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── MainWindowViewModel.cs │ ├── MenuItem.cs │ ├── NewDesign.csproj │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── SidePanel │ │ ├── SidePanelControl.cs │ │ └── SidePanelControl.xaml │ └── packages.config ├── SQLiteLogger │ ├── App.config │ ├── Application.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SQLiteAppender.cs │ ├── SQLiteLogger.csproj │ └── packages.config └── TablePlayground │ ├── App.config │ ├── App.xaml │ ├── App.xaml.cs │ ├── DefaultLogColumns.cs │ ├── GridSplitterPanel.cs │ ├── ILogColumn.cs │ ├── LogColumn.cs │ ├── LogEntry2.cs │ ├── LogFileContent.cs │ ├── LogResponse.cs │ ├── LogTableView.xaml │ ├── LogTableView.xaml.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ ├── TableCanvas.cs │ ├── TableHeaderItem.cs │ ├── TablePlayground.csproj │ └── packages.config ├── scripts ├── print_environment.cmd └── rename_installer.cmd ├── sig ├── .gitignore ├── DeveloperKey.snk ├── key.snk └── sns ├── src ├── GlobalAssemblyInfo.cs ├── Installer │ ├── App.config │ ├── Applications │ │ ├── AbstractViewModel.cs │ │ ├── App.cs │ │ ├── Install │ │ │ ├── InstallApplication.cs │ │ │ ├── Launcher.cs │ │ │ ├── LicenseWindow.xaml │ │ │ ├── LicenseWindow.xaml.cs │ │ │ ├── MainWindow.xaml │ │ │ ├── MainWindow.xaml.cs │ │ │ └── MainWindowViewModel.cs │ │ ├── SilentInstall │ │ │ └── SilentInstallApplication.cs │ │ ├── Uninstall │ │ │ └── UninstallApplication.cs │ │ └── Update │ │ │ ├── UpdateApplication.cs │ │ │ ├── UpdateWindowViewModel.cs │ │ │ ├── UpdaterWindow.xaml │ │ │ └── UpdaterWindow.xaml.cs │ ├── Arguments.cs │ ├── Bootstrapper.cs │ ├── Constants.cs │ ├── Exceptions │ │ ├── CopyFileException.cs │ │ ├── DeleteFileException.cs │ │ └── FileIOException.cs │ ├── InstallationFiles │ │ ├── Plugins │ │ │ └── Readme.txt │ │ ├── Tailviewer.AcceptanceTests.dll │ │ └── Uninstall.cmd │ ├── Installer.cs │ ├── Installer.csproj │ ├── Mode.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── app.manifest │ └── packages.config ├── Plugins │ ├── Tailviewer.Formats.Serilog.Tests │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── SerilogAcceptanceTest.cs │ │ ├── SerilogFileParserTest.cs │ │ ├── Tailviewer.Formats.Serilog.Tests.csproj │ │ ├── app.config │ │ └── packages.config │ ├── Tailviewer.Formats.Serilog │ │ ├── ISerilogMatcher.cs │ │ ├── Matchers │ │ │ ├── LevelMatcher.cs │ │ │ ├── MessageMatcher.cs │ │ │ └── TimestampMatcher.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── SerilogEntry.cs │ │ ├── SerilogEntryParser.cs │ │ ├── SerilogEntryParserPlugin.cs │ │ ├── SerilogFileFormat.cs │ │ ├── SerilogFileFormatCreatorPlugin.cs │ │ ├── SerilogFileFormatMatcher.cs │ │ ├── SerilogFileFormatMatcherPlugin.cs │ │ ├── Tailviewer.Formats.Serilog.csproj │ │ ├── app.config │ │ └── packages.config │ └── Tailviewer.PluginCreator │ │ ├── App.config │ │ ├── FileFormatPlugin2Creator.cs │ │ ├── FileFormatPluginCreator.cs │ │ ├── LogFileCreator.cs │ │ ├── MsBuild.cs │ │ ├── Nuget.cs │ │ ├── Packer.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ └── Tailviewer.PluginCreator.csproj ├── Tailviewer.Acceptance.Tests │ ├── ApplicationTest.cs │ ├── AssemblySetup.cs │ ├── BusinessLogic │ │ ├── AutoUpdater │ │ │ └── AutoUpdaterTest.cs │ │ ├── DataSources │ │ │ ├── FileDataSourceAcceptanceTest.cs │ │ │ ├── FileDataSourceManualTest.cs │ │ │ ├── FileDataSourceRealTest.cs │ │ │ └── FileDataSourceTest.cs │ │ ├── Searches │ │ │ └── LogFileSearchProxyTest.cs │ │ └── Sources │ │ │ ├── FilteredAndMergedLogSourceTest.cs │ │ │ ├── FilteredLogSourceTest.cs │ │ │ ├── LogSourceProxyTest.cs │ │ │ ├── MergedLogFileTest.CustomTimestampParser.cs │ │ │ ├── MergedLogSourceTest.cs │ │ │ ├── MultiLineLogSourceTest.cs │ │ │ └── Text │ │ │ ├── AbstractTextLogSourceAcceptanceTest.cs │ │ │ ├── FileLogSourceAcceptanceTest.cs │ │ │ ├── FileLogSourceAcceptanceTest2.cs │ │ │ ├── FileLogSourceTest.cs │ │ │ ├── Simple │ │ │ ├── StreamReaderExTest.cs │ │ │ ├── TextLogSourceAcceptanceTest.cs │ │ │ ├── TextLogSourceTest.cs │ │ │ └── TextLogSourceTest2.cs │ │ │ └── Streaming │ │ │ ├── StreamingTextLogSourceAcceptanceTest.cs │ │ │ └── StreamingTextLogSourceTest.cs │ ├── InstallerTest.cs │ ├── ProcessEx.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── SingleApplicationHelperTest.cs │ ├── SystemtestBase.cs │ ├── Tailviewer.Acceptance.Tests.csproj │ ├── Ui │ │ └── LogView │ │ │ ├── FileDataSourceViewModelTest.cs │ │ │ ├── FolderDataSourceViewModelTest.cs │ │ │ ├── LogEntryListViewTest.cs │ │ │ └── LogViewerViewModelTest.cs │ ├── app.config │ └── packages.config ├── Tailviewer.Api.Tests │ ├── AbstractIdTest.cs │ ├── AssemblySetup.cs │ ├── AssemblyTest.cs │ ├── DataSourceIdTest.cs │ ├── FlakyTestAttribute.cs │ ├── IssueAttribute.cs │ ├── LevelFlagsTest.cs │ ├── LocalTest.cs │ ├── LogEntryIndexTest.cs │ ├── LogEntrySourceIdTest.cs │ ├── LogLineIndexTest.cs │ ├── LogSourceModificationTest.cs │ ├── LogSourceSectionTest.cs │ ├── PathEx.cs │ ├── PercentageTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── RequiresElevation.cs │ ├── Tailviewer.Api.Tests.csproj │ └── packages.config ├── Tailviewer.Api │ ├── Certainty.cs │ ├── ColumnNotRetrievedException.cs │ ├── DataSourceId.cs │ ├── IColumnDescriptor.cs │ ├── IEmptyReason.cs │ ├── ILogBuffer.cs │ ├── ILogEntry.cs │ ├── ILogEntryFilter.cs │ ├── ILogFileFormat.cs │ ├── ILogFileFormatRepository.cs │ ├── ILogLineFilter.cs │ ├── ILogSource.cs │ ├── ILogSourceListener.cs │ ├── ILogSourceProxy.cs │ ├── IMergedLogFile.cs │ ├── IPropertiesBuffer.cs │ ├── IPropertyDescriptor.cs │ ├── IReadOnlyLogBuffer.cs │ ├── IReadOnlyLogEntry.cs │ ├── IReadOnlyPropertyDescriptor.cs │ ├── IReader.cs │ ├── ISerializableType.cs │ ├── IServiceContainer.cs │ ├── ITimestampParser.cs │ ├── ITypeFactory.cs │ ├── IWriter.cs │ ├── LevelFlags.cs │ ├── LogEntriesExtensions.cs │ ├── LogEntryIndex.cs │ ├── LogEntrySectionExtensions.cs │ ├── LogEntrySourceId.cs │ ├── LogLine.cs │ ├── LogLineIndex.cs │ ├── LogLineMatch.cs │ ├── LogSourceModification.cs │ ├── LogSourceQueryMode.cs │ ├── LogSourceQueryOptions.cs │ ├── LogSourceSection.cs │ ├── NoSuchColumnException.cs │ ├── NoSuchPropertyException.cs │ ├── NoSuchServiceException.cs │ ├── Percentage.cs │ ├── Plugins │ │ ├── CustomDataSourceId.cs │ │ ├── ICustomDataSourceConfiguration.cs │ │ ├── ICustomDataSourcePlugin.cs │ │ ├── ICustomLogFileFormat.cs │ │ ├── ICustomLogFileFormatCreatorPlugin.cs │ │ ├── ILogEntryParser.cs │ │ ├── ILogEntryParserPlugin.cs │ │ ├── ILogFileFormatMatcher.cs │ │ ├── ILogFileFormatMatcherPlugin.cs │ │ ├── ILogFileIssueListener.cs │ │ ├── ILogFileIssuesPlugin.cs │ │ ├── ILogFileOutlinePlugin.cs │ │ ├── ILogSourceIssue.cs │ │ ├── ILogSourceIssueAnalyser.cs │ │ ├── ILogSourceParserPlugin.cs │ │ ├── IPlugin.cs │ │ ├── PluginAuthorAttribute.cs │ │ ├── PluginDescriptionAttribute.cs │ │ ├── PluginIdAttribute.cs │ │ ├── PluginInterfaceVersion.cs │ │ ├── PluginInterfaceVersionAttribute.cs │ │ ├── PluginVersionAttribute.cs │ │ ├── PluginWebsiteAttribute.cs │ │ └── Severity.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── ServiceAttribute.cs │ ├── Tailviewer.Api.csproj │ ├── Tailviewer.Api.nuspec │ ├── ThreadSafeAttribute.cs │ ├── Ui │ │ ├── ICustomDataSourceViewModel.cs │ │ ├── ILogFileOutlineViewModel.cs │ │ ├── INavigationService.cs │ │ ├── IPropertyPresenter.cs │ │ └── IPropertyPresenterPlugin.cs │ ├── WillBeRemoved.cs │ ├── app.config │ └── packages.config ├── Tailviewer.Archiver.Tests │ ├── AbstractPluginTest.cs │ ├── AggregatedPluginLoaderTest.cs │ ├── AssemblySetup.cs │ ├── BinaryFormatterExtensions.cs │ ├── GitGetChangesTest.cs │ ├── PluginArchiveLoaderTest.cs │ ├── PluginArchiveTest.cs │ ├── PluginAssemblyLoaderTest.cs │ ├── PluginBuilder.cs │ ├── PluginCacheTest.cs │ ├── PluginPackerTest.cs │ ├── PluginRegistryTest.cs │ ├── Plugins │ │ ├── Description │ │ │ ├── PluginDescriptionTest.cs │ │ │ └── PluginImplementationDescriptionTest.cs │ │ ├── PluginGroupTest.cs │ │ ├── PluginIdTest.cs │ │ ├── PluginPackageIndexTest.cs │ │ └── SerializableChangesTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Repository │ │ └── RemotePublishDisabledExceptionTest.cs │ ├── Tailviewer.Archiver.Tests.csproj │ ├── TestData │ │ ├── Managed │ │ │ ├── AnyCPU │ │ │ │ └── ClassLibrary1.dll │ │ │ ├── x64 │ │ │ │ └── ClassLibrary1.dll │ │ │ └── x86 │ │ │ │ ├── ClassLibrary1.dll │ │ │ │ ├── Targets.NET.4.6.1.dll │ │ │ │ ├── Targets.NET.4.6.2.dll │ │ │ │ └── Targets.NET.4.6.dll │ │ ├── Native │ │ │ ├── x64 │ │ │ │ └── NativeImage.dll │ │ │ └── x86 │ │ │ │ └── NativeImage.dll │ │ └── cropped-uiforetwicon2.png │ ├── app.config │ └── packages.config ├── Tailviewer.Archiver │ ├── App.config │ ├── Applications │ │ ├── GitGetChanges.cs │ │ ├── GitGetChangesOptions.cs │ │ ├── Pack.cs │ │ ├── PackOptions.cs │ │ ├── Publish.cs │ │ └── PublishOptions.cs │ ├── Bootstrapper.cs │ ├── ColoringConsoleAppender.cs │ ├── ConsoleLogger.cs │ ├── EnumerableExtensions.cs │ ├── ExitCode.cs │ ├── ListOptions.cs │ ├── PackException.cs │ ├── Plugins │ │ ├── AbstractPluginLoader.cs │ │ ├── AggregatedPluginLoader.cs │ │ ├── AssemblyDescription.cs │ │ ├── AssemblyReference.cs │ │ ├── CorruptPluginException.cs │ │ ├── Description │ │ │ ├── Change.cs │ │ │ ├── IChange.cs │ │ │ ├── IPluginDescription.cs │ │ │ ├── IPluginImplementationDescription.cs │ │ │ ├── PluginDescription.cs │ │ │ ├── PluginError.cs │ │ │ └── PluginImplementationDescription.cs │ │ ├── EmptyPluginArchive.cs │ │ ├── IAssemblyDescription.cs │ │ ├── IAssemblyReference.cs │ │ ├── INativeImageDescription.cs │ │ ├── IPluginArchive.cs │ │ ├── IPluginLoader.cs │ │ ├── IPluginPackageIndex.cs │ │ ├── IPluginStatus.cs │ │ ├── IPluginWithDescription.cs │ │ ├── NativeImageDescription.cs │ │ ├── PluginArchive.cs │ │ ├── PluginArchiveLoader.cs │ │ ├── PluginAssemblyLoader.cs │ │ ├── PluginCache.cs │ │ ├── PluginGroup.cs │ │ ├── PluginId.cs │ │ ├── PluginInterfaceImplementation.cs │ │ ├── PluginPackageIndex.cs │ │ ├── PluginPacker.cs │ │ ├── PluginRegistry.cs │ │ ├── PluginStatus.cs │ │ ├── PluginWithDescription.cs │ │ ├── SerializableChange.cs │ │ ├── SerializableChanges.cs │ │ └── SerializableTypeDescription.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Repository │ │ ├── Change.cs │ │ ├── Constants.cs │ │ ├── IPluginRepository.cs │ │ ├── InvalidUserTokenException.cs │ │ ├── PluginAlreadyPublishedException.cs │ │ ├── PluginIdentifier.cs │ │ ├── PluginInterface.cs │ │ ├── PublishedPluginDescription.cs │ │ └── RemotePublishDisabledException.cs │ ├── Tailviewer.Archiver.csproj │ └── packages.config ├── Tailviewer.Core.Tests │ ├── AssemblyTest.cs │ ├── Buffers │ │ ├── AbstractLogBufferTest.cs │ │ ├── AbstractReadOnlyLogBufferTest.cs │ │ ├── CombinedLogBufferViewTest.cs │ │ ├── LogBufferArrayTest.cs │ │ ├── LogBufferListTest.cs │ │ ├── LogBufferViewTest.cs │ │ ├── LogEntryBufferAccessorTest.cs │ │ ├── LogEntryListAccessorTest.cs │ │ └── SingleColumnLogBufferViewTest.cs │ ├── Columns │ │ ├── CustomColumnDescriptorTest.cs │ │ ├── GeneralColumnsTest.cs │ │ └── WellKnownColumnDescriptorTest.cs │ ├── ConcurrentQueueExtensionsTest.cs │ ├── Entries │ │ ├── AbstractLogEntryTest.cs │ │ ├── AbstractReadOnlyLogEntryTest.cs │ │ ├── LogEntryTest.cs │ │ ├── LogEntryTest2.cs │ │ ├── LogEntryViewTest.cs │ │ ├── ReadOnlyLogEntryTest.cs │ │ └── ReadOnlyLogEntryViewTest.cs │ ├── Filters │ │ ├── AndFilterTest.cs │ │ ├── EmptyLogLineFilterTest.cs │ │ ├── ExpressionEngine │ │ │ ├── ContainsTimestampExpressionTest.cs │ │ │ ├── ExpressionParserErrorTest.cs │ │ │ ├── ExpressionParserTest.cs │ │ │ ├── FilterExpressionTest.cs │ │ │ ├── LogLevelLiteralTest.cs │ │ │ └── TokenizerTest.cs │ │ ├── FilterTest.cs │ │ ├── LevelFilterTest.cs │ │ ├── NoFilterTest.cs │ │ ├── OrFilterTest.cs │ │ ├── RangeFilterTest.cs │ │ └── SubstringFilterTest.cs │ ├── FixedSizeListTest.cs │ ├── LogFileListenerCollectionTest.cs │ ├── LogFileListenerNotifierTest.cs │ ├── Parsers │ │ ├── LogLevelParserTest.cs │ │ ├── TimeOfDaySecondsSinceStartParserTest.cs │ │ └── TimestampParserTest.cs │ ├── Properties │ │ ├── AbstractPropertiesBufferTest.cs │ │ ├── AssemblyInfo.cs │ │ ├── ConcurrentPropertiesListTest.cs │ │ ├── GeneralPropertiesTest.cs │ │ └── PropertiesBufferListTest.cs │ ├── SimpleLogFileFormatMatcher.cs │ ├── Sources │ │ ├── AbstractAggregatedLogSourceTest.cs │ │ ├── AbstractLogSourceTest.cs │ │ ├── AbstractTaskSchedulerLogFileTest.cs │ │ ├── Adorner │ │ │ ├── LogSourceColumnAdornerTest.cs │ │ │ └── LogSourcePropertyAdornerTest.cs │ │ ├── Buffer │ │ │ ├── BufferedLogSourceTest.cs │ │ │ ├── BufferedLogSourceTest2.cs │ │ │ ├── PageTest.cs │ │ │ └── PagedLogBufferTest.cs │ │ ├── EmptyLogFileTest.cs │ │ ├── Filtered │ │ │ ├── FilteredLogSourceTest.cs │ │ │ ├── FilteredLogSourceTest2.cs │ │ │ └── FilteredLogSourceTest3.cs │ │ ├── InMemoryLogSourceTest.cs │ │ ├── LogFileFormatsTest.cs │ │ ├── Merged │ │ │ ├── MergedLogFileChangesTest.cs │ │ │ ├── MergedLogFileIndexTest.cs │ │ │ ├── MergedLogFilePendingModificationTest.cs │ │ │ ├── MergedLogSourceTest.cs │ │ │ ├── MergedLogSourceTest2.cs │ │ │ └── MergedLogSourceTest3.cs │ │ ├── MultiLine │ │ │ ├── MultiLineLogSourceTest.cs │ │ │ ├── MultiLineLogSourceTest2.cs │ │ │ └── MultiLineLogSourceTest3.cs │ │ ├── Proxy │ │ │ ├── LogSourceProxyTest.cs │ │ │ └── LogSourceProxyTest2.cs │ │ └── Text │ │ │ ├── EncodingDetectorTest.cs │ │ │ ├── FileFingerprintTest.cs │ │ │ ├── FileFormatDetectorTest.cs │ │ │ ├── Simple │ │ │ └── StreamReaderExTest.cs │ │ │ └── Streaming │ │ │ └── LineOffsetDetectorTest.cs │ ├── Tailviewer.Core.Tests.csproj │ ├── app.config │ └── packages.config ├── Tailviewer.Core │ ├── ArrayExtensions.cs │ ├── AssemblyExtensions.cs │ ├── Buffers │ │ ├── CombinedLogBufferView.cs │ │ ├── LogBufferArray.cs │ │ ├── LogBufferEnumerator.cs │ │ ├── LogBufferExtensions.cs │ │ ├── LogBufferList.cs │ │ ├── LogBufferView.cs │ │ ├── LogEntryCache.cs │ │ ├── ReadOnlyLogBufferEnumerator.cs │ │ └── SingleColumnLogBufferView.cs │ ├── Columns │ │ ├── ColumnDescriptorExtensions.cs │ │ ├── Columns.cs │ │ ├── CustomColumnDescriptor.cs │ │ └── WellKnownColumnDescriptor.cs │ ├── Comparers │ │ └── LevelFlagsComparer.cs │ ├── ConcurrentQueueExtensions.cs │ ├── Constants.cs │ ├── DateTimeExtensions.cs │ ├── DisposableExtensions.cs │ ├── Entries │ │ ├── AbstractLogEntry.cs │ │ ├── AbstractReadOnlyLogEntry.cs │ │ ├── LogEntry.cs │ │ ├── LogEntryView.cs │ │ ├── ReadOnlyLogEntry.cs │ │ ├── ReadOnlyLogEntryExtensions.cs │ │ └── ReadOnlyLogEntryView.cs │ ├── EnumerableExtensions.cs │ ├── Filters │ │ ├── AndFilter.cs │ │ ├── EmptyLogLineFilter.cs │ │ ├── ExpressionEngine │ │ │ ├── AndExpression.cs │ │ │ ├── BinaryExpression.cs │ │ │ ├── BinaryOperation.cs │ │ │ ├── BoolLiteral.cs │ │ │ ├── ContainsStringExpression.cs │ │ │ ├── ContainsTimestampExpression.cs │ │ │ ├── DateTimeInterval.cs │ │ │ ├── DateTimeIntervalLiteral.cs │ │ │ ├── DateTimeLiteral.cs │ │ │ ├── ExpressionParser.cs │ │ │ ├── GreaterOrEqualsExpression.cs │ │ │ ├── GreaterThanExpression.cs │ │ │ ├── IExpression.cs │ │ │ ├── IInterval.cs │ │ │ ├── IntegerLiteral.cs │ │ │ ├── Interval.cs │ │ │ ├── IsExpression.cs │ │ │ ├── LessOrEqualsExpression.cs │ │ │ ├── LessThanExpression.cs │ │ │ ├── LineNumberVariable.cs │ │ │ ├── Literal.cs │ │ │ ├── LogLevelLiteral.cs │ │ │ ├── LogLevelVariable.cs │ │ │ ├── MessageVariable.cs │ │ │ ├── NotExpression.cs │ │ │ ├── OrExpression.cs │ │ │ ├── ParseException.cs │ │ │ ├── StringLiteral.cs │ │ │ ├── TimestampVariable.cs │ │ │ ├── Token.cs │ │ │ ├── TokenOrExpression.cs │ │ │ ├── TokenType.cs │ │ │ ├── Tokenizer.cs │ │ │ └── UnaryOperation.cs │ │ ├── Filter.cs │ │ ├── FilterExpression.cs │ │ ├── InvertFilter.cs │ │ ├── LevelFilter.cs │ │ ├── NoFilter.cs │ │ ├── OrFilter.cs │ │ ├── RangeFilter.cs │ │ ├── RegexFilter.cs │ │ ├── SubstringFilter.cs │ │ └── WildcardFilter.cs │ ├── FixedSizeList.cs │ ├── Formats │ │ └── TextLogFileFormat.cs │ ├── Int32Range.cs │ ├── Int32View.cs │ ├── ListExtensions.cs │ ├── LogFileFormats.cs │ ├── MathEx.cs │ ├── Parsers │ │ ├── DateTimeParser.cs │ │ ├── LogLevelParser.cs │ │ ├── TimeOfDaySecondsSinceStartParser.cs │ │ └── TimestampParser.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── ConcurrentPropertiesList.cs │ │ ├── IWellKnownReadOnlyPropertyDescriptor.cs │ │ ├── LogFilePropertiesExtensions.cs │ │ ├── Properties.cs │ │ ├── PropertiesBufferDebuggerVisualization.cs │ │ ├── PropertiesBufferHidingView.cs │ │ ├── PropertiesBufferList.cs │ │ ├── PropertiesBufferView.cs │ │ ├── ReadOnlyPropertyDescriptorExtensions.cs │ │ ├── TextProperties.cs │ │ ├── WellKnownProperty.cs │ │ └── WellKnownReadOnlyProperty.cs │ ├── QueueExtensions.cs │ ├── QuickFilterId.cs │ ├── Reader.cs │ ├── SerializableTypeExtensions.cs │ ├── ServiceContainer.cs │ ├── Settings │ │ ├── FilterMatchType.cs │ │ ├── ILogFileSettings.cs │ │ ├── QuickFilterActionType.cs │ │ ├── QuickFilterSettings.cs │ │ ├── QuickFiltersSettings.cs │ │ ├── SpecialDateTimeInterval.cs │ │ ├── TimeFilterMode.cs │ │ └── TimeFilterSettings.cs │ ├── SourceCannotBeAccessed.cs │ ├── SourceDoesNotExist.cs │ ├── Sources │ │ ├── AbstractLogSource.cs │ │ ├── AbstractProcessingLogSource.cs │ │ ├── Adorner │ │ │ ├── LogSourceColumnAdorner.cs │ │ │ └── LogSourcePropertyAdorner.cs │ │ ├── Buffer │ │ │ ├── FullyBufferedLogSource.cs │ │ │ ├── Page.cs │ │ │ ├── PageBufferedLogSource.cs │ │ │ ├── PagedLogBuffer.cs │ │ │ └── RetrievalState.cs │ │ ├── EmptyLogSource.cs │ │ ├── EventLogSource.cs │ │ ├── FilteredLogSource.cs │ │ ├── ILogSourceFactory.cs │ │ ├── InMemoryLogSource.cs │ │ ├── Issues │ │ │ └── LogSourceIssue.cs │ │ ├── ListenerProxy.cs │ │ ├── LogSourceDebuggerVisualization.cs │ │ ├── LogSourceExtensions.cs │ │ ├── LogSourceListenerCollection.cs │ │ ├── LogSourceListenerNotifier.cs │ │ ├── LogSourceProxy.cs │ │ ├── Merged │ │ │ ├── MergedLogLineIndex.cs │ │ │ ├── MergedLogLineIndexComparer.cs │ │ │ ├── MergedLogSource.cs │ │ │ ├── MergedLogSourceChanges.cs │ │ │ ├── MergedLogSourceIndex.cs │ │ │ ├── MergedLogSourcePendingModification.cs │ │ │ ├── MergedLogSourceSection.cs │ │ │ └── Stuff.cs │ │ ├── MultiLineLogSource.cs │ │ ├── ProxyLogListenerCollection.cs │ │ └── Text │ │ │ ├── EncodingDetector.cs │ │ │ ├── FileFingerprint.cs │ │ │ ├── FileFormatDetector.cs │ │ │ ├── FileLogSource.cs │ │ │ ├── FileLogSourceFactory.cs │ │ │ ├── GenericTextLogEntryParser.cs │ │ │ ├── GenericTextLogSource.cs │ │ │ ├── IRawFileLogSourceFactory.cs │ │ │ ├── Simple │ │ │ ├── StreamReaderEx.cs │ │ │ └── TextLogSource.cs │ │ │ ├── Streaming │ │ │ ├── LineOffsetDetector.cs │ │ │ └── StreamingTextLogSource.cs │ │ │ ├── StreamingTextLogSourceFactory.cs │ │ │ └── TextLogSourceFactory.cs │ ├── StringExtensions.cs │ ├── Tailviewer.Core.csproj │ ├── TypeFactory.cs │ ├── Writer.cs │ ├── XmlReaderExtensions.cs │ ├── XmlWriterExtensions.cs │ ├── app.config │ └── packages.config ├── Tailviewer.PluginRepository.Service │ ├── App.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Service.Designer.cs │ ├── Service.cs │ ├── Tailviewer.PluginRepository.Service.csproj │ ├── create_service.cmd │ ├── delete_service.cmd │ ├── install.cmd │ ├── packages.config │ ├── require_admin.cmd │ ├── set_environment.cmd │ ├── start_service.cmd │ └── stop_service.cmd ├── Tailviewer.PluginRepository.Tests │ ├── App.config │ ├── Applications │ │ └── AddPluginTest.cs │ ├── BinarySerializerTest.cs │ ├── IPEndPointExtensionsTest.cs │ ├── PluginIdentifierTest.cs │ ├── PluginRepositoryProxyTest.cs │ ├── PluginRepositoryTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── PublishedPluginDescriptionTest.cs │ ├── Tailviewer.PluginRepository.Tests.csproj │ └── packages.config ├── Tailviewer.PluginRepository │ ├── App.config │ ├── App.cs │ ├── Applications │ │ ├── AddPlugin.cs │ │ ├── AddPluginOptions.cs │ │ ├── AddUser.cs │ │ ├── AddUserOptions.cs │ │ ├── Export.cs │ │ ├── ExportOptions.cs │ │ ├── IApplication.cs │ │ ├── IPEndPointExtensions.cs │ │ ├── ListPlugins.cs │ │ ├── ListPluginsOptions.cs │ │ ├── ListUsers.cs │ │ ├── ListUsersOptions.cs │ │ ├── PluginRepositoryProxy.cs │ │ ├── RemovePlugin.cs │ │ ├── RemovePluginOptions.cs │ │ ├── RemoveUser.cs │ │ ├── RemoveUserOptions.cs │ │ ├── RunServer.cs │ │ ├── RunServerOptions.cs │ │ ├── WriteConfiguration.cs │ │ └── WriteConfigurationOptions.cs │ ├── Bootstrapper.cs │ ├── Configuration │ │ ├── Publishing.cs │ │ └── ServerConfiguration.cs │ ├── Constants.cs │ ├── Entities │ │ ├── Change.cs │ │ ├── PublishedPlugin.cs │ │ └── User.cs │ ├── Exceptions │ │ ├── CannotAddUserException.cs │ │ ├── CannotRemovePluginException.cs │ │ └── CannotRemoveUserException.cs │ ├── ExitCode.cs │ ├── IInternalPluginRepository.cs │ ├── Logging.cs │ ├── PluginRepository.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── README.md │ ├── Server.cs │ ├── Tailviewer.PluginRepository.csproj │ ├── pack_repository.cmd │ └── packages.config ├── Tailviewer.System.Tests │ ├── AssemblySetup.cs │ ├── Plugins │ │ └── AbstractPluginCompatabilityTest.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Tailviewer.System.Tests.csproj │ ├── app.config │ └── packages.config ├── Tailviewer.Tests │ ├── Appender.cs │ ├── ArrayExtensionsTest.cs │ ├── AssemblySetup.cs │ ├── BusinessLogic │ │ ├── ActionCenter │ │ │ ├── ActionCenterTest.cs │ │ │ ├── ExportActionTest.cs │ │ │ └── OpenFolderActionTest.cs │ │ ├── AutoUpdater │ │ │ └── AutoUpdaterTest.cs │ │ ├── Bookmarks │ │ │ └── BookmarkCollectionTest.cs │ │ ├── DataSources │ │ │ ├── DataSourcesTest.cs │ │ │ ├── FolderDataSourceTest.cs │ │ │ └── MergedDataSourceTest.cs │ │ ├── Export │ │ │ ├── LogFileToFileExporterTest.cs │ │ │ └── LogFileToStreamExporterTest.cs │ │ ├── Highlighters │ │ │ ├── HighlighterIdTest.cs │ │ │ └── HighlighterTest.cs │ │ ├── Plugins │ │ │ ├── LogFileFormatMatcherPluginTest.cs │ │ │ ├── LogFileIssuesPluginTest.cs │ │ │ ├── LogFileOutlinePluginTest.cs │ │ │ ├── PluginInterfaceVersionAttributeTest.cs │ │ │ └── PluginInterfaceVersionTest.cs │ │ ├── Searches │ │ │ ├── LogSourceSearchTest.cs │ │ │ └── SearchResultsTest.cs │ │ ├── Settings │ │ │ ├── QuickFilterTest.cs │ │ │ └── QuickFiltersTest.cs │ │ └── Sources │ │ │ ├── LogEntryParserFactoryTest.cs │ │ │ ├── NoThrowLogEntryParserTest.cs │ │ │ ├── NoThrowLogSourceTest.cs │ │ │ ├── ParsingLogSourceFactoryTest.cs │ │ │ ├── PluginLogFileFactoryTest.cs │ │ │ └── Text │ │ │ ├── GenericTextLogEntryParserTest.cs │ │ │ └── GenericTextLogSourceTest.cs │ ├── ChangelogTest.cs │ ├── DesktopTest.cs │ ├── EnhancementAttribute.cs │ ├── FileExTest.cs │ ├── FileLogger.cs │ ├── ManualDispatcher.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── QuickFilterIdTest.cs │ ├── ReaderWriterTest.cs │ ├── RectangleTest.cs │ ├── SerializableTypeExtensions.cs │ ├── ServiceContainerTest.cs │ ├── Settings │ │ ├── ApplicationSettingsTest.cs │ │ ├── AutoUpdateSettingsTest.cs │ │ ├── Bookmarks │ │ │ └── BookmarksTest.cs │ │ ├── DataSourceSettingsTest.cs │ │ ├── DataSourceTest.cs │ │ ├── ExportSettingsTest.cs │ │ ├── LogLevelSettingsTest.cs │ │ ├── LogViewerSettingsTest.cs │ │ ├── MainWindowSettingsTest.cs │ │ ├── QuickFilterTest.cs │ │ ├── QuickFiltersTest.cs │ │ ├── TextSettingsTest.cs │ │ ├── TimeFilterTest.cs │ │ └── settings_no_file_guid.xml │ ├── SimpleLogEntryParserPlugin.cs │ ├── SimplePluginLogSourceFactory.cs │ ├── StringExtensionsTest.cs │ ├── Tailviewer.Tests.csproj │ ├── TestData │ │ ├── 1Line.txt │ │ ├── 1Line_WithNewline.txt │ │ ├── 1Mb.txt │ │ ├── 1Mb_1Line.txt │ │ ├── 1Mb_2Lines.txt │ │ ├── 20Mb.txt │ │ ├── 2Lines.txt │ │ ├── 2LogEntries.txt │ │ ├── 2MB.txt │ │ ├── 3LogEntries.txt │ │ ├── DifferentLevels.txt │ │ ├── Empty.txt │ │ ├── Encodings │ │ │ ├── utf16_be_bom.txt │ │ │ ├── utf16_le_bom.txt │ │ │ ├── utf8_w_bom.txt │ │ │ └── windows_1252.txt │ │ ├── Formats │ │ │ └── Serilog │ │ │ │ └── Serilog.txt │ │ ├── LevelCounts.txt │ │ ├── Multiline │ │ │ ├── Log1.txt │ │ │ └── Log2.txt │ │ ├── TestLive1.txt │ │ ├── TestLive2.txt │ │ ├── Timestamps │ │ │ ├── HH_mm_ss.txt │ │ │ ├── HH_mm_ss;s.txt │ │ │ ├── ddd MMM dd HH_mm_ss.fff yyyy.txt │ │ │ ├── yyyy MMM dd HH_mm_ss.fff.txt │ │ │ ├── yyyy-MM-dd HH_mm_ss.txt │ │ │ └── yyyy-MM-dd HH_mm_ss_fff.txt │ │ ├── dawwddwa.txt │ │ ├── utf8 - Copy.txt │ │ ├── utf8.txt │ │ └── version.xml │ ├── TypeFactoryTest.cs │ ├── Ui │ │ ├── AbstractDataSourceViewModelTest.cs │ │ ├── AutoUpdateViewModelTest.cs │ │ ├── AvailablePluginViewModelTest.cs │ │ ├── Controls │ │ │ ├── About │ │ │ │ └── ChangelogViewModelTest.cs │ │ │ ├── ActionCenter │ │ │ │ ├── ActionCenterViewModelTest.cs │ │ │ │ └── ExportViewModelTest.cs │ │ │ ├── DispatcherExtensions.cs │ │ │ ├── LogEntryListViewTest.cs │ │ │ ├── LogView │ │ │ │ ├── AdjustingDoubleConverterTest.cs │ │ │ │ ├── DataSourceCanvasTest.cs │ │ │ │ ├── DataSourceDisplayModeToggleButtonTest.cs │ │ │ │ ├── DeltaTimes │ │ │ │ │ ├── DeltaTimeColumnPresenterTest.cs │ │ │ │ │ └── DeltaTimePresenterTest.cs │ │ │ │ ├── ElapsedTime │ │ │ │ │ └── ElapsedTimePresenterTest.cs │ │ │ │ ├── LineNumbers │ │ │ │ │ └── OriginalLineNumberColumnPresenterTest.cs │ │ │ │ └── PresentationLogFileTest.cs │ │ │ ├── LogViewerControlTest.cs │ │ │ ├── MainPanel │ │ │ │ ├── LogViewMainPanelViewModelTest.cs │ │ │ │ ├── Plugins │ │ │ │ │ └── PluginViewModelTest.cs │ │ │ │ ├── Raw │ │ │ │ │ └── GoToLine │ │ │ │ │ │ └── GoToLineViewModelTest.cs │ │ │ │ └── Settings │ │ │ │ │ ├── CustomFormatPluginViewModelTest.cs │ │ │ │ │ └── SettingsControlTest.cs │ │ │ ├── MainWindowTest.cs │ │ │ ├── QuickNavigation │ │ │ │ ├── DataSourceSuggestionViewModelTest.cs │ │ │ │ └── QuickNavigationViewModelTest.cs │ │ │ ├── SidePanel │ │ │ │ ├── Bookmarks │ │ │ │ │ ├── BookmarkViewModelTest.cs │ │ │ │ │ └── BookmarksViewModelTest.cs │ │ │ │ ├── Issues │ │ │ │ │ └── IssuesSidePanelViewModelTest.cs │ │ │ │ ├── Outline │ │ │ │ │ ├── LogFilePropertyConverterTest.cs │ │ │ │ │ └── OutlineSidePanelViewModelTest.cs │ │ │ │ └── TimeFilter │ │ │ │ │ └── TimeFiltersViewModelTest.cs │ │ │ ├── TextCanvasTest.cs │ │ │ └── TextLineTest.cs │ │ ├── Converters │ │ │ └── CountConverterTest.cs │ │ ├── DataSourcesControlTest.cs │ │ ├── DataSourcesViewModelTest.cs │ │ ├── DragLayerTest.cs │ │ ├── FileDataSourceViewModelTest.cs │ │ ├── FolderDataSourceViewModelTest.cs │ │ ├── LogViewerViewModelTest.cs │ │ ├── MainWindowViewModelTest.cs │ │ ├── Menu │ │ │ └── EditMenuViewModelTest.cs │ │ ├── MergedDataSourceViewModelTest.cs │ │ ├── QuickFilterViewModelTest.cs │ │ ├── QuickFiltersSidePanelViewModelTest.cs │ │ ├── SettingsMainPanelViewModelTest.cs │ │ └── ToggleMenuViewModelTest.cs │ ├── app.config │ └── packages.config └── Tailviewer │ ├── App.config │ ├── App.cs │ ├── ArgumentParser.cs │ ├── Bootstrapper.cs │ ├── BusinessLogic │ ├── ActionCenter │ │ ├── ActionCenter.cs │ │ ├── ActionCenterExtensions.cs │ │ ├── Build.cs │ │ ├── Change.cs │ │ ├── ExportAction.cs │ │ ├── ExportException.cs │ │ ├── IActionCenter.cs │ │ ├── IBug.cs │ │ ├── IExportAction.cs │ │ ├── INotification.cs │ │ ├── IOpenFolderAction.cs │ │ ├── Level.cs │ │ ├── Notification.cs │ │ ├── OpenFolderAction.cs │ │ ├── OpenFolderException.cs │ │ └── UnhandledException.cs │ ├── AutoUpdates │ │ ├── AutoUpdater.cs │ │ ├── IAutoUpdater.cs │ │ └── VersionInfo.cs │ ├── Bookmarks │ │ ├── Bookmark.cs │ │ └── BookmarkCollection.cs │ ├── DataSources │ │ ├── AbstractDataSource.cs │ │ ├── Count.cs │ │ ├── Custom │ │ │ ├── CustomDataSource.cs │ │ │ ├── ICustomDataSource.cs │ │ │ ├── NoThrowCustomDataSourceConfiguration.cs │ │ │ └── NoThrowCustomDataSourcePlugin.cs │ │ ├── DataSources.cs │ │ ├── FileDataSource.cs │ │ ├── FolderDataSource.cs │ │ ├── IDataSource.cs │ │ ├── IDataSources.cs │ │ ├── IFileDataSource.cs │ │ ├── IFolderDataSource.cs │ │ ├── IMergedDataSource.cs │ │ ├── IMultiDataSource.cs │ │ ├── ISingleDataSource.cs │ │ └── MergedDataSource.cs │ ├── Drive.cs │ ├── Exporter │ │ ├── ILogFileExporter.cs │ │ ├── ILogFileToFileExporter.cs │ │ ├── LogFileToFileExporter.cs │ │ └── LogFileToStreamExporter.cs │ ├── FileEx.cs │ ├── FileExplorer │ │ ├── FileExplorer.cs │ │ ├── IFileExplorer.cs │ │ └── NativeMethods.cs │ ├── Filters │ │ ├── IQuickFilters.cs │ │ ├── QuickFilter.cs │ │ ├── QuickFilters.cs │ │ └── TimeFilter.cs │ ├── Highlighters │ │ ├── Highlighter.cs │ │ ├── HighlighterCollection.cs │ │ ├── HighlighterId.cs │ │ └── IHighlighters.cs │ ├── LogFileFormats │ │ ├── ILogFileFormatRegistry.cs │ │ └── LogFileFormatRegistry.cs │ ├── NoThrowTimestampParser.cs │ ├── Plugins │ │ ├── IPluginUpdater.cs │ │ └── PluginUpdater.cs │ ├── Searches │ │ ├── DispatchedSearchResults.cs │ │ ├── ILogFileSearchListener.cs │ │ ├── ILogSourceSearch.cs │ │ ├── ISearchResults.cs │ │ ├── ISearchResultsByLogLineIndex.cs │ │ ├── LogFileSearchListenerCollection.cs │ │ ├── LogMatch.cs │ │ ├── LogMatchIndex.cs │ │ ├── LogMatchSection.cs │ │ ├── LogSourceSearch.cs │ │ ├── LogSourceSearchProxy.cs │ │ ├── SearchResults.cs │ │ ├── SearchResultsByLogLineIndex.cs │ │ └── SearchResultsListener.cs │ └── Sources │ │ ├── ILogSourceFactory.cs │ │ ├── LogEntryParserFactory.cs │ │ ├── LogFileFormatMatcher.cs │ │ ├── NoThrowLogEntryParser.cs │ │ ├── NoThrowLogFileFormatMatcher.cs │ │ ├── NoThrowLogSource.cs │ │ ├── ParsingLogSourceFactory.cs │ │ └── PluginLogSourceFactory.cs │ ├── Changelog.cs │ ├── Collections │ ├── CompoundObservableCollection.cs │ ├── EnumerableExtensions.cs │ ├── FilteringObservableCollection.cs │ ├── IObservableCollection.cs │ ├── ObservableCollectionExt.cs │ └── ProjectingObservableCollection.cs │ ├── Constants.cs │ ├── FrameworkElementExtensions.cs │ ├── HashSetExtensions.cs │ ├── Int32RangeRule.cs │ ├── Language.cs │ ├── Licenses │ ├── GoogleMaterialDesignIcons │ │ └── License.txt │ ├── Inconsolata │ │ └── OFL.txt │ ├── Log4Net │ │ └── LICENSE-2.0.txt │ ├── MMQ │ │ └── LICENSE │ ├── MaterialDesignIcons │ │ └── License.txt │ ├── Metrolib │ │ └── License.txt │ ├── Ookii.Dialogs.Wpf │ │ └── LICENSE │ ├── System.Threading.Extensions │ │ └── LICENSE │ └── Xceed.Wpf.Toolkit │ │ └── LICENSE │ ├── Properties │ └── AssemblyInfo.cs │ ├── Resource.cs │ ├── Resources │ ├── Fonts │ │ ├── FONTLOG.txt │ │ ├── Inconsolata-Bold.ttf │ │ ├── Inconsolata-Regular.ttf │ │ └── METADATA.pb │ ├── Icons.xaml │ ├── Tailviewer.ico │ ├── Tailviewer.png │ ├── ic_alarm_black_18dp.png │ ├── ic_no_time_black_18dp.png │ ├── ic_no_time_black_8dp.png │ ├── ic_no_time_white_18dp.png │ ├── ic_no_time_white_8dp.png │ └── ic_open_10_black_18dp.png │ ├── Settings │ ├── ApplicationSettings.cs │ ├── AutoUpdateSettings.cs │ ├── Bookmarks │ │ ├── BookmarkSettings.cs │ │ ├── Bookmarks.cs │ │ └── IBookmarks.cs │ ├── CustomFormats │ │ ├── CustomFormatSettings.cs │ │ ├── CustomLogFileFormat.cs │ │ └── IDataSourcesSettings.cs │ ├── Dashboard │ │ ├── LayoutSettings.cs │ │ └── Widgets │ │ │ └── WidgetSettings.cs │ ├── DataSource.cs │ ├── DataSourceDisplayMode.cs │ ├── DataSourceSettings.cs │ ├── Desktop.cs │ ├── ExportSettings.cs │ ├── IApplicationSettings.cs │ ├── IAutoUpdateSettings.cs │ ├── ICustomFormatsSettings.cs │ ├── IExportSettings.cs │ ├── ILogViewerSettings.cs │ ├── IMainWindowSettings.cs │ ├── LogFileSettings.cs │ ├── LogLevelSettings.cs │ ├── LogViewerSettings.cs │ ├── MainWindowSettings.cs │ └── TextSettings.cs │ ├── SingleApplicationHelper.cs │ ├── Tailviewer.csproj │ ├── Tailviewer.csproj.DotSettings │ ├── TaskExtensions.cs │ ├── Themes │ ├── Constants.xaml │ ├── Converters.xaml │ └── Generic.xaml │ ├── Ui │ ├── About │ │ ├── AboutFlyoutDataTemplate.xaml │ │ ├── AboutFlyoutViewModel.cs │ │ ├── ChangelogControl.xaml │ │ ├── ChangelogControl.xaml.cs │ │ ├── ChangelogViewModel.cs │ │ ├── Dependency.cs │ │ ├── LicenseControl.xaml │ │ ├── LicenseControl.xaml.cs │ │ ├── TailviewerControl.xaml │ │ └── TailviewerControl.xaml.cs │ ├── AboutViewModel.cs │ ├── AbstractMainPanelViewModel.cs │ ├── ActionCenter │ │ ├── AbstractNotificationViewModel.cs │ │ ├── ActionCenterControl.xaml │ │ ├── ActionCenterControl.xaml.cs │ │ ├── ActionCenterItem.xaml │ │ ├── ActionCenterViewModel.cs │ │ ├── BugTemplate.xaml │ │ ├── BugViewModel.cs │ │ ├── BuildTemplate.xaml │ │ ├── BuildViewModel.cs │ │ ├── ChangeTemplate.xaml │ │ ├── ChangeViewModel.cs │ │ ├── ExportTemplate.xaml │ │ ├── ExportViewModel.cs │ │ ├── INotificationViewModel.cs │ │ ├── NotificationTemplate.xaml │ │ └── NotificationViewModel.cs │ ├── AutoPopup.cs │ ├── AutoUpdateControl.xaml │ ├── AutoUpdateControl.xaml.cs │ ├── AutoUpdateViewModel.cs │ ├── Converters │ │ ├── AdjustingDoubleConverter.cs │ │ ├── BrushType.cs │ │ ├── CountConverter.cs │ │ ├── DoubleOneToHiddenConverter.cs │ │ ├── FollowTailTooltipConverter.cs │ │ ├── LevelToggleTooltipConverter.cs │ │ ├── NonMergedDataSourceToVisibilityCollapsedConverter.cs │ │ ├── NullToNotAvailableConverter.cs │ │ ├── ShowAllToContentConverter.cs │ │ ├── SkippedDueToTimestampConverter.cs │ │ ├── VersionConverter.cs │ │ └── ZeroToHiddenConverter.cs │ ├── DataSourceTree │ │ ├── CustomDataSourceTemplate.xaml │ │ ├── CustomDataSourceViewModel.cs │ │ ├── DataSourceArrangeAdorner.cs │ │ ├── DataSourceDragAdorner.cs │ │ ├── DataSourceDropAdorner.cs │ │ ├── DataSourceDropType.cs │ │ ├── DataSourcesControl.cs │ │ ├── DataSourcesControl.xaml │ │ ├── DataSourcesToggleButton.cs │ │ ├── DataSourcesToggleButton.xaml │ │ ├── DropInfo.cs │ │ ├── FileDataSourceTemplate.xaml │ │ ├── FileDataSourceViewModel.cs │ │ ├── FolderDataSourceTemplate.xaml │ │ ├── FolderDataSourceViewModel.cs │ │ ├── ICustomDataSourceViewModel.cs │ │ ├── IDataSourceViewModel.cs │ │ ├── IFileDataSourceViewModel.cs │ │ ├── IMergedDataSourceViewModel.cs │ │ ├── ISingleDataSourceViewModel.cs │ │ ├── MergedDataSourceTemplate.xaml │ │ ├── MergedDataSourceViewModel.cs │ │ ├── TreeItem.cs │ │ └── TreeViewItemStyle.xaml │ ├── DragLayer.cs │ ├── EmptyState.cs │ ├── EmptyStateStyle.xaml │ ├── FlatImage.cs │ ├── FlatImage.xaml │ ├── GoToLine │ │ ├── GoToLinePopup.cs │ │ └── GoToLineViewModel.cs │ ├── IFlyoutViewModel.cs │ ├── IMainPanelEntry.cs │ ├── IMainPanelViewModel.cs │ ├── IMainWindowViewModel.cs │ ├── ImageLabel.cs │ ├── ImageLabel.xaml │ ├── LogView │ │ ├── AbstractDataSourceViewModel.cs │ │ ├── AbstractLogColumnPresenter.cs │ │ ├── AbstractLogEntryValueFormatter.cs │ │ ├── AddCustomDataSourceViewModel.cs │ │ ├── Any │ │ │ ├── AnyColumnPresenter.cs │ │ │ └── AnyFormatter.cs │ │ ├── DataSource │ │ │ └── DataSourceCanvas.cs │ │ ├── DataSourceDisplayModeToggleButton.cs │ │ ├── DataSourceDisplayModeToggleButton.xaml │ │ ├── DeltaTimes │ │ │ ├── DeltaTimeColumnPresenter.cs │ │ │ └── DeltaTimeFormatter.cs │ │ ├── ElapsedTime │ │ │ ├── ElapsedTimeColumnPresenter.cs │ │ │ └── ElapsedTimeFormatter.cs │ │ ├── IFindAllViewModel.cs │ │ ├── ILogEntryValueFormatter.cs │ │ ├── ILogFileColumnPresenter.cs │ │ ├── ILogViewMainPanelViewModel.cs │ │ ├── ISearchViewModel.cs │ │ ├── LineNumbers │ │ │ ├── LineNumberFormatter.cs │ │ │ └── OriginalLineNumberColumnPresenter.cs │ │ ├── LogEntryListView.cs │ │ ├── LogLevelToggleButton.cs │ │ ├── LogLevelToggleButtonStyle.xaml │ │ ├── LogLevels │ │ │ ├── LevelFormatter.cs │ │ │ └── LogLevelColumnPresenter.cs │ │ ├── LogViewMainPanelDataTemplate.xaml │ │ ├── LogViewMainPanelViewModel.cs │ │ ├── LogViewerControl.cs │ │ ├── LogViewerControl.xaml │ │ ├── LogViewerViewModel.cs │ │ ├── Messages │ │ │ ├── MessageColumnPresenter.cs │ │ │ └── MessageFormatter.cs │ │ ├── PluginDescriptionControl.xaml │ │ ├── PluginDescriptionControl.xaml.cs │ │ ├── PresentationLogSource.cs │ │ ├── SelectMode.cs │ │ ├── TextBrushes.cs │ │ ├── TextCanvas.cs │ │ ├── TextLine.cs │ │ ├── TextSegment.cs │ │ ├── Timestamps │ │ │ ├── TimestampColumnPresenter.cs │ │ │ └── TimestampFormatter.cs │ │ ├── ToolbarToggleButton.cs │ │ └── ToolbarToggleButtonStyle.xaml │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── MainWindowViewModel.cs │ ├── Menu │ │ ├── AbstractMainMenuViewModel.cs │ │ ├── AbstractMenuViewModel.cs │ │ ├── CommandMenuViewModel.cs │ │ ├── EditMenuViewModel.cs │ │ ├── ExcludeAllInGroupViewModel.cs │ │ ├── FileMenuViewModel.cs │ │ ├── HelpMenuViewModel.cs │ │ ├── IMenu.cs │ │ ├── IMenuViewModel.cs │ │ ├── IncludeAllInGroupViewModel.cs │ │ ├── KeyBindingCommand.cs │ │ ├── MainMenu.cs │ │ ├── MenuItemTemplates.xaml │ │ ├── ParentMenuViewModel.cs │ │ ├── ToggleExcludeFromGroupViewModel.cs │ │ ├── ToggleMenuViewModel.cs │ │ └── ViewMenuViewModel.cs │ ├── NavigationService.cs │ ├── Plugins │ │ ├── AvailablePluginViewModel.cs │ │ ├── IPluginViewModel.cs │ │ ├── InstalledPluginViewModel.cs │ │ ├── PluginDataTemplate.xaml │ │ ├── PluginsMainPanelDataTemplate.xaml │ │ └── PluginsMainPanelViewModel.cs │ ├── QuickFilter │ │ ├── FilterToggleButton.cs │ │ ├── FilterToggleButton.xaml │ │ ├── QuickFilterDataTemplate.xaml │ │ ├── QuickFilterViewModel.cs │ │ ├── QuickFiltersDataTemplate.xaml │ │ └── QuickFiltersViewModel.cs │ ├── QuickFilterMatchTypeToggleButton.cs │ ├── QuickFilterMatchTypeToggleButton.xaml │ ├── QuickNavigation │ │ ├── DataSourceSuggestionViewModel.cs │ │ ├── QuickNavigationPopup.cs │ │ └── QuickNavigationViewModel.cs │ ├── Settings │ │ ├── CustomFormats │ │ │ ├── CustomFormatDataTemplate.xaml │ │ │ ├── CustomFormatPluginDataTemplate.xaml │ │ │ ├── CustomFormatPluginViewModel.cs │ │ │ ├── CustomFormatViewModel.cs │ │ │ ├── CustomFormatsSettingsDataTemplate.xaml │ │ │ └── CustomFormatsSettingsViewModel.cs │ │ ├── EncodingViewModel.cs │ │ ├── LogLevelSettingsViewModel.cs │ │ ├── SettingsControl.xaml │ │ ├── SettingsControl.xaml.cs │ │ ├── SettingsFlyoutDataTemplate.xaml │ │ └── SettingsFlyoutViewModel.cs │ └── SidePanel │ │ ├── AbstractSidePanelViewModel.cs │ │ ├── Bookmarks │ │ ├── BookmarkViewModel.cs │ │ ├── BookmarksDataTemplate.xaml │ │ └── BookmarksViewModel.cs │ │ ├── DataSources │ │ └── DataSourcesViewModel.cs │ │ ├── Highlighters │ │ ├── HighlighterDataTemplate.xaml │ │ ├── HighlighterViewModel.cs │ │ ├── HighlightersSidePanelDataTemplate.xaml │ │ └── HighlightersSidePanelViewModel.cs │ │ ├── HyperlinkRun.cs │ │ ├── ISidePanelViewModel.cs │ │ ├── Issues │ │ ├── IssueViewModel.cs │ │ ├── IssuesSidePanelDataTemplate.xaml │ │ ├── IssuesSidePanelViewModel.cs │ │ ├── IssuesViewModel.cs │ │ ├── LogSourceIssueAnalyserDummy.cs │ │ ├── NoThrowLogFileIssuePlugin.cs │ │ ├── NoThrowLogSourceIssueAnalyser.cs │ │ ├── SeverityToBrushConverter.cs │ │ └── SeverityToIconConverter.cs │ │ ├── Outline │ │ ├── IInternalLogFileOutlineViewModel.cs │ │ ├── LogFileOutlineViewModelProxy.cs │ │ ├── LogFilePropertyConverter.cs │ │ ├── OutlineSidePanelDataTemplate.xaml │ │ └── OutlineSidePanelViewModel.cs │ │ ├── Property │ │ ├── DefaultPropertyPresenter.cs │ │ ├── EncodingPropertyPresenter.cs │ │ ├── PropertiesSidePanelDataTemplate.xaml │ │ ├── PropertiesSidePanelViewModel.cs │ │ └── PropertyPresenterRegistry.cs │ │ ├── QuickFilters │ │ ├── QuickFiltersSidePanelDataTemplate.xaml │ │ ├── QuickFiltersSidePanelViewModel.cs │ │ └── TimeFilter │ │ │ ├── IChoseTimeRangeViewModel.cs │ │ │ ├── SpecialTimeRangeViewModel.cs │ │ │ ├── TimeChooserControl.xaml │ │ │ ├── TimeChooserControl.xaml.cs │ │ │ └── TimeFiltersViewModel.cs │ │ ├── SidePanelControl.cs │ │ └── SidePanelControl.xaml │ ├── app.manifest │ └── packages.config └── tools ├── .gitignore ├── BuildTool.exe ├── Crypt.exe ├── GenerateRedirects.exe └── zip.exe /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Explicitly declare text files you want to always be normalized and converted 5 | # to native line endings on checkout. 6 | *.cs text 7 | 8 | # Declare files that will always have CRLF line endings on checkout. 9 | *.sln text eol=crlf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | *.obj 3 | *.exe 4 | *.pdb 5 | *.user 6 | *.aps 7 | *.pch 8 | *.vspscc 9 | *_i.c 10 | *_p.c 11 | *.ncb 12 | *.suo 13 | *.sln.docstates 14 | *.tlb 15 | *.tlh 16 | *.bak 17 | *.cache 18 | *.ilk 19 | *.log 20 | *.diagsession 21 | [Bb]in 22 | [Dd]ebug*/ 23 | *.lib 24 | *.sbr 25 | obj/ 26 | _ReSharper*/ 27 | [Tt]est[Rr]esult* 28 | *.vssscc 29 | $tf*/ 30 | *.nupkg 31 | .vs/ 32 | 33 | /packages 34 | /Live 35 | 36 | # Visual C++ cache files 37 | ipch/ 38 | *.aps 39 | *.ncb 40 | *.opensdf 41 | *.sdf 42 | *.cachefile 43 | 44 | *.psess 45 | *.vspx 46 | *.etl -------------------------------------------------------------------------------- /.idea/.idea.Tailviewer/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /modules.xml 6 | /.idea.Tailviewer.iml 7 | /contentModel.xml 8 | /projectSettingsUpdater.xml 9 | # Datasource local storage ignored files 10 | /../../../../../../../../../:\Users\Simon\Documents\GitHub\Tailviewer\.idea\.idea.Tailviewer\.idea/dataSources/ 11 | /dataSources.local.xml 12 | # Editor-based HTTP Client requests 13 | /httpRequests/ 14 | -------------------------------------------------------------------------------- /.idea/.idea.Tailviewer/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.Tailviewer/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/.idea.Tailviewer/.idea/riderModule.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/.idea.Tailviewer/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.tfignore: -------------------------------------------------------------------------------- 1 | \.git -------------------------------------------------------------------------------- /Keys/.gitignore: -------------------------------------------------------------------------------- 1 | *.snk 2 | *.cer 3 | *.pvk -------------------------------------------------------------------------------- /Screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/Screenshot1.png -------------------------------------------------------------------------------- /Screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/Screenshot2.png -------------------------------------------------------------------------------- /Tailviewer-Complete.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | <data><IncludeFilters /><ExcludeFilters /></data> 3 | <data /> -------------------------------------------------------------------------------- /docs/BuildEvents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/docs/BuildEvents.png -------------------------------------------------------------------------------- /docs/CreateProject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/docs/CreateProject.png -------------------------------------------------------------------------------- /docs/DebugSettings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/docs/DebugSettings.png -------------------------------------------------------------------------------- /docs/NugetPackage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/docs/NugetPackage.png -------------------------------------------------------------------------------- /docs/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes #ticket id 2 | 3 | Changes proposed in this pull request: 4 | - 5 | - 6 | - 7 | - 8 | 9 | 10 | Any expected problems concerning backwards compatibility of existing plugins? 11 | Yes/No 12 | 13 | Any expected problems concerning backwards compatibility of existing user settings? 14 | Yes/No 15 | 16 | Does this break existing user workflows? 17 | Yes/No 18 | -------------------------------------------------------------------------------- /docs/issue_template.md: -------------------------------------------------------------------------------- 1 | ### Current behaviour 2 | 3 | 4 | 5 | ### Expected behaviour 6 | 7 | 8 | 9 | ### Steps to reproduce the problem 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/Tailviewer.LogLevelPlugin/TestData/Example.mylog: -------------------------------------------------------------------------------- 1 | 0 This log file contains lineswith log levels which are not detected by tailviewer by default. 2 | 1 DBG This is a DEBUG level line 3 | 2 ERR This line contains an ERROR 4 | 3 WARN This line contains a WARNING 5 | 4 TRA This line contains a TRACE message 6 | 5 INF This line is of INFORMATIVE nature 7 | 6 FAT This line is really FATal -------------------------------------------------------------------------------- /examples/Tailviewer.LogLevelPlugin/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /pack.cmd: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | 4 | if not defined APPVEYOR_BUILD_VERSION ( 5 | echo Error: Expected the environment variable APPVEYOR_BUILD_VERSION to be set, but it's not! 6 | exit /b -1 7 | ) 8 | 9 | nuget pack src\Tailviewer.Api\Tailviewer.Api.nuspec -Version %APPVEYOR_BUILD_VERSION%-beta 10 | 11 | endlocal 12 | -------------------------------------------------------------------------------- /playground/ControlPlayground/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playground/ControlPlayground/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /playground/ControlPlayground/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace ControlPlayground 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /playground/ControlPlayground/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /playground/ControlPlayground/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace ControlPlayground 2 | { 3 | /// 4 | /// Interaction logic for MainWindow.xaml 5 | /// 6 | public partial class MainWindow 7 | { 8 | public MainWindow() 9 | { 10 | InitializeComponent(); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /playground/ControlPlayground/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /playground/ControlPlayground/Themes/Generic.xaml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /playground/ControlPlayground/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /playground/FileLogger/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /playground/FileLogger/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /playground/Live/SQLiteLogger.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/playground/Live/SQLiteLogger.db -------------------------------------------------------------------------------- /playground/LogFile2Playground/ILogFile2.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Tailviewer.BusinessLogic.LogFiles; 4 | 5 | namespace LogFile2Playground 6 | { 7 | public interface ILogFile2 8 | { 9 | /// 10 | /// Requests the given section of the log file. 11 | /// 12 | /// 13 | /// 14 | Task RequestAsync(LogFileSection section); 15 | 16 | /// 17 | /// Requests the given section of the log file. 18 | /// 19 | /// 20 | /// 21 | /// 22 | Task RequestAsync(LogFileSection section, CancellationToken cancellationToken); 23 | } 24 | } -------------------------------------------------------------------------------- /playground/LogFile2Playground/ILogLineAccessor.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.BusinessLogic.LogFiles; 2 | 3 | namespace LogFile2Playground 4 | { 5 | public interface ILogLineAccessor 6 | { 7 | LogLineResponse Request(LogFileSection section); 8 | } 9 | } -------------------------------------------------------------------------------- /playground/LogFile2Playground/ILogLineCache.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using Metrolib; 4 | using Tailviewer.BusinessLogic.LogFiles; 5 | 6 | namespace LogFile2Playground 7 | { 8 | public interface ILogLineCache 9 | { 10 | Size EstimatedSize { get; } 11 | Task RequestAsync(LogFileSection section, CancellationToken cancellationToken); 12 | } 13 | } -------------------------------------------------------------------------------- /playground/LogFile2Playground/LogLineResponse.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.BusinessLogic.LogFiles; 2 | 3 | namespace LogFile2Playground 4 | { 5 | public struct LogLineResponse 6 | { 7 | public LogLine[] Lines; 8 | public LogFileSection ActualSection; 9 | } 10 | } -------------------------------------------------------------------------------- /playground/LogFile2Playground/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playground/Logger/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /playground/Logger/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Threading; 3 | using log4net; 4 | 5 | namespace Logger 6 | { 7 | internal class Program 8 | { 9 | private static readonly ILog Log = 10 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 11 | 12 | private static void Main(string[] args) 13 | { 14 | using (var logger = new Tailviewer.Test.Logger("Slow.log")) 15 | { 16 | while (true) 17 | { 18 | for (int i = 0; i < 9; ++i) 19 | { 20 | Log.InfoFormat("Test"); 21 | Thread.Sleep(10); 22 | } 23 | Log.WarnFormat("Shit"); 24 | } 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /playground/Logger/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /playground/LoggerCore/LoggingEventTemplate.cs: -------------------------------------------------------------------------------- 1 | using log4net.Core; 2 | 3 | namespace LoggerCore 4 | { 5 | public struct LoggingEventTemplate 6 | { 7 | public Level Level; 8 | public string Message; 9 | 10 | public LoggingEventTemplate(Level level, string message) 11 | { 12 | Level = level; 13 | Message = message; 14 | } 15 | 16 | public override string ToString() 17 | { 18 | return string.Format("{0} {1}", Level, Message); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /playground/LoggerCore/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /playground/LoggerCore/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /playground/NewDesign/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /playground/NewDesign/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /playground/NewDesign/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace NewDesign 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/ISidePanelViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Windows.Media; 3 | 4 | namespace NewDesign.Dashboard 5 | { 6 | public interface ISidePanelViewModel 7 | : INotifyPropertyChanged 8 | { 9 | Geometry Icon { get; } 10 | bool IsSelected { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Layout/HorizontalWidgetLayoutViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace NewDesign.Dashboard.Layout 2 | { 3 | public sealed class HorizontalWidgetLayoutViewModel 4 | : WidgetLayoutViewModel 5 | { 6 | } 7 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Layout/IWidgetLayoutViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using NewDesign.Dashboard.Widgets; 4 | 5 | namespace NewDesign.Dashboard.Layout 6 | { 7 | public interface IWidgetLayoutViewModel 8 | : INotifyPropertyChanged 9 | { 10 | IEnumerable Widgets { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Layout/VerticalLayoutDataTemplate.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/AbstractWidgetViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace NewDesign.Dashboard.Widgets 5 | { 6 | public abstract class AbstractWidgetViewModel 7 | : IWidgetViewModel 8 | { 9 | private bool _isEditing; 10 | 11 | public bool IsEditing 12 | { 13 | get { return _isEditing; } 14 | set 15 | { 16 | if (value == _isEditing) 17 | return; 18 | 19 | _isEditing = value; 20 | EmitPropertyChanged(); 21 | } 22 | } 23 | 24 | public event PropertyChangedEventHandler PropertyChanged; 25 | 26 | protected virtual void EmitPropertyChanged([CallerMemberName] string propertyName = null) 27 | { 28 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/Events/EventViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace NewDesign.Dashboard.Widgets.Events 6 | { 7 | public sealed class EventViewModel 8 | : INotifyPropertyChanged 9 | { 10 | public event PropertyChangedEventHandler PropertyChanged; 11 | 12 | public DateTime Timestamp { get; } 13 | public string Value { get; } 14 | 15 | private void EmitPropertyChanged([CallerMemberName] string propertyName = null) 16 | { 17 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/Events/EventsViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace NewDesign.Dashboard.Widgets.Events 5 | { 6 | public sealed class EventsViewModel 7 | : AbstractWidgetViewModel 8 | { 9 | private readonly ObservableCollection _events; 10 | 11 | public EventsViewModel() 12 | { 13 | _events = new ObservableCollection(); 14 | } 15 | 16 | public IEnumerable Events => _events; 17 | } 18 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/IWidgetViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace NewDesign.Dashboard.Widgets 4 | { 5 | public interface IWidgetViewModel 6 | : INotifyPropertyChanged 7 | { 8 | /// 9 | /// 10 | /// 11 | bool IsEditing { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/LineCount/LineCountViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace NewDesign.Dashboard.Widgets.LineCount 2 | { 3 | public class LineCountViewModel 4 | : AbstractWidgetViewModel 5 | { 6 | public long Count { get; set; } 7 | public string Caption { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/QuickInfos/INamedValueViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace NewDesign.Dashboard.Widgets.QuickInfos 4 | { 5 | public interface INamedValueViewModel 6 | : INotifyPropertyChanged 7 | { 8 | string Name { get; } 9 | object Value { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/Widget.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace NewDesign.Dashboard.Widgets 4 | { 5 | public static class Widget 6 | { 7 | public static readonly DependencyProperty IsEditingProperty = DependencyProperty.RegisterAttached( 8 | "IsEditing", typeof(bool), typeof(Widget), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits)); 9 | 10 | public static void SetIsEditing(DependencyObject element, bool value) 11 | { 12 | element.SetValue(IsEditingProperty, value); 13 | } 14 | 15 | public static bool GetIsEditing(DependencyObject element) 16 | { 17 | return (bool) element.GetValue(IsEditingProperty); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /playground/NewDesign/Dashboard/Widgets/WidgetSidePanelDataTemplate.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /playground/NewDesign/HorizontalWidgetLayoutViewModel.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/playground/NewDesign/HorizontalWidgetLayoutViewModel.cs -------------------------------------------------------------------------------- /playground/NewDesign/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace NewDesign 2 | { 3 | public partial class MainWindow 4 | { 5 | public MainWindow() 6 | { 7 | InitializeComponent(); 8 | DataContext = new MainWindowViewModel(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /playground/NewDesign/MenuItem.cs: -------------------------------------------------------------------------------- 1 | namespace NewDesign 2 | { 3 | public sealed class MenuItem 4 | { 5 | public MenuItem(string icon, string title) 6 | { 7 | Icon = icon; 8 | Title = title; 9 | } 10 | 11 | public string Icon { get; } 12 | 13 | public string Title { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /playground/NewDesign/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /playground/NewDesign/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /playground/SQLiteLogger/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /playground/SQLiteLogger/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /playground/TablePlayground/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /playground/TablePlayground/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /playground/TablePlayground/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Threading.Tasks; 5 | using System.Windows; 6 | 7 | namespace TablePlayground 8 | { 9 | /// 10 | /// Interaction logic for App.xaml 11 | /// 12 | public partial class App : Application 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /playground/TablePlayground/ILogColumn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TablePlayground 4 | { 5 | public interface ILogColumn 6 | { 7 | Type DataType { get; } 8 | } 9 | 10 | public interface ILogColumn 11 | : ILogColumn 12 | { 13 | 14 | } 15 | } -------------------------------------------------------------------------------- /playground/TablePlayground/LogColumn.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace TablePlayground 4 | { 5 | public sealed class LogColumn 6 | : ILogColumn 7 | { 8 | public Type DataType => typeof(T); 9 | } 10 | } -------------------------------------------------------------------------------- /playground/TablePlayground/LogEntry2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TablePlayground 5 | { 6 | public sealed class LogEntry2 7 | { 8 | private readonly IReadOnlyDictionary _columns; 9 | 10 | public LogEntry2(IReadOnlyDictionary columns) 11 | { 12 | if (columns == null) 13 | throw new ArgumentNullException(nameof(columns)); 14 | 15 | _columns = columns; 16 | } 17 | 18 | public T GetValue(ILogColumn column) 19 | { 20 | object value; 21 | if (!_columns.TryGetValue(column, out value)) 22 | throw new NotImplementedException(); 23 | 24 | return (T) value; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /playground/TablePlayground/LogFileContent.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.BusinessLogic.LogFiles; 2 | 3 | namespace TablePlayground 4 | { 5 | public struct LogFileContent 6 | { 7 | public LogEntry2[] Lines; 8 | public LogFileSection ActualSection; 9 | } 10 | } -------------------------------------------------------------------------------- /playground/TablePlayground/LogResponse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TablePlayground 4 | { 5 | public sealed class LogResponse 6 | { 7 | public IReadOnlyList Entries { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /playground/TablePlayground/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /playground/TablePlayground/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using Tailviewer.Core; 3 | 4 | namespace TablePlayground 5 | { 6 | public partial class MainWindow 7 | { 8 | private readonly ITaskScheduler _scheduler; 9 | //private readonly LogDataCache _cache; 10 | //private readonly SQLiteLogTable _table; 11 | 12 | public MainWindow() 13 | { 14 | InitializeComponent(); 15 | 16 | _scheduler = new DefaultTaskScheduler(); 17 | //_cache = new LogDataCache(); 18 | //_table = new SQLiteLogTable(_scheduler, _cache, @"..\Live\SQLiteLogger.db"); 19 | //TableView.LogTable = _table; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /playground/TablePlayground/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /playground/TablePlayground/TableCanvas.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Tailviewer.Core.LogTables; 3 | 4 | namespace TablePlayground 5 | { 6 | /// 7 | /// Responsible for only displaying the content of the currently visible region of an . 8 | /// Does NOT display header, etc... 9 | /// 10 | public sealed class TableCanvas 11 | : FrameworkElement 12 | { 13 | } 14 | } -------------------------------------------------------------------------------- /playground/TablePlayground/TableHeaderItem.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Core.LogTables; 2 | 3 | namespace TablePlayground 4 | { 5 | public sealed class TableHeaderItem 6 | { 7 | private readonly IColumnHeader _header; 8 | 9 | public TableHeaderItem(IColumnHeader header) 10 | { 11 | _header = header; 12 | } 13 | 14 | public string Name 15 | { 16 | get { return _header.Name; } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /playground/TablePlayground/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /sig/.gitignore: -------------------------------------------------------------------------------- 1 | *.snk 2 | !crypt.exe -------------------------------------------------------------------------------- /sig/DeveloperKey.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/sig/DeveloperKey.snk -------------------------------------------------------------------------------- /sig/key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/sig/key.snk -------------------------------------------------------------------------------- /sig/sns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/sig/sns -------------------------------------------------------------------------------- /src/GlobalAssemblyInfo.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/GlobalAssemblyInfo.cs -------------------------------------------------------------------------------- /src/Installer/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Installer/Applications/Install/InstallApplication.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Metrolib; 3 | 4 | namespace Installer.Applications.Install 5 | { 6 | public sealed class InstallApplication 7 | : Application 8 | { 9 | public static int Run(Arguments args) 10 | { 11 | var app = new InstallApplication(); 12 | var dispatcher = new UiDispatcher(System.Windows.Threading.Dispatcher.CurrentDispatcher); 13 | var window = new MainWindow(new MainWindowViewModel(dispatcher)); 14 | window.Show(); 15 | return app.Run(); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Installer/Applications/Install/LicenseWindow.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Installer/Applications/Uninstall/UninstallApplication.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using log4net; 3 | 4 | namespace Installer.Applications.Uninstall 5 | { 6 | public class UninstallApplication 7 | { 8 | private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 9 | 10 | public static int Run(Arguments arguments) 11 | { 12 | var installationPath = arguments.InstallationPath; 13 | Log.InfoFormat("Uninstalling {0} from '{1}'...", Constants.ApplicationTitle, installationPath); 14 | 15 | var installer = new Installer(); 16 | installer.Uninstall(installationPath); 17 | 18 | Log.InfoFormat("Uninstallation finished"); 19 | 20 | return 0; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Installer/Exceptions/CopyFileException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Installer.Exceptions 4 | { 5 | public class CopyFileException 6 | : FileIoException 7 | { 8 | public CopyFileException(string fileName, string destFolder, Exception innerException) 9 | : base(string.Format("Could not copy '{0}' to '{1}': {2}", 10 | fileName, 11 | destFolder, 12 | innerException.Message), innerException) 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Installer/Exceptions/DeleteFileException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Installer.Exceptions 4 | { 5 | public class DeleteFileException 6 | : FileIoException 7 | { 8 | public DeleteFileException(string fileName, string sourceFolder, Exception innerException) 9 | : base(string.Format("Could not delete '{0}' from '{1}': {2}", 10 | fileName, 11 | sourceFolder, 12 | innerException.Message), innerException) 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Installer/Exceptions/FileIOException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Installer.Exceptions 5 | { 6 | public class FileIoException 7 | : IOException 8 | { 9 | public FileIoException(string message, Exception innerException) 10 | : base(message, innerException) 11 | { 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Installer/InstallationFiles/Plugins/Readme.txt: -------------------------------------------------------------------------------- 1 | Tailviewer can be extended by installing plugins for file formats which aren't natively supported. 2 | 3 | In order to start developing a plugin, you need to install Visual Studio (any version since Visual Studio 2012 will do) 4 | and create a new Class Library targeting .NET 4.5. You must then add a reference to Tailviewers API which can be found on https://www.nuget.org/packages/tailviewer.api/. 5 | Please note the API is not yet stable and subject to change until release 1.0. Once you've implemented at least one of the IPlugin interfaces, 6 | such as IFileFormatPlugin, you can place your plugin in this folder. 7 | 8 | A real world example of such a plugin can be found under https://github.com/Kittyfisto/Tailviewer.Plugins.SQLite, 9 | which shows how to allow Tailviewer to display a table from a SQLite file. -------------------------------------------------------------------------------- /src/Installer/InstallationFiles/Tailviewer.AcceptanceTests.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Installer/InstallationFiles/Tailviewer.AcceptanceTests.dll -------------------------------------------------------------------------------- /src/Installer/Mode.cs: -------------------------------------------------------------------------------- 1 | namespace Installer 2 | { 3 | public enum Mode 4 | { 5 | Install, 6 | SilentInstall, 7 | Update, 8 | Uninstall 9 | } 10 | } -------------------------------------------------------------------------------- /src/Installer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Installer/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.Formats.Serilog.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.Formats.Serilog.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.Formats.Serilog/SerilogEntryParserPlugin.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | 3 | namespace Tailviewer.Formats.Serilog 4 | { 5 | /// 6 | /// Plugin to allow parsing of serilog text files. 7 | /// 8 | public sealed class SerilogEntryParserPlugin 9 | : ILogEntryParserPlugin 10 | { 11 | #region Implementation of ITextLogFileParserPlugin 12 | 13 | public ILogEntryParser CreateParser(IServiceContainer services, ILogFileFormat format) 14 | { 15 | var serilogFormat = format as SerilogFileFormat; 16 | if (serilogFormat == null) 17 | return null; 18 | 19 | return serilogFormat.Parser; 20 | } 21 | 22 | #endregion 23 | } 24 | } -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.Formats.Serilog/SerilogFileFormatMatcherPlugin.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | 3 | namespace Tailviewer.Formats.Serilog 4 | { 5 | public sealed class SerilogFileFormatMatcherPlugin 6 | : ILogFileFormatMatcherPlugin 7 | { 8 | #region Implementation of ILogFileFormatMatcherPlugin 9 | 10 | public ILogFileFormatMatcher CreateMatcher(IServiceContainer services) 11 | { 12 | var registry = services.Retrieve(); 13 | return new SerilogFileFormatMatcher(registry); 14 | } 15 | 16 | #endregion 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.Formats.Serilog/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.Formats.Serilog/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Plugins/Tailviewer.PluginCreator/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Tailviewer.Acceptance.Tests/AssemblySetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using NUnit.Framework; 5 | 6 | namespace Tailviewer.Acceptance.Tests 7 | { 8 | [SetUpFixture] 9 | public sealed class AssemblySetup 10 | { 11 | [OneTimeSetUp] 12 | public void SetUp() 13 | { 14 | Directory.SetCurrentDirectory(AssemblyDirectory); 15 | } 16 | 17 | public static string AssemblyDirectory 18 | { 19 | get 20 | { 21 | string codeBase = Assembly.GetExecutingAssembly().CodeBase; 22 | UriBuilder uri = new UriBuilder(codeBase); 23 | string path = Uri.UnescapeDataString(uri.Path); 24 | return Path.GetDirectoryName(path); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Tailviewer.Acceptance.Tests/BusinessLogic/DataSources/FileDataSourceAcceptanceTest.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using NUnit.Framework; 3 | using Tailviewer.BusinessLogic.Sources; 4 | using Tailviewer.Tests; 5 | 6 | namespace Tailviewer.Acceptance.Tests.BusinessLogic.DataSources 7 | { 8 | [TestFixture] 9 | public sealed class FileDataSourceAcceptanceTest 10 | { 11 | private ManualTaskScheduler _scheduler; 12 | private PluginLogSourceFactory _logSourceFactory; 13 | 14 | [SetUp] 15 | public void SetUp() 16 | { 17 | _scheduler = new ManualTaskScheduler(); 18 | _logSourceFactory = new SimplePluginLogSourceFactory(_scheduler); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tailviewer.Acceptance.Tests/BusinessLogic/Sources/Text/Simple/TextLogSourceTest2.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | using System.Threading; 4 | using NUnit.Framework; 5 | using Tailviewer.Api; 6 | using Tailviewer.Core; 7 | using Tailviewer.Core.Tests.Sources; 8 | 9 | namespace Tailviewer.Acceptance.Tests.BusinessLogic.Sources.Text.Simple 10 | { 11 | [TestFixture] 12 | public sealed class TextLogSourceTest2 13 | : AbstractTaskSchedulerLogFileTest 14 | { 15 | #region Overrides of AbstractTaskSchedulerLogFileTest 16 | 17 | protected override ILogSource CreateEmpty(IFilesystem filesystem, ITaskScheduler taskScheduler) 18 | { 19 | return new TextLogSource(filesystem, taskScheduler, "", LogFileFormats.GenericText, Encoding.Default); 20 | } 21 | 22 | #endregion 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/AssemblySetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using NUnit.Framework; 5 | 6 | namespace Tailviewer.Api.Tests 7 | { 8 | [SetUpFixture] 9 | [Parallelizable(ParallelScope.Fixtures)] 10 | public sealed class AssemblySetup 11 | { 12 | [OneTimeSetUp] 13 | public void SetUp() 14 | { 15 | Directory.SetCurrentDirectory(AssemblyDirectory); 16 | } 17 | 18 | public static string AssemblyDirectory 19 | { 20 | get 21 | { 22 | string codeBase = Assembly.GetExecutingAssembly().CodeBase; 23 | UriBuilder uri = new UriBuilder(codeBase); 24 | string path = Uri.UnescapeDataString(uri.Path); 25 | return Path.GetDirectoryName(path); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/IssueAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api.Tests 4 | { 5 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] 6 | public sealed class IssueAttribute 7 | : Attribute 8 | { 9 | public IssueAttribute(string issueUri) 10 | { 11 | IssueUri = issueUri; 12 | } 13 | 14 | public string IssueUri { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/LevelFlagsTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | 4 | namespace Tailviewer.Api.Tests 5 | { 6 | [TestFixture] 7 | public sealed class LevelFlagsTest 8 | { 9 | [Test] 10 | public void TestAll() 11 | { 12 | LevelFlags.All.Should().Be(LevelFlags.Fatal | LevelFlags.Error | LevelFlags.Warning | LevelFlags.Info | 13 | LevelFlags.Debug | LevelFlags.Trace | LevelFlags.Other); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/LocalTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Api.Tests 4 | { 5 | /// 6 | /// Attribute to mark tests that wont run in the CI environment (missing dependencies, rights, etc..) 7 | /// 8 | public sealed class LocalTest 9 | : CategoryAttribute 10 | { 11 | public LocalTest(string description) 12 | : base("LocalTest") 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/PathEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Tailviewer.Api.Tests 5 | { 6 | public static class PathEx 7 | { 8 | /// 9 | /// Actually returns a temporary file, unlike which may return a new temporary file 10 | /// or just given up because it's the weekend and it's already in its pajamas. 11 | /// 12 | /// 13 | public static string GetTempFileName() 14 | { 15 | var path = Path.Combine(Path.GetTempPath(), "Tailviewer", "Tests"); 16 | Directory.CreateDirectory(path); 17 | 18 | var fileName = Guid.NewGuid().ToString(); 19 | return Path.Combine(path, fileName); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/PercentageTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | 4 | namespace Tailviewer.Api.Tests 5 | { 6 | [TestFixture] 7 | public sealed class PercentageTest 8 | { 9 | [Test] 10 | public void TestConstants() 11 | { 12 | Percentage.Zero.RelativeValue.Should().Be(0); 13 | Percentage.FiftyPercent.RelativeValue.Should().Be(0.5f); 14 | Percentage.HundredPercent.RelativeValue.Should().Be(1); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/RequiresElevation.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Api.Tests 4 | { 5 | /// 6 | /// Attribute to mark tests that require elevated rights to run 7 | /// 8 | public sealed class RequiresElevation 9 | : CategoryAttribute 10 | { 11 | public RequiresElevation(string description) 12 | : base("RequiresElevation") 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Tailviewer.Api/Certainty.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// 5 | /// 6 | public enum Certainty 7 | { 8 | /// 9 | /// We aren't sure what we're dealing with. 10 | /// 11 | None, 12 | 13 | /// 14 | /// The guess might be correct, but we can't say for certain. 15 | /// 16 | Uncertain, 17 | 18 | /// 19 | /// We're certain and the format won't change anymore. 20 | /// 21 | Sure 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ColumnNotRetrievedException.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// This exception is thrown when a particular column MIGHT exist, but it hasn't been queried 5 | /// from the source and therefore isn't present. 6 | /// 7 | public sealed class ColumnNotRetrievedException 8 | : NoSuchColumnException 9 | { 10 | /// 11 | /// Initializes this object. 12 | /// 13 | /// 14 | public ColumnNotRetrievedException(IColumnDescriptor column) 15 | : base(string.Format("No column with the id '{0}' has been retrieved. You should fetch it if you think it exists!", column.Id)) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ILogFileFormatRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// A registry of all log file formats known by Tailviewer. Allows users to query the list of currently known 7 | /// (and supported) log file formats. 8 | /// 9 | [Service] 10 | public interface ILogFileFormatRepository 11 | { 12 | /// 13 | /// Returns the current list of supported log file formats. 14 | /// 15 | IReadOnlyList Formats { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ILogSourceListener.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// The interface for a class that is interested in receiving changes made to the data exposed by a 5 | /// . 6 | /// 7 | public interface ILogSourceListener 8 | { 9 | /// 10 | /// This method is called when a portion of the log file has been modified. 11 | /// 12 | /// The log-file that was modified 13 | /// The section of the log file that was modified 14 | void OnLogFileModified(ILogSource logSource, LogSourceModification modification); 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ILogSourceProxy.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// Fully represents another which can be replaced over the lifetime 5 | /// of the proxy. 6 | /// 7 | /// 8 | /// Exists so that specialized implementations don't need to be concerned about re-use 9 | /// or certain changes. 10 | /// 11 | public interface ILogSourceProxy 12 | : ILogSource 13 | { 14 | /// 15 | /// The log file represented by this proxy. 16 | /// 17 | ILogSource InnerLogSource { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/IMergedLogFile.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// The interface for a log file which aggregates the contents of one or more individual s. 7 | /// 8 | public interface IMergedLogFile 9 | { 10 | /// 11 | /// The actual sources from which the merged view is created. 12 | /// 13 | IReadOnlyList Sources { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/IPropertyDescriptor.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// Describes a property of an which may be changed by the end-user. 5 | /// 6 | public interface IPropertyDescriptor 7 | : IReadOnlyPropertyDescriptor 8 | { 9 | 10 | } 11 | 12 | /// 13 | /// Describes a property of an which may be changed by the end-user. 14 | /// 15 | public interface IPropertyDescriptor 16 | : IReadOnlyPropertyDescriptor 17 | , IPropertyDescriptor 18 | { 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ISerializableType.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// The interface for a serializable type. 5 | /// 6 | public interface ISerializableType 7 | { 8 | /// 9 | /// Serializes this object using the given writer. 10 | /// 11 | /// 12 | void Serialize(IWriter writer); 13 | 14 | /// 15 | /// Deserializes a previously serialized object again. 16 | /// This method is called after the parameter less constructor 17 | /// of this type is called. 18 | /// 19 | /// 20 | void Deserialize(IReader reader); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ITimestampParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// The interface for a parser that is responsible for determining the timestamp of a message 7 | /// of a log line. 8 | /// 9 | public interface ITimestampParser 10 | { 11 | /// 12 | /// The minimum length (in characters) of the timestamp this parser is able to parse. 13 | /// 14 | int MinimumLength { get; } 15 | 16 | /// 17 | /// 18 | /// 19 | /// 20 | /// 21 | bool TryParse(string content, out DateTime timestamp); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ITypeFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// Responsible for creating serializable types from their type name. 7 | /// 8 | [Service] 9 | public interface ITypeFactory 10 | { 11 | /// 12 | /// Tries to create a new object of the given type or returns null 13 | /// if the type is not known or creation failed. 14 | /// 15 | /// 16 | /// 17 | ISerializableType TryCreateNew(string typeName); 18 | 19 | /// 20 | /// Tries to lookup the name of the given type. 21 | /// 22 | /// 23 | /// 24 | string TryGetTypeName(Type type); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/LogEntrySectionExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Api 2 | { 3 | /// 4 | /// 5 | /// 6 | public static class LogEntrySectionExtensions 7 | { 8 | /// 9 | /// Copies data from the given array into this buffer. 10 | /// 11 | /// 12 | /// 13 | /// The column to copy data to 14 | /// The source from which to copy data from 15 | public static void CopyFrom(this ILogBuffer section, IColumnDescriptor column, T[] source) 16 | { 17 | section.CopyFrom(column, 0, source, 0, source.Length); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/NoSuchColumnException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// Thrown when a column which doesn't exist is accessed. 7 | /// 8 | public class NoSuchColumnException 9 | : ArgumentException 10 | { 11 | /// 12 | /// Initializes this object. 13 | /// 14 | /// 15 | public NoSuchColumnException(IColumnDescriptor column) 16 | : base(string.Format("No such column: '{0}'", column.Id)) 17 | {} 18 | 19 | /// 20 | /// Initializes this object. 21 | /// 22 | /// 23 | public NoSuchColumnException(string message) 24 | : base(message) 25 | { } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/NoSuchPropertyException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// This exception is thrown when one tries to change the property of a log file which doesn't even have that property. 7 | /// 8 | public sealed class NoSuchPropertyException 9 | : ArgumentException 10 | { 11 | /// 12 | /// Initializes this object. 13 | /// 14 | /// 15 | public NoSuchPropertyException(IReadOnlyPropertyDescriptor property) 16 | : base(string.Format("This log file doesn't have a property '{0}'", property)) 17 | {} 18 | } 19 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/NoSuchServiceException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// This exception is thrown when a service which is not registered with the is accessed. 7 | /// 8 | public sealed class NoSuchServiceException 9 | : ArgumentException 10 | { 11 | /// 12 | /// 13 | /// 14 | public NoSuchServiceException(Type missingService) 15 | : base($"No service has been registered with this container which implements {missingService.FullName}") 16 | {} 17 | } 18 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/Plugins/ICustomLogFileFormat.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace Tailviewer.Api 5 | { 6 | /// 7 | /// 8 | public interface ICustomLogFileFormat 9 | { 10 | /// 11 | /// The human readable name of this format 12 | /// 13 | string Name { get; } 14 | 15 | /// 16 | /// The format (input by a human) which specifies how the log file is to be interpreted 17 | /// 18 | string Format { get; } 19 | 20 | /// 21 | /// The encoding with which the text file is to be opened. 22 | /// 23 | Encoding Encoding { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/Plugins/ILogSourceParserPlugin.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Api 3 | { 4 | /// 5 | /// This plugin needs to be implemented when introducing a log format to tailviewer that it does not natively support. 6 | /// 7 | [Service] 8 | public interface ILogSourceParserPlugin 9 | : IPlugin 10 | { 11 | /// 12 | /// Creates a new log source which aggregates the given one provides access to more columns based on what 13 | /// could be parsed from the original source. 14 | /// 15 | /// 16 | /// 17 | /// 18 | [ThreadSafe] 19 | ILogSource CreateParser(IServiceContainer services, ILogSource source); 20 | } 21 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/Plugins/IPlugin.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Api 3 | { 4 | /// 5 | /// The tag-interface for any Tailviewer plugin. 6 | /// 7 | public interface IPlugin 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/Plugins/Severity.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Api 3 | { 4 | /// 5 | /// Describes the severity of an issue. 6 | /// 7 | public enum Severity 8 | { 9 | /// 10 | /// The issue is a minor one. 11 | /// 12 | Minor, 13 | 14 | /// 15 | /// The issue is major and possibly requires a user's attention. 16 | /// 17 | Major, 18 | 19 | /// 20 | /// The issue is critical and requires a user's attention. 21 | /// 22 | Critical 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/ServiceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Api 4 | { 5 | /// 6 | /// This attribute marks interfaces which can be retrieved from a . 7 | /// 8 | /// 9 | /// This attribute doesn't influence Tailviewer's behavior: It exists so plugin authors can search for the list 10 | /// of interfaces which are provided by the service container from within their IDE / in Tailviewer's source code. 11 | /// 12 | [AttributeUsage(AttributeTargets.Interface)] 13 | public sealed class ServiceAttribute 14 | : Attribute 15 | { 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/Ui/INavigationService.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Api 3 | { 4 | /// 5 | /// This service enables users to navigate tailviewer programmatically. 6 | /// Is part of . 7 | /// 8 | [Service] 9 | public interface INavigationService 10 | { 11 | /// 12 | /// Navigates to the given line of the currently selected data source. 13 | /// 14 | /// 15 | bool NavigateTo(LogLineIndex line); 16 | 17 | /// 18 | /// Navigates to the given line of the given data source. 19 | /// 20 | /// 21 | /// 22 | bool NavigateTo(DataSourceId dataSource, LogLineIndex line); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer.Api/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Tailviewer.Api/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/AbstractPluginTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using FluentAssertions; 3 | 4 | namespace Tailviewer.Archiver.Tests 5 | { 6 | public abstract class AbstractPluginTest 7 | { 8 | protected static void CreatePlugin(string assemblyFileName, 9 | string author = null, 10 | string website = null, 11 | string description = null) 12 | { 13 | var pluginName = Path.GetFileNameWithoutExtension(assemblyFileName); 14 | var idParts = pluginName.Split('.'); 15 | idParts.Should().HaveCount(2); 16 | var @namespace = idParts[0]; 17 | var name = idParts[1]; 18 | 19 | var builder = new PluginBuilder(@namespace, name, pluginName, author, website, description); 20 | builder.Save(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/AggregatedPluginLoaderTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | using Tailviewer.Archiver.Plugins; 5 | 6 | namespace Tailviewer.Archiver.Tests 7 | { 8 | [TestFixture] 9 | public sealed class AggregatedPluginLoaderTest 10 | { 11 | [Test] 12 | public void TestLoadPluginEmpty() 13 | { 14 | var loader = new AggregatedPluginLoader(); 15 | loader.LoadAllOfType().Should().BeEmpty(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/AssemblySetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using NUnit.Framework; 5 | 6 | namespace Tailviewer.Archiver.Tests 7 | { 8 | [SetUpFixture] 9 | [Parallelizable(ParallelScope.Fixtures)] 10 | public sealed class AssemblySetup 11 | { 12 | [OneTimeSetUp] 13 | public void SetUp() 14 | { 15 | Directory.SetCurrentDirectory(AssemblyDirectory); 16 | } 17 | 18 | public static string AssemblyDirectory 19 | { 20 | get 21 | { 22 | string codeBase = Assembly.GetExecutingAssembly().CodeBase; 23 | UriBuilder uri = new UriBuilder(codeBase); 24 | string path = Uri.UnescapeDataString(uri.Path); 25 | return Path.GetDirectoryName(path); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/BinaryFormatterExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Runtime.Serialization.Formatters.Binary; 3 | 4 | namespace Tailviewer.Archiver.Tests 5 | { 6 | public static class BinaryFormatterExtensions 7 | { 8 | public static T Roundtrip(T value) 9 | { 10 | using (var stream = new MemoryStream()) 11 | { 12 | BinaryFormatter bf = new BinaryFormatter(); 13 | bf.Serialize(stream, value); 14 | stream.Position = 0; 15 | 16 | return (T) bf.Deserialize(stream); 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/Plugins/Description/PluginImplementationDescriptionTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | using Tailviewer.Archiver.Plugins.Description; 5 | 6 | namespace Tailviewer.Archiver.Tests.Plugins.Description 7 | { 8 | [TestFixture] 9 | public sealed class PluginImplementationDescriptionTest 10 | { 11 | [PluginInterfaceVersion(42)] 12 | interface ISomeCoolPlugin 13 | : IPlugin 14 | {} 15 | 16 | [Test] 17 | public void TestConstruction() 18 | { 19 | var description = new PluginImplementationDescription("A.B.SomeType", typeof(ISomeCoolPlugin)); 20 | description.FullTypeName.Should().Be("A.B.SomeType"); 21 | description.Version.Should().Be(new PluginInterfaceVersion(42)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/Plugins/PluginIdTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Archiver.Plugins; 4 | 5 | namespace Tailviewer.Archiver.Tests.Plugins 6 | { 7 | [TestFixture] 8 | public sealed class PluginIdTest 9 | { 10 | [Test] 11 | public void TestEquality() 12 | { 13 | new PluginId("A").Should().Be(new PluginId("A")); 14 | new PluginId("A").Should().NotBe(new PluginId("a")); 15 | new PluginId("A").Should().NotBe(new PluginId("â")); 16 | new PluginId("A").Should().NotBe(new PluginId("b")); 17 | } 18 | 19 | [Test] 20 | public void TestToString() 21 | { 22 | var id = new PluginId("MyCompany.Namespace.Log"); 23 | id.ToString().Should().Be("MyCompany.Namespace.Log"); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/Repository/RemotePublishDisabledExceptionTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Archiver.Repository; 4 | 5 | namespace Tailviewer.Archiver.Tests.Repository 6 | { 7 | [TestFixture] 8 | public sealed class RemotePublishDisabledExceptionTest 9 | { 10 | [Test] 11 | public void TestRoundtrip() 12 | { 13 | BinaryFormatterExtensions.Roundtrip(new RemotePublishDisabledException()) 14 | .Should().BeOfType(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Managed/AnyCPU/ClassLibrary1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Managed/AnyCPU/ClassLibrary1.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Managed/x64/ClassLibrary1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Managed/x64/ClassLibrary1.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Managed/x86/ClassLibrary1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Managed/x86/ClassLibrary1.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Managed/x86/Targets.NET.4.6.1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Managed/x86/Targets.NET.4.6.1.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Managed/x86/Targets.NET.4.6.2.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Managed/x86/Targets.NET.4.6.2.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Managed/x86/Targets.NET.4.6.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Managed/x86/Targets.NET.4.6.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Native/x64/NativeImage.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Native/x64/NativeImage.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/Native/x86/NativeImage.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/Native/x86/NativeImage.dll -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/TestData/cropped-uiforetwicon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Archiver.Tests/TestData/cropped-uiforetwicon2.png -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Tailviewer.Archiver 5 | { 6 | public static class EnumerableExtensions 7 | { 8 | public static T MaxBy(this IEnumerable values, Func selector) where TY : IComparable 9 | { 10 | using (var it = values.GetEnumerator()) 11 | { 12 | if (!it.MoveNext()) 13 | return default(T); 14 | 15 | T highest = it.Current; 16 | TY highestValue = selector(highest); 17 | while (it.MoveNext()) 18 | { 19 | TY currentValue = selector(it.Current); 20 | if (currentValue.CompareTo(highestValue) > 0) 21 | { 22 | highest = it.Current; 23 | highestValue = currentValue; 24 | } 25 | } 26 | 27 | return highest; 28 | } 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/ExitCode.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Archiver 2 | { 3 | public enum ExitCode 4 | { 5 | Success = 0, 6 | 7 | GenericFailure = -1, 8 | 9 | RemotePublishDisabled = -10, 10 | CorruptPlugin = -11, 11 | InvalidUserToken = -12, 12 | PluginAlreadyPublished = -13, 13 | ConnectionError = -14, 14 | 15 | FileNotFound = -20, 16 | DirectoryNotFound = -21, 17 | 18 | UnhandledException = int.MinValue 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/ListOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.Archiver 4 | { 5 | [Verb("list", HelpText = "List the contents of an existing tailviewer plugin archive")] 6 | public sealed class ListOptions 7 | { 8 | 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/PackException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Archiver 4 | { 5 | /// 6 | /// An exception that occured during packing of an archive. 7 | /// Messages are descriptive enough to be printed to the user 8 | /// (omitting callstack and other things). 9 | /// 10 | public sealed class PackException 11 | : Exception 12 | { 13 | public PackException(string message) 14 | : base(message) 15 | { 16 | } 17 | 18 | public PackException(string message, Exception inner) 19 | : base(message) 20 | { 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/AssemblyReference.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Tailviewer.Archiver.Plugins 4 | { 5 | /// 6 | /// Describes an assembly referenced by another assembly in a plugin package. 7 | /// 8 | [DataContract] 9 | public sealed class AssemblyReference : IAssemblyReference 10 | { 11 | /// 12 | [DataMember] 13 | public string FullName { get; set; } 14 | 15 | /// 16 | public override string ToString() 17 | { 18 | return FullName ?? string.Empty; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/Description/Change.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Archiver.Plugins.Description 2 | { 3 | public sealed class Change 4 | : IChange 5 | { 6 | public Change() 7 | {} 8 | 9 | public Change(SerializableChange serializableChange) 10 | { 11 | Summary = serializableChange.Summary; 12 | Description = serializableChange.Description; 13 | } 14 | 15 | public string Summary { get; set; } 16 | public string Description { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/Description/IChange.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Archiver.Plugins.Description 2 | { 3 | public interface IChange 4 | { 5 | /// 6 | /// A required short one sentence summary of the change. 7 | /// 8 | string Summary { get; } 9 | 10 | /// 11 | /// An optional (possibly longer) description of the change. 12 | /// 13 | string Description { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/Description/IPluginImplementationDescription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.Archiver.Plugins.Description 5 | { 6 | /// 7 | /// 8 | public interface IPluginImplementationDescription 9 | { 10 | /// 11 | /// The full .NET type name (sans assembly) of the class implementing the plugin interface. 12 | /// 13 | string FullTypeName { get; } 14 | 15 | /// 16 | /// The version of the interface being implemented. 17 | /// 18 | PluginInterfaceVersion Version { get; } 19 | 20 | /// 21 | /// The interface which is implemented by this type. 22 | /// 23 | Type InterfaceType { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/IAssemblyReference.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Archiver.Plugins 2 | { 3 | /// 4 | /// 5 | /// 6 | public interface IAssemblyReference 7 | { 8 | /// 9 | /// The fully qualified assembly name in the form "UtilityLibrary, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null" 10 | /// 11 | string FullName { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/INativeImageDescription.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Archiver.Plugins 2 | { 3 | public interface INativeImageDescription 4 | { 5 | /// 6 | /// The file name of the native image in the package. 7 | /// 8 | string EntryName { get; } 9 | 10 | /// 11 | /// The name of the native image, excluding its file extension. 12 | /// 13 | string ImageName { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/IPluginStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Archiver.Plugins 4 | { 5 | /// 6 | /// 7 | /// 8 | public interface IPluginStatus 9 | { 10 | /// 11 | /// 12 | /// 13 | bool IsInstalled { get; } 14 | 15 | /// 16 | /// 17 | /// 18 | bool IsLoaded { get; } 19 | 20 | /// 21 | /// 22 | /// 23 | Exception LoadException { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/IPluginWithDescription.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | using Tailviewer.Archiver.Plugins.Description; 3 | 4 | namespace Tailviewer.Archiver.Plugins 5 | { 6 | public interface IPluginWithDescription where T : class, IPlugin 7 | { 8 | T Plugin { get; } 9 | IPluginDescription Description { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/NativeImageDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Tailviewer.Archiver.Plugins 4 | { 5 | [DataContract] 6 | public sealed class NativeImageDescription 7 | : INativeImageDescription 8 | { 9 | /// 10 | [DataMember] 11 | public string EntryName { get; set; } 12 | 13 | /// 14 | [DataMember] 15 | public string ImageName { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/PluginInterfaceImplementation.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Tailviewer.Archiver.Plugins 4 | { 5 | [DataContract] 6 | public struct PluginInterfaceImplementation 7 | { 8 | [DataMember] 9 | public string InterfaceTypename { get; set; } 10 | 11 | [DataMember] 12 | public string ImplementationTypename { get; set; } 13 | 14 | /// 15 | /// The version of the interface at the time it was implemented. 16 | /// 17 | [DataMember] 18 | public int InterfaceVersion { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/PluginStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Archiver.Plugins 4 | { 5 | sealed class PluginStatus 6 | : IPluginStatus 7 | { 8 | public bool IsInstalled { get; set; } 9 | 10 | public bool IsLoaded { get; set; } 11 | 12 | public Exception LoadException { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/PluginWithDescription.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | using Tailviewer.Archiver.Plugins.Description; 3 | 4 | namespace Tailviewer.Archiver.Plugins 5 | { 6 | public sealed class PluginWithDescription 7 | : IPluginWithDescription 8 | where T : class, IPlugin 9 | { 10 | public T Plugin { get; } 11 | public IPluginDescription Description { get; } 12 | 13 | public PluginWithDescription(T plugin, IPluginDescription description) 14 | { 15 | Plugin = plugin; 16 | Description = description; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Plugins/SerializableTypeDescription.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace Tailviewer.Archiver.Plugins 4 | { 5 | [DataContract] 6 | public struct SerializableTypeDescription 7 | { 8 | /// 9 | /// The name with which the serializable type is referred to during (de)serialization. 10 | /// 11 | [DataMember] 12 | public string Name { get; set; } 13 | 14 | /// 15 | /// The full .NET name of the serializable type. 16 | /// 17 | [DataMember] 18 | public string FullName { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/Repository/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Archiver.Repository 2 | { 3 | public static class Constants 4 | { 5 | /// 6 | /// Identifier for the first version of the plugin registry. 7 | /// 8 | public static ulong PluginRepositoryV1Id = 1; 9 | 10 | /// 11 | /// The protocol used to communicate with a plugin repository. 12 | /// 13 | public static string Protocol = "tvpr"; 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer.Archiver/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Buffers/LogEntryBufferAccessorTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Tailviewer.Api; 3 | using Tailviewer.Core.Tests.Entries; 4 | 5 | namespace Tailviewer.Core.Tests.Buffers 6 | { 7 | [TestFixture] 8 | public sealed class LogEntryBufferAccessorTest 9 | : AbstractReadOnlyLogEntryTest 10 | { 11 | protected override IReadOnlyLogEntry CreateDefault() 12 | { 13 | // TODO: Swap 14 | var buffer = new LogBufferArray(1, Core.Columns.Minimum); 15 | return buffer[0]; 16 | } 17 | 18 | protected override IReadOnlyLogEntry CreateEmpty() 19 | { 20 | // TODO: Swap 21 | var buffer = new LogBufferArray(1); 22 | return buffer[0]; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Buffers/LogEntryListAccessorTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Tailviewer.Api; 3 | using Tailviewer.Core.Tests.Entries; 4 | 5 | namespace Tailviewer.Core.Tests.Buffers 6 | { 7 | [TestFixture] 8 | public sealed class LogEntryListAccessorTest 9 | : AbstractReadOnlyLogEntryTest 10 | { 11 | protected override IReadOnlyLogEntry CreateDefault() 12 | { 13 | // TODO: Swap 14 | var buffer = new LogBufferList(Core.Columns.Minimum); 15 | buffer.AddEmpty(); 16 | return buffer[0]; 17 | } 18 | 19 | protected override IReadOnlyLogEntry CreateEmpty() 20 | { 21 | // TODO: Swap 22 | var buffer = new LogBufferList(); 23 | buffer.AddEmpty(); 24 | return buffer[0]; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Entries/LogEntryTest2.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.Core.Tests.Entries 5 | { 6 | [TestFixture] 7 | public sealed class LogEntryTest2 8 | : AbstractLogEntryTest 9 | { 10 | #region Overrides of AbstractLogEntryTest 11 | 12 | public override ILogEntry CreateDefault() 13 | { 14 | return new LogEntry(); 15 | } 16 | 17 | public override ILogEntry CreateEmpty() 18 | { 19 | return new LogEntry(new IColumnDescriptor[0]); 20 | } 21 | 22 | public override ILogEntry Create(params IColumnDescriptor[] columns) 23 | { 24 | return new LogEntry(columns); 25 | } 26 | 27 | #endregion 28 | } 29 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Filters/AndFilterTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Core.Tests.Filters 4 | { 5 | [TestFixture] 6 | public sealed class AndFilterTest 7 | { 8 | [Test] 9 | public void TestCtor1() 10 | { 11 | 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Filters/FilterTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Core.Tests.Filters 4 | { 5 | [TestFixture] 6 | public sealed class FilterTest 7 | { 8 | [Test] 9 | public void TestCreate1() 10 | { 11 | 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Filters/LevelFilterTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Core.Tests.Filters 6 | { 7 | [TestFixture] 8 | public sealed class LevelFilterTest 9 | { 10 | [Test] 11 | public void TestToString() 12 | { 13 | new LevelFilter(LevelFlags.Debug).ToString().Should().Be("level == Debug"); 14 | new LevelFilter(LevelFlags.Debug | LevelFlags.Info).ToString().Should().Be("(level == Debug || Info)"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Filters/NoFilterTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | using Tailviewer.Api; 5 | 6 | namespace Tailviewer.Core.Tests.Filters 7 | { 8 | [TestFixture] 9 | public sealed class NoFilterTest 10 | { 11 | [Test] 12 | public void TestPassesFilter1() 13 | { 14 | var filter = new NoFilter(); 15 | filter.PassesFilter(new LogEntry()).Should().BeTrue(); 16 | filter.PassesFilter((IEnumerable) null).Should().BeTrue(); 17 | filter.PassesFilter(new LogEntry[0]).Should().BeTrue(); 18 | filter.PassesFilter(new[] {new LogEntry()}).Should().BeTrue(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Properties/ConcurrentPropertiesListTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using NUnit.Framework; 4 | using Tailviewer.Api; 5 | 6 | namespace Tailviewer.Core.Tests.Properties 7 | { 8 | [TestFixture] 9 | public sealed class ConcurrentPropertiesListTest 10 | : AbstractPropertiesBufferTest 11 | { 12 | #region Overrides of AbstractLogFilePropertiesTest 13 | 14 | protected override IPropertiesBuffer Create(params KeyValuePair[] properties) 15 | { 16 | var collection = new ConcurrentPropertiesList(properties.Select(x => x.Key)); 17 | foreach (var pair in properties) 18 | { 19 | collection.SetValue(pair.Key, pair.Value); 20 | } 21 | 22 | return collection; 23 | } 24 | 25 | #endregion 26 | } 27 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/Buffer/PageTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Core.Tests.Sources.Buffer 4 | { 5 | [TestFixture] 6 | public sealed class PageTest 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/Filtered/FilteredLogSourceTest2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading; 4 | using NUnit.Framework; 5 | using Tailviewer.Api; 6 | 7 | namespace Tailviewer.Core.Tests.Sources.Filtered 8 | { 9 | [TestFixture] 10 | public sealed class FilteredLogSourceTest2 11 | : AbstractTaskSchedulerLogFileTest 12 | { 13 | #region Overrides of AbstractTaskSchedulerLogFileTest 14 | 15 | protected override ILogSource CreateEmpty(IFilesystem filesystem, ITaskScheduler taskScheduler) 16 | { 17 | return new FilteredLogSource(taskScheduler, TimeSpan.Zero, new EmptyLogSource(), new WildcardFilter("*", true), 18 | null); 19 | } 20 | 21 | #endregion 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/Filtered/FilteredLogSourceTest3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using NUnit.Framework; 4 | using Tailviewer.Api; 5 | 6 | namespace Tailviewer.Core.Tests.Sources.Filtered 7 | { 8 | [TestFixture] 9 | public sealed class FilteredLogSourceTest3 10 | : AbstractAggregatedLogSourceTest 11 | { 12 | #region Overrides of AbstractAggregatedLogFileTest 13 | 14 | protected override ILogSource Create(ITaskScheduler taskScheduler, ILogSource source) 15 | { 16 | return new FilteredLogSource(taskScheduler, TimeSpan.Zero, source, null, Filter.Create(null, true, LevelFlags.Debug)); 17 | } 18 | 19 | #endregion 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/LogFileFormatsTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Core.Tests.Sources 4 | { 5 | [TestFixture] 6 | public sealed class LogFileFormatsTest 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/Merged/MergedLogSourceTest2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading; 4 | using NUnit.Framework; 5 | using Tailviewer.Api; 6 | 7 | namespace Tailviewer.Core.Tests.Sources.Merged 8 | { 9 | [TestFixture] 10 | public sealed class MergedLogSourceTest2 11 | : AbstractTaskSchedulerLogFileTest 12 | { 13 | #region Overrides of AbstractTaskSchedulerLogFileTest 14 | 15 | protected override ILogSource CreateEmpty(IFilesystem filesystem, ITaskScheduler taskScheduler) 16 | { 17 | return new MergedLogSource(taskScheduler, TimeSpan.Zero, new EmptyLogSource()); 18 | } 19 | 20 | #endregion 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/Merged/MergedLogSourceTest3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using NUnit.Framework; 4 | using Tailviewer.Api; 5 | 6 | namespace Tailviewer.Core.Tests.Sources.Merged 7 | { 8 | [TestFixture] 9 | public sealed class MergedLogSourceTest3 10 | : AbstractAggregatedLogSourceTest 11 | { 12 | #region Overrides of AbstractAggregatedLogFileTest 13 | 14 | protected override ILogSource Create(ITaskScheduler taskScheduler, ILogSource source) 15 | { 16 | return new MergedLogSource(taskScheduler, TimeSpan.Zero, source); 17 | } 18 | 19 | #endregion 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/MultiLine/MultiLineLogSourceTest2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading; 4 | using NUnit.Framework; 5 | using Tailviewer.Api; 6 | 7 | namespace Tailviewer.Core.Tests.Sources.MultiLine 8 | { 9 | [TestFixture] 10 | public sealed class MultiLineLogSourceTest2 11 | : AbstractTaskSchedulerLogFileTest 12 | { 13 | #region Overrides of AbstractTaskSchedulerLogFileTest 14 | 15 | protected override ILogSource CreateEmpty(IFilesystem filesystem, ITaskScheduler taskScheduler) 16 | { 17 | return new MultiLineLogSource(taskScheduler, new EmptyLogSource(), TimeSpan.Zero); 18 | } 19 | 20 | #endregion 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/MultiLine/MultiLineLogSourceTest3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using NUnit.Framework; 4 | using Tailviewer.Api; 5 | 6 | namespace Tailviewer.Core.Tests.Sources.MultiLine 7 | { 8 | [TestFixture] 9 | public sealed class MultiLineLogSourceTest3 10 | : AbstractAggregatedLogSourceTest 11 | { 12 | #region Overrides of AbstractAggregatedLogFileTest 13 | 14 | protected override ILogSource Create(ITaskScheduler taskScheduler, ILogSource source) 15 | { 16 | return new MultiLineLogSource(taskScheduler, source, TimeSpan.Zero); 17 | } 18 | 19 | #endregion 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/Sources/Proxy/LogSourceProxyTest2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Threading; 4 | using NUnit.Framework; 5 | using Tailviewer.Api; 6 | 7 | namespace Tailviewer.Core.Tests.Sources.Proxy 8 | { 9 | [TestFixture] 10 | public sealed class LogSourceProxyTest2 11 | : AbstractTaskSchedulerLogFileTest 12 | { 13 | #region Overrides of AbstractTaskSchedulerLogFileTest 14 | 15 | protected override ILogSource CreateEmpty(IFilesystem filesystem, ITaskScheduler taskScheduler) 16 | { 17 | return new LogSourceProxy(taskScheduler, TimeSpan.Zero); 18 | } 19 | 20 | #endregion 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Tailviewer.Core.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Tailviewer.Core/AssemblyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | 5 | namespace Tailviewer.Core 6 | { 7 | /// 8 | /// Extension methods for the class. 9 | /// 10 | public static class AssemblyExtensions 11 | { 12 | /// 13 | /// Returns the folder this assembly is located in. 14 | /// 15 | /// 16 | /// 17 | public static string GetFolder(this Assembly assembly) 18 | { 19 | var codeBase = assembly.CodeBase; 20 | var uri = new UriBuilder(codeBase); 21 | var path = Uri.UnescapeDataString(uri.Path); 22 | return Path.GetDirectoryName(path); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Tailviewer.Core/Comparers/LevelFlagsComparer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Tailviewer.Api; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace Tailviewer.Core 6 | { 7 | internal sealed class LevelFlagsComparer 8 | : IEqualityComparer 9 | { 10 | #region Implementation of IEqualityComparer 11 | 12 | public bool Equals(LevelFlags x, LevelFlags y) 13 | { 14 | return x == y; 15 | } 16 | 17 | public int GetHashCode(LevelFlags obj) 18 | { 19 | return obj.GetHashCode(); 20 | } 21 | 22 | #endregion 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/DisposableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using log4net; 4 | 5 | namespace Tailviewer.Core 6 | { 7 | internal static class DisposableExtensions 8 | { 9 | private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 10 | 11 | public static void TryDispose(this IDisposable that) 12 | { 13 | try 14 | { 15 | that.Dispose(); 16 | } 17 | catch (Exception e) 18 | { 19 | Log.WarnFormat("Caught unexpected exception: {0}", e); 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.Core 4 | { 5 | /// 6 | /// 7 | /// 8 | /// 9 | public static class EnumerableExtensions 10 | { 11 | /// 12 | /// 13 | /// 14 | public static readonly IReadOnlyList Empty; 15 | 16 | static EnumerableExtensions() 17 | { 18 | Empty = new List(); 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/BinaryOperation.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Core.Filters.ExpressionEngine 2 | { 3 | internal enum BinaryOperation 4 | { 5 | And, 6 | Or, 7 | Contains, 8 | Is, 9 | LessThan, 10 | LessOrEquals, 11 | GreaterThan, 12 | GreaterOrEquals 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/DateTimeLiteral.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Core.Filters.ExpressionEngine 6 | { 7 | internal sealed class DateTimeLiteral 8 | : IExpression 9 | { 10 | private readonly DateTime? _value; 11 | 12 | public DateTimeLiteral(DateTime? value) 13 | { 14 | _value = value; 15 | } 16 | 17 | #region Implementation of IExpression 18 | 19 | public Type ResultType => typeof(DateTime?); 20 | 21 | public DateTime? Evaluate(IReadOnlyList logEntry) 22 | { 23 | return _value; 24 | } 25 | 26 | object IExpression.Evaluate(IReadOnlyList logEntry) 27 | { 28 | return Evaluate(logEntry); 29 | } 30 | 31 | #endregion 32 | } 33 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/IInterval.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Core.Filters.ExpressionEngine 2 | { 3 | internal interface IInterval 4 | { 5 | T Minimum { get; } 6 | T Maximum { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/Interval.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Core.Filters.ExpressionEngine 2 | { 3 | internal sealed class Interval 4 | : IInterval 5 | { 6 | private readonly T _minimum; 7 | private readonly T _maximum; 8 | 9 | public Interval(T minimum, T maximum) 10 | { 11 | _minimum = minimum; 12 | _maximum = maximum; 13 | } 14 | 15 | #region Implementation of IInterval 16 | 17 | public T Minimum => _minimum; 18 | 19 | public T Maximum => _maximum; 20 | 21 | #endregion 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/ParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Core.Filters.ExpressionEngine 4 | { 5 | /// 6 | /// 7 | /// 8 | internal sealed class ParseException 9 | : Exception 10 | { 11 | /// 12 | /// 13 | /// 14 | public ParseException() 15 | {} 16 | 17 | /// 18 | /// 19 | /// 20 | /// 21 | public ParseException(string message) 22 | : base(message) 23 | { 24 | } 25 | 26 | /// 27 | /// 28 | /// 29 | /// 30 | /// 31 | public ParseException(string message, Exception inner) 32 | : base(message, inner) 33 | { 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/TokenOrExpression.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Core.Filters.ExpressionEngine 2 | { 3 | internal struct TokenOrExpression 4 | { 5 | public readonly Token Token; 6 | public readonly IExpression Expression; 7 | 8 | public TokenOrExpression(Token token) 9 | { 10 | Token = token; 11 | Expression = null; 12 | } 13 | 14 | public override string ToString() 15 | { 16 | if (Expression != null) 17 | { 18 | return Expression.ToString(); 19 | } 20 | 21 | return Token.ToString(); 22 | } 23 | 24 | public static implicit operator TokenOrExpression(Token token) 25 | { 26 | return new TokenOrExpression(token); 27 | } 28 | 29 | public TokenOrExpression(IExpression expression) 30 | { 31 | Token = default(Token); 32 | Expression = expression; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/TokenType.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Core.Filters.ExpressionEngine 2 | { 3 | internal enum TokenType 4 | { 5 | Invalid = 0, 6 | 7 | Whitespace, 8 | 9 | OpenBracket, 10 | CloseBracket, 11 | 12 | #region Binary Operators 13 | Equals, 14 | NotEquals, 15 | LessThan, 16 | LessOrEquals, 17 | GreaterThan, 18 | GreaterOrEquals, 19 | And, 20 | Or, 21 | Contains, 22 | Is, 23 | #endregion 24 | 25 | #region Unary Operators 26 | Not, 27 | #endregion 28 | 29 | Quotation, 30 | BackwardSlash, 31 | Dollar, 32 | Literal, 33 | True, 34 | False 35 | } 36 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Filters/ExpressionEngine/UnaryOperation.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Core.Filters.ExpressionEngine 2 | { 3 | internal enum UnaryOperation 4 | { 5 | Not 6 | } 7 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Properties/IWellKnownReadOnlyPropertyDescriptor.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Core 3 | { 4 | /// 5 | /// Tags interface to quickly tell Tailviewer's properties from others. 6 | /// 7 | internal interface IWellKnownReadOnlyPropertyDescriptor 8 | { 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Properties/WellKnownProperty.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Tailviewer.Api; 3 | 4 | // ReSharper disable once CheckNamespace 5 | namespace Tailviewer.Core 6 | { 7 | /// 8 | /// A property which is well-known by Tailviewer and can be changed by the user. 9 | /// 10 | /// 11 | internal sealed class WellKnownProperty 12 | : WellKnownReadOnlyProperty 13 | , IPropertyDescriptor 14 | { 15 | public WellKnownProperty(string id, T defaultValue = default) 16 | : base(new []{id}, defaultValue) 17 | {} 18 | 19 | public WellKnownProperty(IEnumerable path, T defaultValue = default) 20 | : base(path, defaultValue) 21 | {} 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/QueueExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.Core 4 | { 5 | /// 6 | /// Provides extension methods for the class. 7 | /// 8 | public static class QueueExtensions 9 | { 10 | /// 11 | /// Tries to dequeue the next value from this queue. 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// true when a value could be dequeued, false otherwise 17 | public static bool TryDequeue(this Queue queue, out T value) 18 | { 19 | if (queue.Count > 0) 20 | { 21 | value = queue.Dequeue(); 22 | return true; 23 | } 24 | 25 | value = default(T); 26 | return false; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Settings/QuickFilterActionType.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Core 3 | { 4 | /// 5 | /// Defines how a quick filter is to be applied. 6 | /// 7 | public enum QuickFilterActionType 8 | { 9 | /// 10 | /// Only lines which match the filter are included. 11 | /// 12 | Include = 0, 13 | 14 | /// 15 | /// Only lines which do NOT match the filter are included. 16 | /// 17 | Exclude = 1, 18 | 19 | /// 20 | /// Lines which match the filter have the matching string colored. 21 | /// 22 | Color = 2 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Settings/SpecialDateTimeInterval.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Core 3 | { 4 | /// 5 | /// 6 | /// 7 | public enum SpecialDateTimeInterval 8 | { 9 | /// 10 | /// 11 | /// 12 | Today, 13 | 14 | /// 15 | /// 16 | /// 17 | ThisWeek, 18 | 19 | /// 20 | /// 21 | /// 22 | ThisMonth, 23 | 24 | /// 25 | /// 26 | /// 27 | ThisYear, 28 | 29 | /// 30 | /// 31 | /// 32 | Last24Hours, 33 | 34 | /// 35 | /// 36 | /// 37 | Last7Days, 38 | 39 | /// 40 | /// 41 | /// 42 | Last30Days, 43 | 44 | /// 45 | /// 46 | /// 47 | Last365Days 48 | } 49 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Settings/TimeFilterMode.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Core 3 | { 4 | /// 5 | /// 6 | public enum TimeFilterMode 7 | { 8 | /// 9 | /// Do not filter by time (i.e. every log event passes the filter). 10 | /// 11 | Everything, 12 | 13 | /// 14 | /// Filter using the specified special interval (e.g. today, this week, etc...) 15 | /// 16 | SpecialInterval, 17 | 18 | /// 19 | /// Filter using the specified custom interval (e.g. from A to B) 20 | /// 21 | Interval 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Sources/Buffer/RetrievalState.cs: -------------------------------------------------------------------------------- 1 | // ReSharper disable once CheckNamespace 2 | namespace Tailviewer.Core 3 | { 4 | /// 5 | /// Describes if a log entry was retrieved from a column or not. 6 | /// 7 | internal enum RetrievalState : byte 8 | { 9 | /// 10 | /// The requested data wasn't retrieved because it isn't part of the source. 11 | /// 12 | NotInSource = 0, 13 | 14 | /// 15 | /// The requested data wasn't retrieved because it wasn't cached. 16 | /// 17 | NotCached = 1, 18 | 19 | /// 20 | /// THe requested data was retrieved. 21 | /// 22 | Retrieved = 2 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Sources/ListenerProxy.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace Tailviewer.Core 5 | { 6 | internal sealed class ListenerProxy 7 | : ILogSourceListener 8 | { 9 | private readonly ILogSourceListener _listener; 10 | private readonly ILogSource _source; 11 | 12 | public ListenerProxy(ILogSource source, ILogSourceListener listener) 13 | { 14 | _source = source; 15 | _listener = listener; 16 | } 17 | 18 | 19 | #region Implementation of ILogSourceListener 20 | 21 | public void OnLogFileModified(ILogSource logSource, LogSourceModification modification) 22 | { 23 | _listener.OnLogFileModified(_source, modification); 24 | } 25 | 26 | #endregion 27 | } 28 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Sources/Merged/MergedLogLineIndexComparer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace Tailviewer.Core 5 | { 6 | internal sealed class MergedLogLineIndexComparer 7 | : IComparer 8 | { 9 | #region Implementation of IComparer 10 | 11 | public int Compare(MergedLogLineIndex x, MergedLogLineIndex y) 12 | { 13 | return x.Timestamp.CompareTo(y.Timestamp); 14 | } 15 | 16 | #endregion 17 | } 18 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/Sources/Text/FileLogSourceFactory.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | 3 | // ReSharper disable once CheckNamespace 4 | namespace Tailviewer.Core 5 | { 6 | /// 7 | /// 8 | /// 9 | public static class FileLogSourceFactory 10 | { 11 | /// 12 | /// 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static ILogSource OpenRead(IServiceContainer services, string fileName) 18 | { 19 | return new FileLogSource(services, fileName); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.Core/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Tailviewer.Core/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Service/Program.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceProcess; 2 | 3 | namespace Tailviewer.PluginRepository.Service 4 | { 5 | static class Program 6 | { 7 | /// 8 | /// The main entry point for the application. 9 | /// 10 | static void Main() 11 | { 12 | Logging.SetupFileAppender(Constants.ServiceLogFile); 13 | Logging.InstallExceptionHandlers(); 14 | 15 | ServiceBase[] ServicesToRun; 16 | ServicesToRun = new ServiceBase[] 17 | { 18 | new Service1() 19 | }; 20 | ServiceBase.Run(ServicesToRun); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Service/delete_service.cmd: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | 4 | call set_environment.cmd 5 | call require_admin.cmd || exit /b 1 6 | 7 | call stop_service.cmd 8 | 9 | sc delete "%ServiceName%" > nul 2>&1 10 | set ret=%errorlevel% 11 | if %ret% == 1060 goto :NOTCREATED 12 | if %ret% == 0 goto :SUCCESS 13 | goto :ERROR 14 | 15 | :NOTCREATED 16 | echo Service "%ServiceName%" doesn't exist, nothing needs to be done 17 | exit /b 0 18 | 19 | :ERROR 20 | echo Error: Unable to delete service "%ServiceName%" 21 | echo sc returned %ret% 22 | net helpmsg %ret% 23 | exit /b %ret% 24 | 25 | :SUCCESS 26 | echo Service "%servicename%" deleted 27 | exit /b 0 28 | 29 | endlocal 30 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Service/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Service/require_admin.cmd: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | 4 | net session >nul 2>&1 5 | if not %errorLevel% == 0 goto :NOADMIN 6 | goto :SUCCESS 7 | 8 | :NOADMIN 9 | echo This script requires administrator privileges to run! 10 | echo Please run your shell (cmd, powershell, etc..) as administrator and retry. 11 | exit /b -1 12 | 13 | :SUCCESS 14 | exit /b 15 | 16 | endlocal 17 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Service/set_environment.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | rem We do not use setlocal here because we want these variables to be available to callers 3 | 4 | set ServiceName=Tailviewer.PluginRepository 5 | set ScriptDir=%~dp0 6 | set ServicePath=%ScriptDir%repository-svc.exe 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Service/stop_service.cmd: -------------------------------------------------------------------------------- 1 | @setlocal 2 | @echo off 3 | 4 | call set_environment.cmd 5 | 6 | sc stop "%ServiceName%" > nul 2>&1 7 | set ret=%errorlevel% 8 | 9 | rem The service isn't installed 10 | if %ret% == 1060 goto :NOTINSTALLED 11 | if %ret% == 1062 goto :NOTRUNNING 12 | if %ret% == 0 goto :SUCCESS 13 | goto :ERROR 14 | 15 | :NOTINSTALLED 16 | echo Service "%ServiceName%" isn't installed, nothing needs to be done 17 | exit /b 0 18 | 19 | :NOTRUNNING 20 | echo Service "%ServiceName%" isn't running, nothing needs to be done 21 | exit /b 0 22 | 23 | :ERROR 24 | echo Error: Unable to stop service "%ServiceName%" 25 | echo sc returned %ret% 26 | net helpmsg %ret% 27 | exit /b %ret% 28 | 29 | :SUCCESS 30 | echo Service "%servicename%" stopped 31 | exit /b 0 32 | 33 | endlocal 34 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository.Tests/IPEndPointExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | using Tailviewer.PluginRepository.Applications; 5 | 6 | namespace Tailviewer.PluginRepository.Tests 7 | { 8 | [TestFixture] 9 | public sealed class IpEndPointExtensionsTest 10 | { 11 | [Test] 12 | public void TestParseIpv6() 13 | { 14 | IPEndPointExtensions.Parse("[::]:80") 15 | .Should().Be(new IPEndPoint(IPAddress.IPv6Any, 80)); 16 | } 17 | 18 | [Test] 19 | public void TestParseIpv4() 20 | { 21 | IPEndPointExtensions.Parse("1.2.3.4:5342") 22 | .Should().Be(new IPEndPoint(IPAddress.Parse("1.2.3.4"), 5342)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/ExportOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("export", HelpText = "Exports the entire database into the given file")] 6 | public sealed class ExportOptions 7 | { 8 | [Value(0, MetaName = "Export folder", 9 | HelpText = "The folder the database should be exported to", 10 | Required = true)] 11 | public string ExportFolder { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/IApplication.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | public interface IApplication 6 | { 7 | bool RequiresRepository { get; } 8 | 9 | bool ReadOnlyRepository { get; } 10 | 11 | ExitCode Run(IFilesystem filesystem, IInternalPluginRepository repository, T options); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/IPEndPointExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | public static class IPEndPointExtensions 6 | { 7 | public static IPEndPoint Parse(string address) 8 | { 9 | var idx = address.LastIndexOf(':'); 10 | var ipAddress = IPAddress.Parse(address.Substring(0, idx)); 11 | var port = int.Parse(address.Substring(idx+1)); 12 | return new IPEndPoint(ipAddress, port); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/ListPlugins.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace Tailviewer.PluginRepository.Applications 5 | { 6 | public sealed class ListPlugins 7 | : IApplication 8 | { 9 | public bool RequiresRepository => true; 10 | 11 | public bool ReadOnlyRepository => true; 12 | 13 | public ExitCode Run(IFilesystem filesystem, IInternalPluginRepository repository, ListPluginsOptions options) 14 | { 15 | foreach (var plugin in repository.FindAllPlugins()) 16 | { 17 | Console.WriteLine("\t{0}", plugin); 18 | } 19 | 20 | return ExitCode.Success; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/ListPluginsOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("list-plugins", HelpText = "List plugins of this repository")] 6 | public sealed class ListPluginsOptions 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/ListUsersOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("list-users", HelpText = "List the users who are allowed to push new plugins from remote locations")] 6 | public sealed class ListUsersOptions 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/RemovePluginOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("remove-plugin", HelpText = "Remove a plugin from this repository")] 6 | public sealed class RemovePluginOptions 7 | { 8 | [Value(0, MetaName = "plugin id", 9 | HelpText = "The id of the plugin to remove, for example Tailviewer.Analysis.Count", 10 | Required = true)] 11 | public string Id { get; set; } 12 | 13 | [Option('v', "version", 14 | Default = null, 15 | HelpText = "The specific version of the plugin to remove, for example 0.1.2", 16 | Required = true)] 17 | public string Version { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/RemoveUserOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("remove-user", HelpText = "Remove a previously added user from the repository")] 6 | public sealed class RemoveUserOptions 7 | { 8 | [Value(0, MetaName = "user name", 9 | HelpText = "The user name of the user to remove from the repository", 10 | Required = true)] 11 | public string Username { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/RunServerOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("run", HelpText = "Run the repository server and serve requests to tailviewer clients")] 6 | public sealed class RunServerOptions 7 | { 8 | [Option("allow-remote-publish", 9 | Default = null, 10 | HelpText = "Allow remote publishing via archive.exe. This setting overwrites the value specified in the configuration file.")] 11 | public bool? AllowRemotePublish { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Applications/WriteConfigurationOptions.cs: -------------------------------------------------------------------------------- 1 | using CommandLine; 2 | 3 | namespace Tailviewer.PluginRepository.Applications 4 | { 5 | [Verb("write-configuration", HelpText = "Writes an example configuration to disk which can be used with the run verb")] 6 | public sealed class WriteConfigurationOptions 7 | { 8 | [Value(0, MetaName = "filename", 9 | Default = "configuration.xml", 10 | HelpText = "The filename where the configuration should be stored")] 11 | public string Filename { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.PluginRepository 4 | { 5 | public static class Bootstrapper 6 | { 7 | public static int Main(string[] args) 8 | { 9 | try 10 | { 11 | return App.Run(args); 12 | } 13 | catch (Exception e) 14 | { 15 | // We don't use log4net here because we might not have been able to load the assembly and therefore 16 | // would crash even harder if we were to throw here 17 | Console.WriteLine("Exiting due to unexpected exception: {0}", e); 18 | return -1; 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Entities/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace Tailviewer.PluginRepository.Entities 5 | { 6 | [DataContract] 7 | public sealed class User 8 | { 9 | [DataMember] 10 | public string Username { get; set; } 11 | 12 | [DataMember] 13 | public string Email { get; set; } 14 | 15 | [DataMember] 16 | public Guid AccessToken { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Exceptions/CannotAddUserException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.PluginRepository.Exceptions 4 | { 5 | public sealed class CannotAddUserException 6 | : Exception 7 | { 8 | public bool IsError { get; } 9 | 10 | public CannotAddUserException(string message, bool isError = true) 11 | : base(message) 12 | { 13 | IsError = isError; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Exceptions/CannotRemovePluginException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.PluginRepository.Exceptions 4 | { 5 | public class CannotRemovePluginException 6 | : Exception 7 | { 8 | public CannotRemovePluginException(string message) 9 | : base(message) 10 | { } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Exceptions/CannotRemoveUserException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.PluginRepository.Exceptions 4 | { 5 | public sealed class CannotRemoveUserException 6 | : Exception 7 | { 8 | public CannotRemoveUserException(string message) 9 | : base(message) 10 | { } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/ExitCode.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.PluginRepository 2 | { 3 | public enum ExitCode 4 | { 5 | Success = 0, 6 | 7 | GenericFailure = -1, 8 | 9 | InvalidUserName = -10, 10 | InvalidUserToken = -12, 11 | 12 | FileNotFound = -20, 13 | DirectoryNotFound = -21, 14 | 15 | InvalidAddress = -30, 16 | 17 | UnhandledException = int.MinValue 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/IInternalPluginRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Tailviewer.Archiver.Repository; 4 | using Tailviewer.PluginRepository.Entities; 5 | 6 | namespace Tailviewer.PluginRepository 7 | { 8 | public interface IInternalPluginRepository 9 | : IPluginRepository 10 | { 11 | Guid AddUser(string username, string email, string accessToken); 12 | void RemoveUser(string username); 13 | IEnumerable GetAllUsers(); 14 | bool TryGetAccessToken(string username, out Guid accessToken); 15 | 16 | void PublishPlugin(byte[] plugin, string accessToken, string publishTimestamp); 17 | long CountPlugins(); 18 | void RemovePlugin(string id, string version); 19 | IReadOnlyList GetAllPlugins(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tailviewer.PluginRepository/Server.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using SharpRemote; 4 | using Tailviewer.Archiver.Repository; 5 | 6 | namespace Tailviewer.PluginRepository 7 | { 8 | public sealed class Server 9 | : IDisposable 10 | { 11 | private readonly SocketServer _socket; 12 | private readonly IPluginRepository _repository; 13 | 14 | public Server(IPEndPoint endPoint, IPluginRepository repository) 15 | { 16 | _repository = repository; 17 | 18 | _socket = new SocketServer($"{Constants.ApplicationTitle} Socket"); 19 | _socket.RegisterSubject(Archiver.Repository.Constants.PluginRepositoryV1Id, _repository); 20 | _socket.Bind(endPoint); 21 | } 22 | 23 | #region IDisposable 24 | 25 | public void Dispose() 26 | { 27 | _socket?.Dispose(); 28 | } 29 | 30 | #endregion 31 | } 32 | } -------------------------------------------------------------------------------- /src/Tailviewer.System.Tests/AssemblySetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using NUnit.Framework; 5 | 6 | namespace Tailviewer.SystemTests 7 | { 8 | [SetUpFixture] 9 | public sealed class AssemblySetup 10 | { 11 | [OneTimeSetUp] 12 | public void SetUp() 13 | { 14 | Directory.SetCurrentDirectory(AssemblyDirectory); 15 | } 16 | 17 | public static string AssemblyDirectory 18 | { 19 | get 20 | { 21 | string codeBase = Assembly.GetExecutingAssembly().CodeBase; 22 | UriBuilder uri = new UriBuilder(codeBase); 23 | string path = Uri.UnescapeDataString(uri.Path); 24 | return Path.GetDirectoryName(path); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Tailviewer.System.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Tailviewer.System.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/ArrayExtensionsTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Core; 4 | 5 | namespace Tailviewer.Tests 6 | { 7 | [TestFixture] 8 | public sealed class ArrayExtensionsTest 9 | { 10 | [Test] 11 | public void TestStartsWith() 12 | { 13 | ArrayExtensions.StartsWith(new byte[] {1}, new byte[] {2}).Should().BeFalse(); 14 | ArrayExtensions.StartsWith(new byte[] {1}, new byte[] {1, 2}).Should().BeFalse(); 15 | ArrayExtensions.StartsWith(new byte[] {2}, new byte[] {1, 2}).Should().BeFalse(); 16 | ArrayExtensions.StartsWith(new byte[] {2, 1}, new byte[] {2}).Should().BeTrue(); 17 | ArrayExtensions.StartsWith(new byte[] {2}, new byte[] {2}).Should().BeTrue(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/AssemblySetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | using NUnit.Framework; 5 | 6 | namespace Tailviewer.Tests 7 | { 8 | [SetUpFixture] 9 | [Parallelizable(ParallelScope.Fixtures)] 10 | public sealed class AssemblySetup 11 | { 12 | [OneTimeSetUp] 13 | public void SetUp() 14 | { 15 | Directory.SetCurrentDirectory(AssemblyDirectory); 16 | } 17 | 18 | public static string AssemblyDirectory 19 | { 20 | get 21 | { 22 | string codeBase = Assembly.GetExecutingAssembly().CodeBase; 23 | UriBuilder uri = new UriBuilder(codeBase); 24 | string path = Uri.UnescapeDataString(uri.Path); 25 | return Path.GetDirectoryName(path); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/BusinessLogic/Highlighters/HighlighterTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.BusinessLogic.Highlighters; 4 | using Tailviewer.Core; 5 | 6 | namespace Tailviewer.Tests.BusinessLogic.Highlighters 7 | { 8 | [TestFixture] 9 | public sealed class HighlighterTest 10 | { 11 | [Test] 12 | public void TestCtor() 13 | { 14 | var highlighter = new Highlighter(); 15 | highlighter.Id.Should().NotBe(HighlighterId.Empty); 16 | highlighter.Value.Should().BeNullOrEmpty(); 17 | highlighter.MatchType.Should().Be(FilterMatchType.SubstringFilter); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/BusinessLogic/Plugins/LogFileFormatMatcherPluginTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Tests.BusinessLogic.Plugins 6 | { 7 | [TestFixture] 8 | public sealed class LogFileFormatMatcherPluginTest 9 | { 10 | [Test] 11 | public void TestFileFormatPluginVersion() 12 | { 13 | PluginInterfaceVersionAttribute.GetInterfaceVersion(typeof(ILogFileFormatMatcherPlugin)).Should().Be(new PluginInterfaceVersion(1), "because this interface hasn't been modified yet"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/BusinessLogic/Plugins/LogFileIssuesPluginTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Tests.BusinessLogic.Plugins 6 | { 7 | [TestFixture] 8 | public sealed class LogFileIssuesPluginTest 9 | { 10 | [Test] 11 | public void TestFileFormatPluginVersion() 12 | { 13 | PluginInterfaceVersionAttribute.GetInterfaceVersion(typeof(ILogFileIssuesPlugin)).Should().Be(new PluginInterfaceVersion(3), "because this interface has been broken twice"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/BusinessLogic/Plugins/LogFileOutlinePluginTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Tests.BusinessLogic.Plugins 6 | { 7 | [TestFixture] 8 | public sealed class LogFileOutlinePluginTest 9 | { 10 | [Test] 11 | public void TestFileFormatPluginVersion() 12 | { 13 | PluginInterfaceVersionAttribute.GetInterfaceVersion(typeof(ILogFileOutlinePlugin)).Should().Be(new PluginInterfaceVersion(2), "because this interface has been broken once"); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/BusinessLogic/Plugins/PluginInterfaceVersionTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Tests.BusinessLogic.Plugins 6 | { 7 | [TestFixture] 8 | public sealed class PluginInterfaceVersionTest 9 | { 10 | [Test] 11 | public void TestEquality() 12 | { 13 | new PluginInterfaceVersion(1).Should().Be(new PluginInterfaceVersion(1)); 14 | new PluginInterfaceVersion(1).Should().Be(PluginInterfaceVersion.First); 15 | } 16 | 17 | [Test] 18 | public void TestInequality() 19 | { 20 | new PluginInterfaceVersion(1).Should().NotBe(new PluginInterfaceVersion(2)); 21 | new PluginInterfaceVersion(2).Should().NotBe(new PluginInterfaceVersion(3)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/BusinessLogic/Sources/Text/GenericTextLogSourceTest.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | namespace Tailviewer.Tests.BusinessLogic.Sources.Text 4 | { 5 | [TestFixture] 6 | public sealed class GenericTextLogSourceTest 7 | { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/EnhancementAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Tests 4 | { 5 | [AttributeUsage(AttributeTargets.Method)] 6 | public sealed class EnhancementAttribute 7 | : Attribute 8 | { 9 | public EnhancementAttribute(string ticketUri) 10 | { 11 | TicketUri = ticketUri; 12 | } 13 | 14 | public string TicketUri { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/SerializableTypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text; 3 | using Tailviewer.Api; 4 | 5 | namespace Tailviewer.Tests 6 | { 7 | public static class SerializableTypeExtensions 8 | { 9 | private static string Format(MemoryStream stream) where T : class, ISerializableType 10 | { 11 | using (var tmp = new StreamReader(stream, Encoding.UTF8, true, 4096, true)) 12 | { 13 | return tmp.ReadToEnd(); 14 | } 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/Settings/TextSettingsTest.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using NUnit.Framework; 3 | using Tailviewer.Settings; 4 | 5 | namespace Tailviewer.Tests.Settings 6 | { 7 | [TestFixture] 8 | public sealed class TextSettingsTest 9 | { 10 | [Test] 11 | public void TestDefault() 12 | { 13 | TextSettings.Default.FontSize.Should().Be(12); 14 | TextSettings.Default.LineSpacing.Should().Be(3); 15 | TextSettings.Default.LineHeight.Should().Be(15); 16 | TextSettings.Default.LineNumberSpacing.Should().Be(5); 17 | TextSettings.Default.Typeface.Should().NotBeNull(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/Settings/settings_no_file_guid.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/SimpleLogEntryParserPlugin.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Tailviewer.Api; 4 | using Tailviewer.Core; 5 | 6 | namespace Tailviewer.Tests 7 | { 8 | public class SimpleLogEntryParserPlugin 9 | : ILogEntryParserPlugin 10 | { 11 | #region Implementation of ITextLogFileParserPlugin 12 | 13 | public IReadOnlyList SupportedFormats 14 | { 15 | get { throw new NotImplementedException(); } 16 | } 17 | 18 | public ILogEntryParser CreateParser(IServiceContainer services, ILogFileFormat format) 19 | { 20 | ITimestampParser timestampParser = services.TryRetrieve() ?? new TimestampParser(); 21 | return new GenericTextLogEntryParser(timestampParser); 22 | } 23 | 24 | #endregion 25 | } 26 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/1Line.txt: -------------------------------------------------------------------------------- 1 | [00:00:01] git clone -q --branch=master https://github.com/Kittyfisto/SharpRemote.git C:\projects\sharpremote -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/1Line_WithNewline.txt: -------------------------------------------------------------------------------- 1 | [00:00:01] git clone -q --branch=master https://github.com/Kittyfisto/SharpRemote.git C:\projects\sharpremote -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/2Lines.txt: -------------------------------------------------------------------------------- 1 | 2015-10-07 19:50:58,981 [8092, 1] INFO SharpRemote.Hosting.OutOfProcessSiloServer (null) - Silo Server starting, args (1): "14056", without custom type resolver 2 | 2015-10-07 19:50:58,997 [8092, 1] DEBUG SharpRemote.Hosting.OutOfProcessSiloServer (null) - Args.Length: 1 3 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/2LogEntries.txt: -------------------------------------------------------------------------------- 1 | 2015-10-07 19:50:58,982 [8092, 1] INFO SharpRemote.Hosting.OutOfProcessSiloServer (null) - Silo Server starting, args (1): "14056", without custom type resolver 2 | Foobar 3 | Some more info 4 | 2015-10-07 19:50:58,998 [8092, 1] DEBUG SharpRemote.Hosting.OutOfProcessSiloServer (null) - Args.Length: 1 5 | Hey look at me 6 | dwadawdadw 7 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/3LogEntries.txt: -------------------------------------------------------------------------------- 1 | 2015-10-07 19:50:58,982 [8092, 1] INFO SharpRemote.Hosting.OutOfProcessSiloServer (null) - Silo Server starting, args (1): "14056", without custom type resolver 2 | Foobar 3 | Some more info 4 | 2015-10-07 19:50:58,998 [8092, 1] DEBUG SharpRemote.Hosting.OutOfProcessSiloServer (null) - Args.Length: 1 5 | Hey look at me 6 | dwadawdadw 7 | 2015-12-08 10:14:53,860 [ 1] WARN ServiceRepository WPF Sample: Adding service Service: RohdeSchwarz.Tools.Plugins.IPluginFactory (PluginFactory) = Active 8 | Additional information 9 | Yes! 10 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/DifferentLevels.txt: -------------------------------------------------------------------------------- 1 | DEBUG ERROR WARN FATAL INFO 2 | INFO DEBUG ERROR WARN FATAL 3 | WARN ERROR FATAL INFO DEBUG 4 | ERROR INFO DEBUG FATAL WARN 5 | FATAL ERROR INFO WARN DEBUG 6 | fatal error info warn debug -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Empty.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Tests/TestData/Empty.txt -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Encodings/utf16_be_bom.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Tests/TestData/Encodings/utf16_be_bom.txt -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Encodings/utf16_le_bom.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Tests/TestData/Encodings/utf16_le_bom.txt -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Encodings/utf8_w_bom.txt: -------------------------------------------------------------------------------- 1 | 2015-10-07 19:50:58,997 [8092, 1] DEBUG SharpRemote.Hosting.OutOfProcessSiloServer (null) - Args.Length: 1 -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Encodings/windows_1252.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Tests/TestData/Encodings/windows_1252.txt -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/LevelCounts.txt: -------------------------------------------------------------------------------- 1 | DEBUG 2 | INFO 3 | INFO 4 | WARN 5 | WARN 6 | WARN 7 | ERROR 8 | ERROR 9 | ERROR 10 | ERROR 11 | FATAL 12 | FATAL 13 | FATAL 14 | FATAL 15 | TRACE 16 | FATAL 17 | TRACE 18 | TRACE 19 | TRACE 20 | TRACE 21 | TRACE 22 | other 23 | other 24 | other 25 | other 26 | other 27 | other -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Multiline/Log1.txt: -------------------------------------------------------------------------------- 1 | 2019-03-18 14:09:54:177 1 00:00:00:0000000 Information Initialize Globals 2 | Started BTPVM3372 05:30:00 6060 3 | 2019-03-18 14:09:54:313 1 00:00:00:0000000 Information Loading 4 | preferences Started BTPVM3372 05:30:00 6060 5 | 2019-03-18 14:09:54:551 1 00:00:00:0000000 Information RMClientURL: 6 | BTPVM3372 05:30:00 6060 -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Multiline/Log2.txt: -------------------------------------------------------------------------------- 1 | 18/03/2019 14:09:54:176 1 Information BTPVM3372 05:30:00 6060 2 | 18/03/2019 14:09:54:178 1 Information Loading preferences Started 3 | BTPVM3372 05:30:00 6060 4 | 18/03/2019 14:09:54:550 1 Information RMClientURL: BTPVM3372 05:30:00 5 | 6060 -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Timestamps/HH_mm_ss.txt: -------------------------------------------------------------------------------- 1 | 21:04:33 INFO Who needs a proper datetime anyways? -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Timestamps/HH_mm_ss;s.txt: -------------------------------------------------------------------------------- 1 | 06:51:57 ; 0.135345; Foo size 0; Th 6252(0x186c); Start;MC 14; Id 169= 169[ 0]; Bar; 2 | 06:53:06 ; 69.341584; Foo size 0; Th 8676(0x21e4); Stop ;MC 97; Id24689= 113[12]; Stuff -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Timestamps/ddd MMM dd HH_mm_ss.fff yyyy.txt: -------------------------------------------------------------------------------- 1 | Fri May 05 08:46:44.257 2017; Created. -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Timestamps/yyyy MMM dd HH_mm_ss.fff.txt: -------------------------------------------------------------------------------- 1 | Time; Clock; Time Process; Module Process; MC; Instance; SrcID; TargetID; Msg Type; CL ReturId; CL Default; PB MC; PB Ident; PB %; Line; Text 2 | 2017 May 09 06:51:57.583473503 Tue; 0; 1; 1; 108; 0; 124; 169;INFO; ; ; ; ; ; 0; -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Timestamps/yyyy-MM-dd HH_mm_ss.txt: -------------------------------------------------------------------------------- 1 | 2017-05-10 20:40:03 INFO Hello World! -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/Timestamps/yyyy-MM-dd HH_mm_ss_fff.txt: -------------------------------------------------------------------------------- 1 | 2017-05-10 20:40:03,143 INFO Hello World! -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/dawwddwa.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer.Tests/TestData/dawwddwa.txt -------------------------------------------------------------------------------- /src/Tailviewer.Tests/TestData/version.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/Ui/Controls/About/ChangelogViewModelTest.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using FluentAssertions; 3 | using NUnit.Framework; 4 | using Tailviewer.Ui.About; 5 | 6 | namespace Tailviewer.Tests.Ui.Controls.About 7 | { 8 | [TestFixture] 9 | public sealed class ChangelogViewModelTest 10 | { 11 | [Test] 12 | public void TestCtor() 13 | { 14 | var model = new ChangelogViewModel(); 15 | model.Changes.Count().Should().Be(Changelog.Changes.Count()); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Tailviewer.Tests/Ui/Controls/DispatcherExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Permissions; 2 | using System.Windows.Threading; 3 | 4 | namespace Tailviewer.Tests.Ui.Controls 5 | { 6 | public static class DispatcherExtensions 7 | { 8 | [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)] 9 | public static void ExecuteAllEvents() 10 | { 11 | var frame = new DispatcherFrame(); 12 | Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 13 | new DispatcherOperationCallback(ExitFrame), frame); 14 | Dispatcher.PushFrame(frame); 15 | } 16 | 17 | private static object ExitFrame(object frame) 18 | { 19 | ((DispatcherFrame)frame).Continue = false; 20 | return null; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/Ui/DragLayerTest.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Windows.Documents; 3 | using NUnit.Framework; 4 | 5 | namespace Tailviewer.Tests.Ui 6 | { 7 | [TestFixture] 8 | [Apartment(ApartmentState.STA)] 9 | public sealed class DragLayerTest 10 | { 11 | [SetUp] 12 | public void SetUp() 13 | { 14 | _decorator = new AdornerDecorator(); 15 | _layer = _decorator.AdornerLayer; 16 | } 17 | 18 | private AdornerLayer _layer; 19 | private AdornerDecorator _decorator; 20 | 21 | [Test] 22 | public void TestDoDragDrop1() 23 | { 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/Tailviewer.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/ActionCenterExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.BusinessLogic.ActionCenter 4 | { 5 | public static class ActionCenterExtensions 6 | { 7 | public static void AddRange(this IActionCenter actionCenter, IEnumerable notifications) 8 | { 9 | foreach (var notification in notifications) 10 | { 11 | actionCenter.Add(notification); 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/Build.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.BusinessLogic.ActionCenter 4 | { 5 | public sealed class Build 6 | : INotification 7 | { 8 | public static readonly Build Current; 9 | 10 | static Build() 11 | { 12 | Current = new Build(Constants.BuildDate, Constants.ApplicationVersion); 13 | } 14 | 15 | public Build(DateTime buildDate, Version applicationVersion) 16 | { 17 | Title = string.Format("{0} {1}, built on {2:D}, {3:T}", 18 | Constants.ApplicationTitle, 19 | applicationVersion, 20 | buildDate, 21 | buildDate); 22 | } 23 | 24 | public string Title { get; } 25 | 26 | public bool ForceShow => false; 27 | } 28 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/ExportException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.BusinessLogic.ActionCenter 4 | { 5 | public sealed class ExportException : Exception 6 | { 7 | public ExportException(string message) 8 | : base(message) 9 | { } 10 | 11 | public ExportException(string message, Exception inner) 12 | : base(message, inner) 13 | { } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/IActionCenter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Tailviewer.BusinessLogic.ActionCenter 5 | { 6 | public interface IActionCenter 7 | { 8 | void Add(INotification notification); 9 | IEnumerable Notifications { get; } 10 | event Action NotificationAdded; 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/IBug.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.ActionCenter 2 | { 3 | public interface IBug 4 | : INotification 5 | { 6 | string Details { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/IExportAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.BusinessLogic.ActionCenter 5 | { 6 | public interface IExportAction 7 | : INotification 8 | { 9 | Exception Exception { get; } 10 | Percentage Progress { get; } 11 | string DataSourceName { get; } 12 | string FullExportFilename { get; } 13 | string Destination { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/INotification.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.ActionCenter 2 | { 3 | public interface INotification 4 | { 5 | string Title { get; } 6 | 7 | /// 8 | /// When set to true then whoever is displaying notifications is told to 9 | /// make sure that this notification is displayed *immediately*. 10 | /// 11 | bool ForceShow { get; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/IOpenFolderAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.BusinessLogic.ActionCenter 5 | { 6 | public interface IOpenFolderAction 7 | : INotification 8 | { 9 | Exception Exception { get; } 10 | Percentage Progress { get; } 11 | string FullFoldername { get; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/Level.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.ActionCenter 2 | { 3 | public enum Level 4 | { 5 | Info, 6 | Warning, 7 | Error, 8 | } 9 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/ActionCenter/OpenFolderException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.BusinessLogic.ActionCenter 4 | { 5 | public sealed class OpenFolderException : Exception 6 | { 7 | public OpenFolderException(string message) : base(message) 8 | {} 9 | public OpenFolderException(string message, Exception inner) 10 | : base(message, inner) 11 | { } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/DataSources/Count.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.DataSources 2 | { 3 | public interface ICount 4 | { 5 | int LogLineCount { get; } 6 | int LogEntryCount { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/DataSources/Custom/ICustomDataSource.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | 3 | namespace Tailviewer.BusinessLogic.DataSources.Custom 4 | { 5 | /// 6 | /// The interface for a custom data source, e.g. one that is integrated into tailviewer via a plugin. 7 | /// 8 | public interface ICustomDataSource 9 | : ISingleDataSource 10 | { 11 | ICustomDataSourceConfiguration Configuration { get; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/DataSources/IFileDataSource.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.DataSources 2 | { 3 | /// 4 | /// Tag interface for an which represents the contents of a log file. 5 | /// 6 | public interface IFileDataSource 7 | : ISingleDataSource 8 | { 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/DataSources/ISingleDataSource.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.DataSources 2 | { 3 | /// 4 | /// Tag interface for an which consists of a single, unspecified source. 5 | /// 6 | /// 7 | /// A class implementing this interface may additionally implement other tag interfaces to specify which 8 | /// kind of data source it is. 9 | /// 10 | public interface ISingleDataSource 11 | : IDataSource 12 | { 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Exporter/ILogFileExporter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.BusinessLogic.Exporter 5 | { 6 | public interface ILogFileExporter 7 | { 8 | void Export(IProgress progressReporter = null); 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Exporter/ILogFileToFileExporter.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.Exporter 2 | { 3 | public interface ILogFileToFileExporter 4 | : ILogFileExporter 5 | { 6 | string FullExportFilename { get; } 7 | } 8 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/FileExplorer/FileExplorer.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | namespace Tailviewer.BusinessLogic.FileExplorer 4 | { 5 | internal sealed class FileExplorer : IFileExplorer 6 | { 7 | public void SelectFile( string filePath) 8 | { 9 | Process.Start("explorer.exe", $@"/select, {filePath}"); 10 | } 11 | public void SelectFiles(string folder, params string[] filesToSelect) 12 | { 13 | NativeMethods.OpenFolderAndSelectFiles(folder, filesToSelect); 14 | } 15 | public void OpenFolder(string folderPath) 16 | { 17 | Process.Start("explorer.exe", $@"/open, {folderPath}"); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/FileExplorer/IFileExplorer.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.BusinessLogic.FileExplorer 2 | { 3 | public interface IFileExplorer 4 | { 5 | void SelectFiles(string folder, params string[] filesToSelect); 6 | 7 | void SelectFile(string filePath); 8 | 9 | void OpenFolder(string folderPath); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Filters/IQuickFilters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Tailviewer.Core; 3 | 4 | namespace Tailviewer.BusinessLogic.Filters 5 | { 6 | 7 | 8 | public interface IQuickFilters 9 | { 10 | IEnumerable Filters { get; } 11 | 12 | /// 13 | /// 14 | /// 15 | TimeFilter TimeFilter { get; } 16 | 17 | /// 18 | /// Adds a new quickfilter. 19 | /// 20 | /// 21 | QuickFilter AddQuickFilter(); 22 | 23 | void Remove(QuickFilterId id); 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Highlighters/IHighlighters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.BusinessLogic.Highlighters 5 | { 6 | /// 7 | /// 8 | /// 9 | [Service] 10 | public interface IHighlighters 11 | { 12 | IEnumerable Highlighters { get; } 13 | 14 | /// 15 | /// Adds a new quickfilter. 16 | /// 17 | /// 18 | Highlighter AddHighlighter(); 19 | 20 | void Remove(HighlighterId id); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/LogFileFormats/ILogFileFormatRegistry.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | using Tailviewer.Settings.CustomFormats; 3 | 4 | namespace Tailviewer.BusinessLogic.LogFileFormats 5 | { 6 | /// 7 | /// 8 | /// 9 | [Service] 10 | public interface ILogFileFormatRegistry 11 | : ILogFileFormatRepository 12 | { 13 | void Add(CustomLogFileFormat customFormat, ILogFileFormat format); 14 | void Remove(CustomLogFileFormat customFormat); 15 | void Replace(CustomLogFileFormat oldCustomFormat, CustomLogFileFormat newCustomFormat, ILogFileFormat newFormat); 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Searches/ILogFileSearchListener.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.BusinessLogic.Searches 4 | { 5 | public interface ILogFileSearchListener 6 | { 7 | void OnSearchModified(ILogSourceSearch sender, IEnumerable matches); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Searches/ISearchResults.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.BusinessLogic.Searches 4 | { 5 | public interface ISearchResults 6 | { 7 | ISearchResultsByLogLineIndex MatchesByLine { get; } 8 | IReadOnlyList Matches { get; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Searches/ISearchResultsByLogLineIndex.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Tailviewer.Api; 3 | 4 | namespace Tailviewer.BusinessLogic.Searches 5 | { 6 | public interface ISearchResultsByLogLineIndex 7 | : IReadOnlyDictionary> 8 | {} 9 | } -------------------------------------------------------------------------------- /src/Tailviewer/BusinessLogic/Sources/ILogSourceFactory.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | using Tailviewer.Archiver.Plugins.Description; 3 | using Tailviewer.Core; 4 | 5 | namespace Tailviewer.BusinessLogic.Sources 6 | { 7 | /// 8 | /// Responsible for creating log sources. 9 | /// 10 | public interface ILogSourceFactoryEx 11 | : ILogSourceFactory 12 | { 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | ILogSource CreateCustom(CustomDataSourceId id, 21 | ICustomDataSourceConfiguration configuration, 22 | out IPluginDescription pluginDescription); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Tailviewer/Collections/IObservableCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Specialized; 3 | 4 | namespace Tailviewer.Collections 5 | { 6 | public interface IObservableCollection 7 | : IEnumerable 8 | , INotifyCollectionChanged 9 | { 10 | 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer/Collections/ObservableCollectionExt.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.ObjectModel; 3 | 4 | namespace Tailviewer.Collections 5 | { 6 | public sealed class ObservableCollectionExt 7 | : ObservableCollection 8 | , IObservableCollection 9 | { 10 | public ObservableCollectionExt() 11 | { 12 | } 13 | 14 | public ObservableCollectionExt(IEnumerable values) 15 | : base(values) 16 | { 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Tailviewer/Language.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.Contracts; 2 | 3 | namespace Tailviewer 4 | { 5 | public static class Language 6 | { 7 | [Pure] 8 | public static string Pluralize(string @base, int count) 9 | { 10 | return count == 1 11 | ? @base 12 | : @base + 's'; 13 | } 14 | 15 | /// 16 | /// Builds a string (with proper pluralization, if necessary) such as: 17 | /// 1 file 18 | /// 2 files 19 | /// etc... 20 | /// 21 | /// 22 | /// 23 | /// 24 | [Pure] 25 | public static string Count(string @base, int count) 26 | { 27 | return string.Format("{0} {1}", count, Pluralize(@base, count)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Tailviewer/Resources/Fonts/Inconsolata-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/Fonts/Inconsolata-Bold.ttf -------------------------------------------------------------------------------- /src/Tailviewer/Resources/Fonts/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/Fonts/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /src/Tailviewer/Resources/Icons.xaml: -------------------------------------------------------------------------------- 1 |  3 | 4 | -------------------------------------------------------------------------------- /src/Tailviewer/Resources/Tailviewer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/Tailviewer.ico -------------------------------------------------------------------------------- /src/Tailviewer/Resources/Tailviewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/Tailviewer.png -------------------------------------------------------------------------------- /src/Tailviewer/Resources/ic_alarm_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/ic_alarm_black_18dp.png -------------------------------------------------------------------------------- /src/Tailviewer/Resources/ic_no_time_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/ic_no_time_black_18dp.png -------------------------------------------------------------------------------- /src/Tailviewer/Resources/ic_no_time_black_8dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/ic_no_time_black_8dp.png -------------------------------------------------------------------------------- /src/Tailviewer/Resources/ic_no_time_white_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/ic_no_time_white_18dp.png -------------------------------------------------------------------------------- /src/Tailviewer/Resources/ic_no_time_white_8dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/ic_no_time_white_8dp.png -------------------------------------------------------------------------------- /src/Tailviewer/Resources/ic_open_10_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kittyfisto/Tailviewer/4047734191c569fad2613dac856eaf8b01f1b22b/src/Tailviewer/Resources/ic_open_10_black_18dp.png -------------------------------------------------------------------------------- /src/Tailviewer/Settings/Bookmarks/IBookmarks.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Tailviewer.Settings.Bookmarks 4 | { 5 | public interface IBookmarks 6 | { 7 | void Add(BookmarkSettings bookmark); 8 | void Remove(IEnumerable removed); 9 | 10 | IEnumerable All { get; } 11 | 12 | bool Save(); 13 | void SaveAsync(); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Tailviewer/Settings/Dashboard/Widgets/WidgetSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Xml; 2 | 3 | namespace Tailviewer.Settings.Dashboard.Widgets 4 | { 5 | public sealed class WidgetSettings 6 | { 7 | public void Restore(XmlReader reader) 8 | { 9 | 10 | } 11 | 12 | public void Save(XmlWriter writer) 13 | { 14 | 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer/Settings/DataSourceDisplayMode.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Ui.LogView.DataSource; 2 | 3 | namespace Tailviewer.Settings 4 | { 5 | /// 6 | /// Defines how displays individual data sources. 7 | /// 8 | public enum DataSourceDisplayMode 9 | { 10 | /// 11 | /// The filename of a data source is displayed (up to a certain character limit). 12 | /// 13 | Filename, 14 | 15 | /// 16 | /// A distinct one or two letter character code is displayed. 17 | /// 18 | CharacterCode 19 | } 20 | } -------------------------------------------------------------------------------- /src/Tailviewer/Settings/IAutoUpdateSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | using System.Xml; 5 | 6 | namespace Tailviewer.Settings 7 | { 8 | public interface IAutoUpdateSettings 9 | { 10 | DateTime LastChecked { get; set; } 11 | bool CheckForUpdates { get; set; } 12 | bool AutomaticallyInstallUpdates { get; set; } 13 | string ProxyServer { get; set; } 14 | string ProxyUsername { get; set; } 15 | string ProxyPassword { get; set; } 16 | IReadOnlyList PluginRepositories { get; set; } 17 | 18 | void Save(XmlWriter writer); 19 | void Restore(XmlReader reader); 20 | ICredentials GetProxyCredentials(); 21 | IWebProxy GetWebProxy(); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer/Settings/ICustomFormatsSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Tailviewer.Settings.CustomFormats; 3 | 4 | namespace Tailviewer.Settings 5 | { 6 | /// 7 | /// Provides access to all registered to this application. 8 | /// 9 | public interface ICustomFormatsSettings 10 | : IList 11 | { 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/Settings/IExportSettings.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Settings 2 | { 3 | /// 4 | /// Holds various settings related to exporting data from tailviewer. 5 | /// 6 | public interface IExportSettings 7 | { 8 | /// 9 | /// The absolute path to the folder where all exports are stored in. 10 | /// 11 | string ExportFolder { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/Tailviewer.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | No -------------------------------------------------------------------------------- /src/Tailviewer/Themes/Generic.xaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/About/ChangelogControl.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.About 2 | { 3 | public partial class ChangelogControl 4 | { 5 | public ChangelogControl() 6 | { 7 | InitializeComponent(); 8 | 9 | DataContext = new ChangelogViewModel(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/About/ChangelogViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Metrolib; 4 | using Tailviewer.BusinessLogic.ActionCenter; 5 | using Tailviewer.Ui.ActionCenter; 6 | 7 | namespace Tailviewer.Ui.About 8 | { 9 | public sealed class ChangelogViewModel 10 | { 11 | private readonly List _changes; 12 | 13 | public ChangelogViewModel() 14 | { 15 | _changes = new List(Changelog.Changes.Select(CreateViewModel)); 16 | _changes.Reverse(); 17 | } 18 | 19 | private ChangeViewModel CreateViewModel(Change change) 20 | { 21 | return new ChangeViewModel(change) 22 | { 23 | Title = change.Version.Format() 24 | }; 25 | } 26 | 27 | public IEnumerable Changes { get { return _changes; } } 28 | } 29 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/About/LicenseControl.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.About 2 | { 3 | public partial class LicenseControl 4 | { 5 | public LicenseControl() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/About/TailviewerControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace Tailviewer.Ui.About 4 | { 5 | /// 6 | /// Interaction logic for TailviewerControl.xaml 7 | /// 8 | public partial class TailviewerControl : UserControl 9 | { 10 | public TailviewerControl() 11 | { 12 | InitializeComponent(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/AboutViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui 2 | { 3 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/ActionCenter/ActionCenterControl.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.ActionCenter 2 | { 3 | public partial class ActionCenterControl 4 | { 5 | public ActionCenterControl() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/ActionCenter/BugViewModel.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.BusinessLogic.ActionCenter; 2 | 3 | namespace Tailviewer.Ui.ActionCenter 4 | { 5 | public sealed class BugViewModel 6 | : AbstractNotificationViewModel 7 | { 8 | private readonly IBug _bug; 9 | 10 | public BugViewModel(IBug bug) : base(bug) 11 | { 12 | _bug = bug; 13 | } 14 | 15 | public string Details 16 | { 17 | get 18 | { 19 | return _bug.Details; 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/ActionCenter/BuildTemplate.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/ActionCenter/BuildViewModel.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.BusinessLogic.ActionCenter; 2 | 3 | namespace Tailviewer.Ui.ActionCenter 4 | { 5 | public sealed class BuildViewModel 6 | : AbstractNotificationViewModel 7 | { 8 | public BuildViewModel(Build build) 9 | : base(build) 10 | {} 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/ActionCenter/INotificationViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | 4 | namespace Tailviewer.Ui.ActionCenter 5 | { 6 | public interface INotificationViewModel 7 | { 8 | void Update(); 9 | event Action OnRemove; 10 | ICommand RemoveCommand { get; } 11 | string Title { get; } 12 | bool IsRead { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/ActionCenter/NotificationViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Tailviewer.BusinessLogic.ActionCenter; 3 | 4 | namespace Tailviewer.Ui.ActionCenter 5 | { 6 | public sealed class NotificationViewModel 7 | : AbstractNotificationViewModel 8 | { 9 | private readonly Notification _notification; 10 | 11 | public NotificationViewModel(Notification notification) 12 | : base(notification) 13 | { 14 | _notification = notification; 15 | } 16 | 17 | public DateTime Timestamp => _notification.Timestamp; 18 | 19 | public string Message => _notification.Message; 20 | 21 | public Level Level => _notification.Level; 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/AutoUpdateControl.xaml.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui 2 | { 3 | public partial class AutoUpdateControl 4 | { 5 | public AutoUpdateControl() 6 | { 7 | InitializeComponent(); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/Converters/BrushType.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.Converters 2 | { 3 | public enum BrushType 4 | { 5 | Background, 6 | Foreground, 7 | } 8 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/Converters/DoubleOneToHiddenConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Tailviewer.Ui.Converters 7 | { 8 | public sealed class DoubleOneToHiddenConverter 9 | : IValueConverter 10 | { 11 | #region Implementation of IValueConverter 12 | 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (!(value is double actualValue)) 16 | return Visibility.Hidden; 17 | 18 | if (actualValue < 1) 19 | return Visibility.Visible; 20 | 21 | return Visibility.Hidden; 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | 29 | #endregion 30 | } 31 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/Converters/NullToNotAvailableConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Tailviewer.Ui.Converters 6 | { 7 | /// 8 | /// A converter which converts null values to N/A. 9 | /// 10 | public sealed class NullToNotAvailableConverter 11 | : IValueConverter 12 | { 13 | /// 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | if (value == null) 17 | return "N/A"; 18 | 19 | return value; 20 | } 21 | 22 | /// 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | throw new NotImplementedException(); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/Converters/ShowAllToContentConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows.Data; 4 | 5 | namespace Tailviewer.Ui.Converters 6 | { 7 | public sealed class ShowAllToContentConverter 8 | : IValueConverter 9 | { 10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 11 | { 12 | var showAll = value as bool?; 13 | if (showAll == true) 14 | return "All"; 15 | if (showAll == false) 16 | return "None"; 17 | return "Mixed"; 18 | } 19 | 20 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 21 | { 22 | return null; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/Converters/ZeroToHiddenConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | 6 | namespace Tailviewer.Ui.Converters 7 | { 8 | public sealed class ZeroToHiddenConverter 9 | : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | if (!(value is int)) 14 | return null; 15 | 16 | var count = (int) value; 17 | return count == 0 18 | ? Visibility.Hidden 19 | : Visibility.Visible; 20 | } 21 | 22 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 23 | { 24 | throw new NotImplementedException(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/CustomDataSourceTemplate.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/DataSourceDropAdorner.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | using System.Windows.Documents; 4 | using System.Windows.Media; 5 | 6 | namespace Tailviewer.Ui.DataSourceTree 7 | { 8 | public sealed class DataSourceDropAdorner 9 | : Adorner 10 | { 11 | private readonly Pen _pen; 12 | 13 | public DataSourceDropAdorner(TreeViewItem dropTarget) 14 | : base(dropTarget) 15 | { 16 | _pen = new Pen(Brushes.DodgerBlue, 2); 17 | } 18 | 19 | protected override void OnRender(DrawingContext drawingContext) 20 | { 21 | var rect = new Rect(0, 0, ActualWidth, ActualHeight); 22 | drawingContext.DrawRectangle(null, 23 | _pen, 24 | rect); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/DataSourceDropType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Tailviewer.Ui.DataSourceTree 4 | { 5 | [Flags] 6 | public enum DataSourceDropType 7 | { 8 | None = 0, 9 | ArrangeTop = 0x1, 10 | ArrangeBottom = 0x2, 11 | Group = 0x4, 12 | } 13 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/DataSourcesToggleButton.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using Metrolib.Controls; 3 | 4 | namespace Tailviewer.Ui.DataSourceTree 5 | { 6 | /// 7 | /// The button with which the user toggles the visibility of the . 8 | /// 9 | public sealed class DataSourcesToggleButton 10 | : FlatToggleButton 11 | { 12 | static DataSourcesToggleButton() 13 | { 14 | DefaultStyleKeyProperty.OverrideMetadata(typeof(DataSourcesToggleButton), 15 | new FrameworkPropertyMetadata(typeof(DataSourcesToggleButton))); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/DropInfo.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.DataSourceTree 2 | { 3 | public sealed class DropInfo 4 | { 5 | public TreeItem Source; 6 | public TreeItem Target; 7 | public TreeItem TargetGroup; 8 | public DataSourceDropType Type; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/ICustomDataSourceViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.DataSourceTree 2 | { 3 | public interface ICustomDataSourceViewModel 4 | : ISingleDataSourceViewModel 5 | { 6 | 7 | } 8 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/IFileDataSourceViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.DataSourceTree 2 | { 3 | public interface IFileDataSourceViewModel 4 | : ISingleDataSourceViewModel 5 | { } 6 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/DataSourceTree/TreeItem.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace Tailviewer.Ui.DataSourceTree 4 | { 5 | public sealed class TreeItem 6 | { 7 | public TreeViewItem TreeViewItem; 8 | public IDataSourceViewModel ViewModel; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/IFlyoutViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace Tailviewer.Ui 4 | { 5 | /// 6 | /// The view model for a fly-out which is laid on top of other content. 7 | /// 8 | public interface IFlyoutViewModel 9 | : INotifyPropertyChanged 10 | { 11 | void Update(); 12 | string Name { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/IMainPanelEntry.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media; 2 | 3 | namespace Tailviewer.Ui 4 | { 5 | public interface IMainPanelEntry 6 | { 7 | string Title { get; } 8 | string Id { get; } 9 | string ToolTip { get; } 10 | Geometry Icon { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/IMainPanelViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Tailviewer.Ui.LogView; 3 | 4 | namespace Tailviewer.Ui 5 | { 6 | public interface IMainPanelViewModel 7 | : INotifyPropertyChanged 8 | { 9 | ISearchViewModel Search { get; } 10 | 11 | IFindAllViewModel FindAll { get; } 12 | 13 | void Update(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/IMainWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Tailviewer.Collections; 3 | using Tailviewer.Ui.DataSourceTree; 4 | using Tailviewer.Ui.LogView; 5 | using Tailviewer.Ui.Menu; 6 | 7 | namespace Tailviewer.Ui 8 | { 9 | public interface IMainWindowViewModel 10 | : INotifyPropertyChanged 11 | { 12 | IObservableCollection KeyBindings { get; } 13 | LogViewMainPanelViewModel LogViewPanel { get; } 14 | IFlyoutViewModel CurrentFlyout { get; set; } 15 | IDataSourceViewModel AddFileOrDirectory(string dataSourceUri); 16 | } 17 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/AddCustomDataSourceViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Input; 3 | using Metrolib; 4 | 5 | namespace Tailviewer.Ui.LogView 6 | { 7 | /// 8 | /// 9 | /// 10 | public sealed class AddCustomDataSourceViewModel 11 | { 12 | private readonly ICommand _command; 13 | private readonly string _name; 14 | 15 | public ICommand AddCommand => _command; 16 | 17 | public string Name => _name; 18 | 19 | public AddCustomDataSourceViewModel(string name, Action add) 20 | { 21 | _name = name; 22 | _command = new DelegateCommand2(add); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/Any/AnyColumnPresenter.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | using Tailviewer.Settings; 3 | 4 | namespace Tailviewer.Ui.LogView.Any 5 | { 6 | /// 7 | /// 8 | /// 9 | /// 10 | public sealed class AnyColumnPresenter 11 | : AbstractLogColumnPresenter 12 | { 13 | public AnyColumnPresenter(IColumnDescriptor column, TextSettings textSettings) 14 | : base(column, textSettings) 15 | { 16 | } 17 | 18 | #region Overrides of AbstractLogColumnPresenter 19 | 20 | protected override void UpdateWidth(ILogSource logSource, TextSettings textSettings) 21 | {} 22 | 23 | protected override AbstractLogEntryValueFormatter CreateFormatter(T value) 24 | { 25 | return new AnyFormatter(value, TextSettings); 26 | } 27 | 28 | #endregion 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/IFindAllViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | using System.Windows.Input; 4 | using Tailviewer.Api; 5 | using Tailviewer.BusinessLogic.Searches; 6 | 7 | namespace Tailviewer.Ui.LogView 8 | { 9 | public interface IFindAllViewModel 10 | : INotifyPropertyChanged 11 | { 12 | IEnumerable SelectedLogLines { get; set; } 13 | ILogSource LogSource { get; } 14 | ILogSourceSearch Search { get; } 15 | string SearchTerm { get; set; } 16 | bool Show { get; } 17 | string ErrorMessage { get; } 18 | bool IsEmpty { get; } 19 | ICommand CloseCommand { get; } 20 | } 21 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/ILogEntryValueFormatter.cs: -------------------------------------------------------------------------------- 1 | namespace Tailviewer.Ui.LogView 2 | { 3 | public interface ILogEntryValueFormatter 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/ILogFileColumnPresenter.cs: -------------------------------------------------------------------------------- 1 | using Tailviewer.Api; 2 | using Tailviewer.Settings; 3 | 4 | namespace Tailviewer.Ui.LogView 5 | { 6 | /// 7 | /// Responsible for presenting one column of a log file. 8 | /// 9 | public interface ILogFileColumnPresenter 10 | { 11 | IColumnDescriptor Column { get; } 12 | 13 | TextSettings TextSettings { get; set; } 14 | 15 | /// 16 | /// Fetches the newest values for this presenter's column from the given log file. 17 | /// 18 | /// 19 | /// 20 | /// 21 | void FetchValues(ILogSource logSource, LogSourceSection visibleSection, double yOffset); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/ILogViewMainPanelViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Input; 2 | 3 | namespace Tailviewer.Ui.LogView 4 | { 5 | public interface ILogViewMainPanelViewModel 6 | : IMainPanelViewModel 7 | { 8 | ICommand AddBookmarkCommand { get; } 9 | ICommand RemoveAllBookmarkCommand { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/ISearchViewModel.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | namespace Tailviewer.Ui.LogView 4 | { 5 | public interface ISearchViewModel 6 | : INotifyPropertyChanged 7 | { 8 | string Term { get; set; } 9 | int ResultCount { get; } 10 | int CurrentResultIndex { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tailviewer/Ui/LogView/LogLevelToggleButtonStyle.xaml: -------------------------------------------------------------------------------- 1 |  4 | 5 | 6 | 7 | 8 | 9 |