diff --git a/components/heidisql/include/const.inc b/components/heidisql/include/const.inc index 971e93c4..47f30b6e 100644 --- a/components/heidisql/include/const.inc +++ b/components/heidisql/include/const.inc @@ -149,6 +149,11 @@ const REGNAME_CSV_LOWPRIO = 'CSVImportLowPriority'; REGNAME_CSV_REPLACE = 'CSVImportReplace'; REGNAME_CSV_IGNORE = 'CSVImportIgnore'; + REGNAME_DO_UPDATECHECK = 'Updatecheck'; + DEFAULT_DO_UPDATECHECK = True; + REGNAME_UPDATECHECK_INTERVAL = 'UpdatecheckInterval'; + DEFAULT_UPDATECHECK_INTERVAL = 3; + REGNAME_LAST_UPDATECHECK = 'UpdatecheckLastrun'; REGPREFIX_COLWIDTHS = 'ColWidths_'; REGPREFIX_COLSVISIBLE = 'ColsVisible_'; diff --git a/source/main.pas b/source/main.pas index ae928d84..82930d05 100644 --- a/source/main.pas +++ b/source/main.pas @@ -17,7 +17,7 @@ uses ActnList, ImgList, Registry, ShellApi, ToolWin, Clipbrd, db, DBCtrls, SynMemo, synedit, SynEditTypes, ZDataSet, ZSqlProcessor, HeidiComp, sqlhelp, MysqlQueryThread, Childwin, VirtualTrees, TntDBGrids, - StrUtils; + StrUtils, DateUtils; type TMainForm = class(TForm) @@ -487,7 +487,28 @@ var parHost, parPort, parUser, parPass, parDatabase, parTimeout, parCompress, parSortDatabases, parDescription : String; reg : TRegistry; + LastUpdatecheck : TDateTime; + UpdatecheckInterval : Integer; + DefaultLastrunDate : String; + frm : TfrmUpdateCheck; begin + // Do an updatecheck if checked in settings + if GetRegValue(REGNAME_DO_UPDATECHECK, DEFAULT_DO_UPDATECHECK) then begin + DefaultLastrunDate := '2000-01-01'; + try + LastUpdatecheck := StrToDateTime( GetRegValue(REGNAME_LAST_UPDATECHECK, DefaultLastrunDate) ); + except + LastUpdatecheck := StrToDateTime( DefaultLastrunDate ); + end; + UpdatecheckInterval := GetRegValue(REGNAME_UPDATECHECK_INTERVAL, DEFAULT_UPDATECHECK_INTERVAL); + if DaysBetween(Now, LastUpdatecheck) >= UpdatecheckInterval then begin + frm := TfrmUpdateCheck.Create(Self); + frm.AutoClose := True; + frm.ShowModal; + FreeAndNil(frm); + end; + end; + // Check commandline if parameters were passed. Otherwise show connections windows curParam := 1; while curParam <= ParamCount do diff --git a/source/options.dfm b/source/options.dfm index 4cab9464..1211f4ce 100644 --- a/source/options.dfm +++ b/source/options.dfm @@ -80,7 +80,7 @@ object optionsform: Toptionsform OnClick = Modified end object updownLogSQLNum: TUpDown - Left = 120 + Left = 114 Top = 101 Width = 17 Height = 21 @@ -93,7 +93,7 @@ object optionsform: Toptionsform OnChanging = anyUpDownLimitChanging end object editLogSQLNum: TEdit - Left = 67 + Left = 61 Top = 101 Width = 53 Height = 21 @@ -150,6 +150,37 @@ object optionsform: Toptionsform TabOrder = 8 OnChanging = anyUpDownLimitChanging end + object chkUpdatecheck: TCheckBox + Left = 16 + Top = 199 + Width = 268 + Height = 17 + Caption = 'Automatically check for updates / Interval [days]:' + Checked = True + State = cbChecked + TabOrder = 9 + OnClick = chkUpdatecheckClick + end + object editUpdatecheckInterval: TEdit + Left = 302 + Top = 197 + Width = 43 + Height = 21 + TabOrder = 10 + Text = '0' + end + object updownUpdatecheckInterval: TUpDown + Left = 345 + Top = 197 + Width = 16 + Height = 21 + Associate = editUpdatecheckInterval + Min = 1 + Max = 999 + Position = 1 + TabOrder = 11 + OnChanging = anyUpDownLimitChanging + end end object TabSheet2: TTabSheet BorderWidth = 5 @@ -674,7 +705,7 @@ object optionsform: Toptionsform end object ColorDialog1: TColorDialog Options = [cdFullOpen, cdSolidColor] - Left = 109 - Top = 229 + Left = 1 + Top = 274 end end diff --git a/source/options.pas b/source/options.pas index fb7ee727..18b0a36b 100644 --- a/source/options.pas +++ b/source/options.pas @@ -92,6 +92,9 @@ type editLogSnip: TEdit; updownLogSnip: TUpDown; labelSqlSnipHint: TLabel; + chkUpdatecheck: TCheckBox; + editUpdatecheckInterval: TEdit; + updownUpdatecheckInterval: TUpDown; procedure ButtonCancelClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure Modified(Sender: TObject); @@ -104,6 +107,7 @@ type procedure anyUpDownLimitChanging(Sender: TObject; var AllowChange: Boolean); procedure btnOpenLogFolderClick(Sender: TObject); + procedure chkUpdatecheckClick(Sender: TObject); private { Private declarations } public @@ -181,6 +185,8 @@ begin reg.WriteInteger(REGNAME_DATAFONTSIZE, UpDownDataFontSize.Position); reg.WriteBool(REGNAME_REMEMBERFILTERS, chkRememberFilters.Checked); reg.WriteBool(REGNAME_LOGTOFILE, chkLogToFile.Checked); + reg.WriteBool(REGNAME_DO_UPDATECHECK, chkUpdatecheck.Checked); + reg.WriteInteger(REGNAME_UPDATECHECK_INTERVAL, updownUpdatecheckInterval.Position); // Close registry key reg.CloseKey; @@ -268,6 +274,9 @@ begin CheckBoxLimit.OnClick(self); updownLogSQLNum.Position := Mainform.GetRegValue(REGNAME_LOGSQLNUM, DEFAULT_LOGSQLNUM); updownLogSnip.Position := Mainform.GetRegValue(REGNAME_LOGSQLWIDTH, DEFAULT_LOGSQLWIDTH); + chkUpdatecheck.Checked := Mainform.GetRegValue(REGNAME_DO_UPDATECHECK, DEFAULT_DO_UPDATECHECK); + updownUpdatecheckInterval.Position := Mainform.GetRegValue(REGNAME_UPDATECHECK_INTERVAL, DEFAULT_UPDATECHECK_INTERVAL); + // Default Column-Width in DBGrids: updownDefaultColWidth.Position := Mainform.GetRegValue(REGNAME_DEFAULTCOLWIDTH, DEFAULT_DEFAULTCOLWIDTH); // Color-coding: @@ -378,4 +387,14 @@ begin ShellExec( '', DirnameSessionLogs ); end; +{** + Updatecheck checkbox was clicked +} +procedure Toptionsform.chkUpdatecheckClick(Sender: TObject); +begin + updownUpdatecheckInterval.Enabled := chkUpdatecheck.Checked; + editUpdatecheckInterval.Enabled := chkUpdatecheck.Checked; + Modified(sender); +end; + end. diff --git a/source/updatecheck.dfm b/source/updatecheck.dfm index 8de8f2e9..8dded478 100644 --- a/source/updatecheck.dfm +++ b/source/updatecheck.dfm @@ -4,7 +4,7 @@ object frmUpdateCheck: TfrmUpdateCheck BorderStyle = bsDialog Caption = 'Check for updates ...' ClientHeight = 273 - ClientWidth = 362 + ClientWidth = 384 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -13,27 +13,30 @@ object frmUpdateCheck: TfrmUpdateCheck Font.Style = [] OldCreateOrder = False Position = poMainFormCenter + OnCreate = FormCreate OnShow = FormShow DesignSize = ( - 362 + 384 273) PixelsPerInch = 96 TextHeight = 13 object lblStatus: TLabel Left = 8 - Top = 245 - Width = 245 - Height = 13 + Top = 240 + Width = 256 + Height = 28 Anchors = [akLeft, akRight, akBottom] AutoSize = False Caption = 'lblStatus' + Layout = tlCenter + WordWrap = True end object btnCancel: TButton - Left = 226 + Left = 270 Top = 240 - Width = 128 + Width = 106 Height = 25 - Anchors = [akLeft, akRight, akBottom] + Anchors = [akRight, akBottom] Cancel = True Caption = 'Cancel' Default = True @@ -43,18 +46,19 @@ object frmUpdateCheck: TfrmUpdateCheck object groupBuild: TGroupBox Left = 8 Top = 123 - Width = 346 + Width = 368 Height = 110 Anchors = [akLeft, akTop, akRight, akBottom] Caption = 'Nightly build' + Enabled = False TabOrder = 1 DesignSize = ( - 346 + 368 110) object btnBuild: TButton Left = 6 Top = 78 - Width = 333 + Width = 355 Height = 25 Anchors = [akLeft, akRight, akBottom] Caption = 'Download nightly build' @@ -65,7 +69,7 @@ object frmUpdateCheck: TfrmUpdateCheck object memoBuild: TMemo Left = 6 Top = 16 - Width = 333 + Width = 355 Height = 60 Anchors = [akLeft, akTop, akRight, akBottom] BorderStyle = bsNone @@ -80,18 +84,19 @@ object frmUpdateCheck: TfrmUpdateCheck object groupRelease: TGroupBox Left = 8 Top = 8 - Width = 346 + Width = 368 Height = 110 Anchors = [akLeft, akTop, akRight] Caption = 'Official release' + Enabled = False TabOrder = 2 DesignSize = ( - 346 + 368 110) object btnRelease: TButton Left = 6 Top = 78 - Width = 333 + Width = 355 Height = 25 Anchors = [akLeft, akRight, akBottom] Caption = 'Download new release' @@ -102,7 +107,7 @@ object frmUpdateCheck: TfrmUpdateCheck object memoRelease: TMemo Left = 6 Top = 16 - Width = 333 + Width = 355 Height = 60 Anchors = [akLeft, akTop, akRight, akBottom] BorderStyle = bsNone diff --git a/source/updatecheck.pas b/source/updatecheck.pas index 9a2d9cb3..92046cd7 100644 --- a/source/updatecheck.pas +++ b/source/updatecheck.pas @@ -4,7 +4,7 @@ interface uses Windows, Messages, SysUtils, Classes, Forms, - Dialogs, StdCtrls, ExtActns, IniFiles, Controls, Graphics; + Dialogs, StdCtrls, ExtActns, IniFiles, Controls, Graphics, Registry; type TfrmUpdateCheck = class(TForm) @@ -16,6 +16,7 @@ type lblStatus: TLabel; memoRelease: TMemo; memoBuild: TMemo; + procedure FormCreate(Sender: TObject); procedure btnBuildClick(Sender: TObject); procedure btnReleaseClick(Sender: TObject); procedure FormShow(Sender: TObject); @@ -27,6 +28,8 @@ type procedure ReadCheckFile; public { Public declarations } + AutoClose: Boolean; // Automatically close dialog after detecting no available downloads + CurrentRevision: Integer; end; implementation @@ -38,6 +41,14 @@ uses helpers, main; {$I const.inc} +{** + Set defaults +} +procedure TfrmUpdateCheck.FormCreate(Sender: TObject); +begin + // Should be false by default. Callers can set this to True after Create() + AutoClose := False; +end; {** Update status text @@ -55,14 +66,15 @@ end; procedure TfrmUpdateCheck.FormShow(Sender: TObject); var TempPath: array[0..MAX_PATH] of Char; + reg : TRegistry; begin Status('Initiating ... '); Caption := 'Check for '+APPNAME+' updates ...'; + CurrentRevision := StrToIntDef(AppRevision, 0); // Init GUI controls btnRelease.Enabled := False; btnBuild.Enabled := False; - btnCancel.Enabled := False; memoRelease.Clear; memoBuild.Clear; @@ -76,16 +88,41 @@ begin // Download the check file Screen.Cursor := crHourglass; - Status('Downloading check file ...'); try + Status('Downloading check file ...'); CheckfileDownload.ExecuteTarget(nil); + Status('Reading check file ...'); ReadCheckFile; - DeleteFile(CheckfileDownload.Filename); - finally - FreeAndNil(CheckfileDownload); - Screen.Cursor := crDefault; - btnCancel.Enabled := True; + if (not groupRelease.Enabled) and (not groupBuild.Enabled) then begin + // Developer versions probably have "unknown" (0) as revision, + // which makes it impossible to compare the revisions. + if CurrentRevision = 0 then + Status('Error: Cannot determine current revision. Using a developer version?') + else + Status('Your '+APPNAME+' is up-to-date (no update available).'); + end else + Status('Updates available.'); + // Remember when we did the updatecheck to enable the automatic interval + reg := TRegistry.Create; + reg.OpenKey(REGPATH, true); + reg.WriteString(REGNAME_LAST_UPDATECHECK, DateTimeToStr(Now)); + reg.CloseKey; + FreeAndNil(reg); + except + // Do not popup errors, just display them in the status label + On E:Exception do + Status(E.Message); end; + if FileExists(CheckfileDownload.Filename) then + DeleteFile(CheckfileDownload.Filename); + FreeAndNil(CheckfileDownload); + Screen.Cursor := crDefault; + + // For automatic updatechecks this dialog should close if no updates are available. + // Using PostMessage, as Self.Close or ModalResult := mrCancel does not work + // as expected in FormShow + if AutoClose and (not groupRelease.Enabled) and (not groupBuild.Enabled) then + PostMessage(Self.Handle, WM_CLOSE, 0, 0); end; @@ -103,8 +140,6 @@ const INISECT_RELEASE = 'Release'; INISECT_BUILD = 'Build'; begin - Status('Reading check file ...'); - // Read [Release] section of check file Ini := TIniFile.Create(CheckfileDownload.Filename); if Ini.SectionExists(INISECT_RELEASE) then begin @@ -118,7 +153,7 @@ begin memoRelease.Lines.Add( 'Note: ' + Note ); btnRelease.Caption := 'Download version ' + ReleaseVersion; // Enable the download button if the current version is outdated - groupRelease.Enabled := ReleaseRevision > StrToIntDef(AppRevision, 0); + groupRelease.Enabled := (CurrentRevision > 0) and (ReleaseRevision > CurrentRevision); btnRelease.Enabled := groupRelease.Enabled; memoRelease.Enabled := groupRelease.Enabled; if not memoRelease.Enabled then @@ -141,7 +176,7 @@ begin // A new release should have priority over a new nightly build. // So the user should not be able to download a newer build here // before having installed the new release. - groupBuild.Enabled := (BuildRevision > StrToIntDef(AppRevision, 0)) and (not btnRelease.Enabled); + groupBuild.Enabled := (CurrentRevision > 0) and (BuildRevision > CurrentRevision) and (not btnRelease.Enabled); btnBuild.Enabled := groupBuild.Enabled; memoBuild.Enabled := groupBuild.Enabled; if not memoBuild.Enabled then @@ -149,9 +184,6 @@ begin else memoBuild.Font.Color := clWindowText; end; - - // Clear status label - Status(''); end;