Unit SettingsUnit; // NewView - a new OS/2 Help Viewer // Copyright 2003 Aaron Lawrence (aaronl at consultant dot com) // This software is released under the Gnu Public License - see readme.txt Interface // Defines settings (options) in a record and contains functions // for loading and saving them to ini file. Uses Forms, Classes; Const ContentsBackgroundColorIndex = 0; ContentsTextColorIndex = 1; ContentsLinesColorIndex = 2; IndexBackgroundColorIndex = 3; IndexTextColorIndex = 4; SearchBackgroundColorIndex = 5; SearchTextColorIndex = 6; NotesListBackgroundColorIndex = 7; NotesListTextColorIndex = 8; TopicBackgroundColorIndex = 9; NotesTextColorIndex = 10; SearchHighlightTextColorIndex = 11; NumColorSettings = 12; clLightYellow = $ffffc0; clLightBlue = $e0e0ff; clLightCyan = $c0ffff; clLightGreen = $e0ffe0; VGADefaultColors: array[ 0 .. NumColorSettings - 1 ] of TColor = ( clWindow, clWindowText, clWindowText, clWindow, clWindowText, clWindow, clWindowText, clWindow, clWindowText, clWindow, clGreen, clYellow ); DefaultColors: array[ 0 .. NumColorSettings - 1 ] of TColor = ( clLightCyan, clBlack, clBlue, clLightGreen, clBlack, clLightBlue, clBlack, clWhite, clBlack, clWhite, clGreen, clYellow ); ApplicationFontIndex = 0; NumFontSettings = 1; DefaultTopicFontName = 'Helv'; DefaultTopicFontSize = 8; DefaultTopicFixedFontName = 'Courier'; DefaultTopicFixedFontSize = 8; Type TIndexStyle = ( isFileOnly, isAlphabetical, isFull ); TToolbarStyle = ( tsNone, tsImages, tsText, tsImagesAndText ); TGlobalSearchLocation = ( gsHelpPaths, gsFixedDrives, gsSelectedHelpPaths, gsCustom ); TMRUItem = class Title: string; Filenames: TStringList; constructor Create; destructor Destroy; override; end; TSettings = record MRUList: TList; LastOpenDirectory: string; LastSaveDirectory: string; StartupHelp: boolean; LeftPanelWidth: longint; ShowLeftPanel_Help: boolean; ShowLeftPanel_Standalone: boolean; FileDialogSplit: real; // Colours Colors: array[ 0..NumColorSettings - 1 ] of TColor; NormalFont: TFont; FixedFont: TFont; Fonts: array[ 0..NumFontSettings - 1 ] of TFont; FixedFontSubstitution: boolean; FixedFontSubstitutes: string; IndexStyle: TIndexStyle; SmoothScrolling: boolean; UseOriginalDialogs: boolean; OpenWithExpandedContents: boolean; ToolbarBackgroundImageFilename: string; ToolbarStyle: TToolbarStyle; ConfirmWinHelp: boolean; GlobalSearchLocation: TGlobalSearchLocation; SearchDirectories: TStringList; end; Procedure WriteWindowPos( Form: TForm ); Procedure ReadWindowPos( Form: TForm ); Procedure LoadSettings; Procedure SaveSettings; PROCEDURE writeSettingsDetailsTo(aStrings : TStrings); Procedure AddToMRUList( const Title: string; Filenames: TStrings ); Var Settings: TSettings; Implementation Uses SysUtils, PMWin, OS2Def, DebugUnit, Dos, FileUtilsUnit, ACLUtility, StringUtilsUnit, ControlsUtility; Const IniFileName = 'NewView.ini'; GeneralSection = 'General'; FontsSection = 'Fonts'; ColoursSection = 'Colours'; MRUSection = 'RecentFiles'; MRUItemBaseSection = 'RecentFile'; SearchSection = 'Search'; DefaultWidth = 620; DefaultHeight = 460; MaxMRUListEntries = 9; constructor TMRUItem.Create; begin Title := ''; Filenames := TStringList.Create; end; destructor TMRUItem.Destroy; begin Filenames.Destroy; end; Function IniFilePath: string; Var Dir: string; Name, Ext: string; UserIniFile: string; Begin // Put it in the same place as the application UserIniFile := GetApplicationDir; // Note: do NOT combine these two steps. Caused an obscure bug! FSplit( UserIniFile, Dir, Name, Ext ); Result := AddDirectorySeparator( Dir ) + IniFileName; End; // Note: since Sibyl SPCC 2.1.8.3 // the Ascii ini file constructor does not throw an exception procedure GetIniFile( Var IniFile: TMyIniFile ); begin IniFile := TMyIniFile.Create( IniFilePath ); end; procedure CloseIniFile( Var IniFIle: TMyIniFile ); begin try LogEvent(LogSettings, 'Calling IniFile.Destroy'); IniFile.Destroy; except on E: Exception do begin // don't care if we can't save settings. LogEvent(LogSettings, ' Exception: ' + E.Message ); end; end; end; Procedure LoadSettings; Var IniFile: TMyIniFile; ColorIndex: longint; DefaultColor: TColor; FontName: string; SettingString: string; MRUItem: TMRUItem; MRUItemSection: string; MRUItemFileCount: longint; MRUItemFileIndex: longint; i: longint; Count: longint; MRUFilename: string; MRUFileTitle: string; Begin GetIniFile( IniFile ); with IniFile do begin IniFile.EraseSection( 'Windows' ); with Settings do begin LastOpenDirectory := ReadString( GeneralSection, 'LastOpenDirectory', '' ); LastSaveDirectory := ReadString( GeneralSection, 'LastSaveDirectory', '' ); // Read split points, as units of 0.1% LeftPanelWidth := ReadInteger( GeneralSection, 'LeftPanelWidth', 225 ); FileDialogSplit := ReadInteger( GeneralSection, 'FileDialogSplit', 500 ) / 1000; ShowLeftPanel_Help := ReadBool( GeneralSection, 'ShowLeftPanel_Help', true ); ShowLeftPanel_Standalone := ReadBool( GeneralSection, 'ShowLeftPanel_Standalone', true ); // Colours for ColorIndex := 0 to High( Colors ) do begin if GetScreenColorDepth > 8 then DefaultColor := DefaultColors[ ColorIndex ] else DefaultColor := VGADefaultColors[ ColorIndex ]; Colors[ ColorIndex ] := ReadInteger( ColoursSection, 'Color' + IntToStr( ColorIndex ), DefaultColor ); end; // Most Recently Used files list... Count := ReadInteger( MRUSection, 'Count', 0 ); // Old style MRU list for i := 0 to Count - 1 do begin MRUFilename := ReadString( MRUSection, 'File' + IntToStr( i ), '' ); MRUFileTitle := ReadString( MRUSection, 'Title' + IntToStr( i ), '' ); if MRUFilename <> '' then begin MRUItem := TMRUItem.Create; MRUItem.Title := MRUFileTitle; StrExtractStrings(MRUItem.Filenames, MRUFilename, ['+'], #0); MRUList.Add( MRUItem ); end; end; // New style for i := 0 to Count - 1 do begin MRUItemSection := MRUItemBaseSection + IntToStr( i ); MRUItem := TMRUItem.Create; MRUItem.Title := ReadString( MRUItemSection, 'Title', '' ); MRUItemFileCount := ReadInteger( MRUItemSection, 'FileCount', 0 ); for MRUItemFileIndex := 0 to MRUItemFileCount - 1 do begin MRUFilename := ReadString( MRUItemSection, 'File' + IntToStr( MRUItemFileIndex ), '' ); if MRUFilename <> '' then begin MRUItem.Filenames.Add( MRUFilename ); end; end; if ( MRUItem.Title <> '' ) and ( MRUItem.Filenames.Count > 0 ) then begin // valid MRU item MRUList.Add( MRUItem ); end else begin // not valid MRUItem.Destroy; MRUItem := nil; end; end; // Fonts NormalFont := Screen.GetFontFromPointSize( ReadString( FontsSection, 'NormalFont', DefaultTopicFontName ), ReadInteger( FontsSection, 'NormalFontSize', DefaultTopicFontSize ) ); if NormalFont = nil then NormalFont := Screen.DefaultFont; FixedFont := Screen.GetFontFromPointSize( ReadString( FontsSection, 'FixedFont', DefaultTopicFixedFontName ), ReadInteger( FontsSection, 'FixedFontSize', DefaultTopicFixedFontSize ) ); if FixedFont = nil then FixedFont := Screen.DefaultFont; for i := 0 to NumFontSettings - 1 do begin FontName := 'Font' + IntToStr( i ); Fonts[ i ] := nil; if ReadBool( FontsSection, FontName + 'Customised', false ) then Fonts[ i ] := Screen.GetFontFromPointSize( ReadString( FontsSection, FontName + 'Face', DefaultTopicFontName ), ReadInteger( FontsSection, FontName + 'Size', 10 ) ); end; FixedFontSubstitution := ReadBool( FontsSection, 'FixedFontSubstitution', true ); FixedFontSubstitutes := ReadString( FontsSection, 'FixedFontSubstitutes', 'Courier 18x12' ); // Index style SettingString := ReadString( GeneralSection, 'IndexStyle', 'Full' ); if StrEqualIgnoringCase( SettingString, 'FileOnly' ) then IndexStyle := isFileOnly else if StrEqualIgnoringCase( SettingString, 'Alphabetical' ) then IndexStyle := isAlphabetical else IndexStyle := isFull; StartupHelp := ReadBool( GeneralSection, 'StartupHelp', true ); SmoothScrolling := ReadBool( GeneralSection, 'SmoothScrolling', true ); UseOriginalDialogs := ReadBool( GeneralSection, 'UseOriginalDialogs', false ); OpenWithExpandedContents := ReadBool( GeneralSection, 'OpenWithExpandedContents', false ); ToolBarBackgroundImageFilename := ReadString( GeneralSection, 'ToolbarBackground', '' ); SettingString := ReadString( GeneralSection, 'ToolbarStyle', 'ImagesAndText' ); if StrEqualIgnoringCase( SettingString, 'None' ) then ToolbarStyle := tsNone else if StrEqualIgnoringCase( SettingString, 'Images' ) then ToolbarStyle := tsImages else if StrEqualIgnoringCase( SettingString, 'Text' ) then ToolbarStyle := tsText else ToolbarStyle := tsImagesAndText; ConfirmWinHelp := ReadBool( GeneralSection, 'ConfirmWinHelp', true ); Count := ReadInteger( SearchSection, 'CustomDirCount', 0 ); SearchDirectories.Clear; for i := 0 to Count - 1 do begin SettingString := ReadString( SearchSection, 'CustomDir' + IntToStr( i ), '' ); if trim( SettingString ) <> '' then SearchDirectories.Add( SettingString ); end; SettingString := ReadString( SearchSection, 'Location', 'HelpPaths' ); if StrEqualIgnoringCase( SettingString, 'HelpPaths' ) then GlobalSearchLocation := gsHelpPaths else if StrEqualIgnoringCase( SettingString, 'FixedDrives' ) then GlobalSearchLocation := gsFixedDrives else if StrEqualIgnoringCase( SettingString, 'SelectedHelpPaths' ) then GlobalSearchLocation := gsSelectedHelpPaths else GlobalSearchLocation := gsCustom; end; end; CloseIniFile( IniFile ); End; Procedure SaveSettings; Var IniFile: TMyIniFile; ColorIndex: longint; FontIndex: longint; FontName: string; i: longint; MRUItemFileIndex: longint; SettingString: string; MRUItem: TMRUItem; MRUItemSection: string; Begin LogEvent(LogSettings, 'SaveSettings' ); GetIniFile( IniFile ); with IniFile do begin with Settings do begin WriteString( GeneralSection, 'LastOpenDirectory', LastOpenDirectory ); WriteString( GeneralSection, 'LastSaveDirectory', LastSaveDirectory ); WriteInteger( GeneralSection, 'LeftPanelWidth', LeftPanelWidth ); // Write split points, as units of 0.1% WriteInteger( GeneralSection, 'FileDialogSplit', Round( FileDialogSplit * 1000 ) ); WriteBool( GeneralSection, 'ShowLeftPanel_Help', ShowLeftPanel_Help ); WriteBool( GeneralSection, 'ShowLeftPanel_Standalone', ShowLeftPanel_Standalone ); // COlours for ColorIndex := 0 to High( Colors ) do WriteInteger( ColoursSection, 'Color' + IntToStr( ColorIndex ), Colors[ ColorIndex ] ); EraseSection( MRUSection ); // get rid of old style MRU WriteInteger( MRUSection, 'Count', MRUList.Count ); for i := 0 to MRUList.Count - 1 do begin MRUItem := MRUList[ i ]; MRUItemSection := MRUItemBaseSection + IntToStr( i ); EraseSection( MRUItemSection ); WriteString( MRUItemSection, 'Title', MRUItem.Title ); WriteInteger( MRUItemSection, 'FileCount', MRUItem.Filenames.Count ); for MRUItemFileIndex := 0 to MRUItem.Filenames.Count - 1 do WriteString( MRUItemSection, 'File' + IntToStr( MRUItemFileIndex ), MRUItem.Filenames[ MRUItemFileIndex ] ); end; // clear unused sections for i := MRUList.Count to MaxMRUListEntries do begin MRUItemSection := MRUItemBaseSection + IntToStr( i ); EraseSection( MRUItemSection ); end; WriteString( FontsSection, 'NormalFont', NormalFont.FaceName ); WriteInteger( FontsSection, 'NormalFontSize', NormalFont.PointSize ); WriteString( FontsSection, 'FixedFont', FixedFont.FaceName ); WriteInteger( FontsSection, 'FixedFontSize', FixedFont.PointSize ); for FontIndex := 0 to NumFontSettings - 1 do begin FontName := 'Font' + IntToStr( FontIndex ); WriteBool( FontsSection, FontName + 'Customised', Fonts[ FontIndex ] <> nil ); if Fonts[ FontIndex ] <> nil then begin WriteString( FontsSection, FontName + 'Face', Fonts[ FontIndex ].FaceName ); WriteInteger( FontsSection, FontName + 'Size', Fonts[ FontIndex ].PointSize ); end; end; WriteBool( FontsSection, 'FixedFontSubstitution', FixedFontSubstitution ); WriteString( FontsSection, 'FixedFontSubstitutes', FixedFontSubstitutes ); case IndexStyle of isFileOnly: SettingString := 'FileOnly'; isAlphabetical: SettingString := 'Alphabetical'; isFull: SettingString := 'Full'; end; WriteString( GeneralSection, 'IndexStyle', SettingString ); WriteBool( GeneralSection, 'StartupHelp', StartupHelp ); WriteBool( GeneralSection, 'SmoothScrolling', SmoothScrolling ); WriteBool( GeneralSection, 'UseOriginalDialogs', UseOriginalDialogs ); WriteBool( GeneralSection, 'OpenWithExpandedContents', OpenWithExpandedContents ); WriteString( GeneralSection, 'ToolbarBackground', ToolbarBackgroundImageFilename ); case ToolbarStyle of tsNone: SettingString := 'None'; tsImages: SettingString := 'Images'; tsText: SettingString := 'Text'; tsImagesAndText: SettingString := 'ImagesAndText'; end; WriteString( GeneralSection, 'ToolbarStyle', SettingString ); WriteBool( GeneralSection, 'ConfirmWinHelp', ConfirmWinHelp ); WriteInteger( SearchSection, 'CustomDirCount', SearchDirectories.Count ); SearchDirectories.Sorted := true; SearchDirectories.CaseSensitive := false; SearchDirectories.Duplicates := dupIgnore; for i := 0 to SearchDirectories.Count - 1 do begin WriteString( SearchSection, 'CustomDir' + IntToStr( i ), SearchDirectories[ i ] ); end; case GlobalSearchLocation of gsHelpPaths: SettingString := 'HelpPaths'; gsFixedDrives: SettingString := 'FixedDrives'; gsSelectedHelpPaths: SettingString := 'SelectedHelpPaths'; gsCustom: SettingString := 'Custom'; end; WriteString( SearchSection, 'Location', SettingString ); end; end; CloseIniFile( IniFile ); LogEvent(LogSettings, ' Done' ); End; Procedure AddToMRUList( const Title: string; Filenames: TStrings ); var MRUIndex: longint; PreviousMRUIndex: longint; MRUItem: TMRUItem; begin PreviousMRUIndex := -1; for MRUIndex := 0 to Settings.MRUList.Count - 1 do begin MRUItem := Settings.MRUList[ MRUIndex ]; if ( MRUItem.Title = Title ) and ( MRUItem.Filenames.Equals( Filenames ) ) then begin // found identical entry in the list already. PreviousMRUIndex := MRUIndex; break; end; end; if PreviousMRUIndex > -1 then begin // is already in list, move to top of list MRUItem := Settings.MRUList[ PreviousMRUIndex ]; Settings.MRUList.Delete( PreviousMRUIndex ); end else begin // not yet in list. Create new MRUItem := TMRUItem.Create; MRUItem.Title := Title; MRUItem.Filenames.Assign( Filenames ); end; Settings.MRUList.Insert( 0, MRUItem ); while Settings.MRUList.Count > MaxMRUListEntries do begin MRUItem := Settings.MRUList[ MaxMRUListEntries ]; Settings.MRUList.Delete( MaxMRUListEntries ); MRUItem.Destroy; end; end; Procedure WriteWindowPos( Form: TForm ); Var IniFile: TMyIniFile; Begin GetIniFile( IniFile ); SaveFormSizePosition( Form, IniFile ); CloseIniFile( IniFile ); End; Procedure ReadWindowPos( Form: TForm ); Var IniFile: TMyIniFile; Begin GetIniFile( IniFile ); LoadFormSizePosition( Form, IniFile ); CloseIniFile( IniFile ); End; PROCEDURE writeSettingsDetailsTo(aStrings : TStrings); Var tmpRect : RECTL; // DesktopHWND : HWND=0; Begin aStrings.Add(''); aStrings.Add('---- Settings ----'); aStrings.Add('info: ' + IntToStr(WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN))); aStrings.Add('info: ' + IntToStr(Screen.Width)); // some tests { WinQueryWindowRect(HWND_DESKTOP, tmpRect); aStrings.Add('info: WinQueryWindowRect(HWND_DESKTOP, tmpRect)'); aStrings.Add('info: ' + IntToStr(tmpRect.xLeft) + ', ' + IntToStr(tmpRect.yBottom) + ', ' + IntToStr(tmpRect.xRight) + ', ' + IntToStr(tmpRect.yTop)); If DesktopHWND = 0 Then DesktopHWND := WinQueryDesktopWindow(AppHandle, 0); WinQueryWindowRect(DesktopHWND, tmpRect); aStrings.Add('info: WinQueryWindowRect(DesktopHWND, tmpRect)'); aStrings.Add('info: ' + IntToStr(tmpRect.xLeft) + ', ' + IntToStr(tmpRect.yBottom) + ', ' + IntToStr(tmpRect.xRight) + ', ' + IntToStr(tmpRect.yTop)); } aStrings.Add('LastOpenDirectory: ' + Settings.LastOpenDirectory); aStrings.Add('LastSaveDirectory: ' + Settings.LastSaveDirectory); aStrings.Add('StartupHelp: ' + boolToStr(Settings.StartupHelp)); // LeftPanelWidth: longint; aStrings.Add('ShowLeftPanel_Help: ' + boolToStr(Settings.ShowLeftPanel_Help)); aStrings.Add('ShowLeftPanel_Standalone: ' + boolToStr(Settings.ShowLeftPanel_Standalone)); // FileDialogSplit: real; // Colors: array[ 0..NumColorSettings - 1 ] of TColor; // NormalFont: TFont; // FixedFont: TFont; // Fonts: array[ 0..NumFontSettings - 1 ] of TFont; aStrings.Add('FixedFontSubstitution: ' + boolToStr(Settings.FixedFontSubstitution)); aStrings.Add('FixedFontSubstitutes: ' + Settings.FixedFontSubstitutes); // IndexStyle: TIndexStyle; aStrings.Add('SmoothScrolling: ' + boolToStr(Settings.SmoothScrolling)); aStrings.Add('UseOriginalDialogs: ' + boolToStr(Settings.UseOriginalDialogs)); aStrings.Add('OpenWithExpandedContents: ' + boolToStr(Settings.OpenWithExpandedContents)); aStrings.Add('ToolbarBackgroundImageFilename: ' + Settings.ToolbarBackgroundImageFilename); // ToolbarStyle: TToolbarStyle; aStrings.Add('ConfirmWinHelp: ' + boolToStr(Settings.ConfirmWinHelp)); // GlobalSearchLocation: TGlobalSearchLocation; // SearchDirectories: TStringList; end; Initialization Settings.NormalFont := Screen.GetFontFromPointSize( 'Helv', 8 ); Settings.FixedFont := Screen.GetFontFromPointSize( 'Courier', 8 ); Settings.SearchDirectories := TStringList.Create; Finalization Settings.NormalFont.Destroy; Settings.FixedFont.Destroy; Settings.SearchDirectories.Destroy; End.