diff -Nru ddrescueview-0.4~alpha3/changelog.txt ddrescueview-0.4~alpha4/changelog.txt --- ddrescueview-0.4~alpha3/changelog.txt 2016-07-20 03:21:21.000000000 +0000 +++ ddrescueview-0.4~alpha4/changelog.txt 2020-09-01 14:23:54.000000000 +0000 @@ -1,3 +1,19 @@ +#### v0.4 alpha 4 #### +Released 2020-09-01 +- Updated to compile on FPC 3.2.0 without errors. Thanks to Peter Green for the patch. +- It's now possible to select a range on the Zoom Bar using right click dragging, just like on the Block Grid. +- Added an option in the Settings to zoom in on mouse position without centering the Block Grid on that position. + This is now the default. It seems more intuitive when the blocks previously under the mouse + stay under the mouse after zooming in or out. +- Added an Option 'Center on Current Position' to the View menu, which keeps the Block Grid centered on the + current rescue position. Handy to keep the rescue position on screen when zoomed in. + This overrides much of the usual zooming functionality and deactivates interaction with the Zoom Bar. +- Zooming and scrolling in large map files is now considerably faster. +- Application title (as reported to the OS, for the task bar etc.) now shows loaded file name. +- The program will now make a second attempt to refresh the mapfile, when ddrescue is currently rewriting it. +- New application icon in multiple sizes up to 256x256 +- Reduced compiler warnings and hints + #### v0.4 alpha 3 #### Released 2016-07-20 @@ -77,4 +93,4 @@ #### v0.3 #### Released 2013-03-28 -- initial release (after porting to Lazarus) \ No newline at end of file +- initial release (after porting to Lazarus) diff -Nru ddrescueview-0.4~alpha3/debian/changelog ddrescueview-0.4~alpha4/debian/changelog --- ddrescueview-0.4~alpha3/debian/changelog 2020-08-16 10:47:46.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/changelog 2020-10-25 18:26:38.000000000 +0000 @@ -1,3 +1,20 @@ +ddrescueview (0.4~alpha4-2) unstable; urgency=medium + + * Drop build-dependency on lazarus-src, + no longer needed since lazarus 2.0.10+dfsg-3 + + -- Graham Inggs Sun, 25 Oct 2020 18:26:38 +0000 + +ddrescueview (0.4~alpha4-1) unstable; urgency=medium + + * New upstream release + * Drop patch included upstream + * Adjust packaging for new resources + * Add build-dependency on lazarus-src + * Update debian/copyright + + -- Graham Inggs Wed, 02 Sep 2020 18:55:17 +0000 + ddrescueview (0.4~alpha3-4) unstable; urgency=medium [ Peter Michael Green ] diff -Nru ddrescueview-0.4~alpha3/debian/copyright ddrescueview-0.4~alpha4/debian/copyright --- ddrescueview-0.4~alpha3/debian/copyright 2019-01-06 08:32:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/copyright 2020-09-02 20:02:45.000000000 +0000 @@ -4,11 +4,11 @@ Source: https://sourceforge.net/projects/ddrescueview/ Files: * -Copyright: 2013-2016 Martin Bittermann +Copyright: 2013-2020 Martin Bittermann License: GPL-3.0+ Files: debian/* -Copyright: 2015-2019 Graham Inggs +Copyright: 2015-2020 Graham Inggs License: GPL-3.0+ License: GPL-3.0+ diff -Nru ddrescueview-0.4~alpha3/debian/ddrescueview.install ddrescueview-0.4~alpha4/debian/ddrescueview.install --- ddrescueview-0.4~alpha3/debian/ddrescueview.install 2019-01-06 07:53:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/ddrescueview.install 2020-09-02 20:02:45.000000000 +0000 @@ -1,3 +1,3 @@ -debian/ddrescueview.png /usr/share/icons/hicolor/32x32/apps -resources/linux/ddrescueview.desktop usr/share/applications +resources/linux/applications usr/share +resources/linux/icons usr/share source/ddrescueview /usr/bin Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/debian/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/debian/ddrescueview.png differ diff -Nru ddrescueview-0.4~alpha3/debian/manpages ddrescueview-0.4~alpha4/debian/manpages --- ddrescueview-0.4~alpha3/debian/manpages 2019-01-06 07:37:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/manpages 2020-09-02 20:02:45.000000000 +0000 @@ -1 +1 @@ -resources/linux/ddrescueview.1 +resources/linux/man/man1/ddrescueview.1 diff -Nru ddrescueview-0.4~alpha3/debian/patches/series ddrescueview-0.4~alpha4/debian/patches/series --- ddrescueview-0.4~alpha3/debian/patches/series 2020-08-16 09:45:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -use-getters-for-fields-in-other-classes.patch diff -Nru ddrescueview-0.4~alpha3/debian/patches/use-getters-for-fields-in-other-classes.patch ddrescueview-0.4~alpha4/debian/patches/use-getters-for-fields-in-other-classes.patch --- ddrescueview-0.4~alpha3/debian/patches/use-getters-for-fields-in-other-classes.patch 2020-08-16 09:45:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/patches/use-getters-for-fields-in-other-classes.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ -Description: Use getters for fields in other classes. - fpc 3.2 no longer allows properties to directly access fields in other classes. - use getters instead to work around this. -Bug: https://sourceforge.net/p/ddrescueview/tickets/13/ -Bug-Debian: https://bugs.debian.org/968121 -Author: Peter Michael Green -Last-Update: 2020-08-11 - ---- a/source/Parser.pas -+++ b/source/Parser.pas -@@ -64,6 +64,10 @@ - function getMap(): TMap; - procedure postParse(); - procedure setContiguous(mode: Boolean); -+ function getCommentLines(): TStringList; -+ function getVersion(): String; -+ function getMapFileName(): String; -+ function getDomFileName(): String; - public - constructor Create; - destructor Destroy; override; -@@ -75,10 +79,10 @@ - function hasDomFile() : Boolean; - property rescueStatus : TRescueStatus read FRescueStatus; - property map : TMap read getMap; -- property CommentLines : TStringList read FMapParser.FComments; -- property Version : String read FMapParser.FVersion; -- property MapFileName : String read FMapParser.FFileName; -- property DomFileName : String read FDomParser.FFileName; -+ property CommentLines : TStringList read GetCommentLines; -+ property Version : String read getVersion; -+ property MapFileName : String read getMapFileName; -+ property DomFileName : String read getDomFileName; - property ContiguousDomain : Boolean read FContiguous write setContiguous; - end; - -@@ -474,4 +478,24 @@ - hasFile:=Assigned(FMapStream); - end; - -+function TMapParser.getCommentLines(): TStringList; -+begin -+ getCommentLines:=FMapParser.FComments; -+end; -+ -+function TMapParser.getVersion(): String; -+begin -+ getVersion:=FMapParser.FVersion; -+end; -+ -+function TMapParser.getMapFileName(): String; -+begin -+ getMapFileName:=FMapParser.FFileName; -+end; -+ -+function TMapParser.getDomFileName(): String; -+begin -+ getDomFileName:=FDomParser.FFileName; -+end; -+ - end. diff -Nru ddrescueview-0.4~alpha3/debian/rules ddrescueview-0.4~alpha4/debian/rules --- ddrescueview-0.4~alpha3/debian/rules 2019-01-06 07:37:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/rules 2020-09-02 20:02:45.000000000 +0000 @@ -9,11 +9,6 @@ override_dh_auto_build: lazbuild source/ddrescueview.lpi --bm="GNU/Linux Release" --no-write-project -override_dh_auto_install: - # Fix some permissions - chmod -x $(CURDIR)/resources/linux/* - dh_auto_install - override_dh_clean: # Clean up temporary HOME rm -rf $(CURDIR)/tmphome diff -Nru ddrescueview-0.4~alpha3/debian/source/include-binaries ddrescueview-0.4~alpha4/debian/source/include-binaries --- ddrescueview-0.4~alpha3/debian/source/include-binaries 2019-01-06 08:09:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/debian/source/include-binaries 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/ddrescueview.png diff -Nru ddrescueview-0.4~alpha3/readme.txt ddrescueview-0.4~alpha4/readme.txt --- ddrescueview-0.4~alpha3/readme.txt 2016-07-20 03:38:20.000000000 +0000 +++ ddrescueview-0.4~alpha4/readme.txt 2020-08-30 00:23:54.000000000 +0000 @@ -5,8 +5,8 @@ This program is free software released under the GNU GPL. Author: Martin Bittermann -Project page: http://sourceforge.net/p/ddrescueview -Manual: http://sourceforge.net/p/ddrescueview/wiki +Project page: https://sourceforge.net/p/ddrescueview +Manual: https://sourceforge.net/p/ddrescueview/wiki Debian package created by Graham Inggs diff -Nru ddrescueview-0.4~alpha3/resources/linux/applications/ddrescueview.desktop ddrescueview-0.4~alpha4/resources/linux/applications/ddrescueview.desktop --- ddrescueview-0.4~alpha3/resources/linux/applications/ddrescueview.desktop 1970-01-01 00:00:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/resources/linux/applications/ddrescueview.desktop 2020-08-29 23:18:31.000000000 +0000 @@ -0,0 +1,17 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Name=ddrescueview +Icon=ddrescueview +Comment=Graphical viewer for GNU ddrescue map files +Keywords=ddrescue;gddrescue;rescue;recovery;log;logfile;mapfile; +Categories=Utility;DataVisualization;GTK; +Exec=ddrescueview %f + + + + + + + + diff -Nru ddrescueview-0.4~alpha3/resources/linux/ddrescueview.1 ddrescueview-0.4~alpha4/resources/linux/ddrescueview.1 --- ddrescueview-0.4~alpha3/resources/linux/ddrescueview.1 2015-05-19 14:16:02.000000000 +0000 +++ ddrescueview-0.4~alpha4/resources/linux/ddrescueview.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -.TH ddrescueview "1" "2015-05-11" "ddrescueview 0.4" "ddrescueview Manual Pages" -.SH NAME -ddrescueview \- graphical viewer for GNU ddrescue log files -.SH SYNOPSIS -.B ddrescueview -.SH DESCRIPTION -This small tool allows the user to graphically examine ddrescue's log files in a user friendly GUI application. The Main window displays a block grid with each block's color representing the block types it contains. Many people know this type of view from defragmentation programs. -.SH OTHER INFO -ddrescueview project: http://ddrescueview.sourceforge.net/ -.SH AUTHORS -Written by Martin Bittermann - -This manual page was written by Graham Inggs -.SH COPYRIGHT -Copyright 2013-2015 Martin Bittermann - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff -Nru ddrescueview-0.4~alpha3/resources/linux/ddrescueview.desktop ddrescueview-0.4~alpha4/resources/linux/ddrescueview.desktop --- ddrescueview-0.4~alpha3/resources/linux/ddrescueview.desktop 2015-05-19 14:16:02.000000000 +0000 +++ ddrescueview-0.4~alpha4/resources/linux/ddrescueview.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -[Desktop Entry] -Categories=Utility; -Keywords=ddrescue;gddrescue;recovery;log;logfile; -Comment=graphical viewer for GNU ddrescue log files -Exec=ddrescueview -Icon=ddrescueview -Name=ddrescueview -Type=Application -Version=1.0 diff -Nru ddrescueview-0.4~alpha3/resources/linux/ddrescueview.xpm ddrescueview-0.4~alpha4/resources/linux/ddrescueview.xpm --- ddrescueview-0.4~alpha3/resources/linux/ddrescueview.xpm 2015-05-19 14:16:02.000000000 +0000 +++ ddrescueview-0.4~alpha4/resources/linux/ddrescueview.xpm 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -/* XPM */ -static char * ddrescueview_xpm[] = { -"32 32 12 1", -" c None", -". c #000000", -"+ c #6F6F6F", -"@ c #777777", -"# c #5F5F5F", -"$ c #C5C5C5", -"% c #007C00", -"& c #FF0000", -"* c #6A1691", -"= c #A20000", -"- c #00FFF0", -"; c #8E8E8E", -" ............................ ", -" .++++++++++++++++++++++++++++. ", -".@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.", -".##############################.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".%%$%%$%%$&&$**$&&$&&$&&$&&$%%$.", -".%%$%%$%%$&&$**$&&$&&$&&$&&$%%$.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".%%$%%$%%$**$&&$&&$**$**$**$&&$.", -".%%$%%$%%$**$&&$&&$**$**$**$&&$.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".&&$%%$%%$%%$%%$%%$%%$%%$%%$%%$.", -".&&$%%$%%$%%$%%$%%$%%$%%$%%$%%$.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".%%$%%$%%$%%$==$%%$%%$%%$%%$**$.", -".%%$%%$%%$%%$==$%%$%%$%%$%%$**$.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".**$%%$%%$%%$%%$==$%%$%%$%%$%%$.", -".**$%%$%%$%%$%%$==$%%$%%$%%$%%$.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".%%$%%$%%$==$==$==$%%$%%$%%$%%$.", -".%%$%%$%%$==$==$==$%%$%%$%%$%%$.", -".$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$.", -".%%$%%$%%$%%$%%$%%$%%$%%$%%$%%$.", -".%%$%%$%%$%%$%%$%%$%%$%%$%%$%%$.", -".$$$$$$$$$$$----$$$$$$$$$$$$$$$.", -".%%$%%$%%$%%-;;-;;$;;$;;$;;$;;$.", -".%%$%%$%%$%%-;;-;;$;;$;;$;;$;;$.", -".$$$$$$$$$$$----$$$$$$$$$$$$$$$.", -".##############################.", -".##############################.", -"................................"}; Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/128x128/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/128x128/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/16x16/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/16x16/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/22x22/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/22x22/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/24x24/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/24x24/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/256x256/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/256x256/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/32x32/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/32x32/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/48x48/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/48x48/apps/ddrescueview.png differ Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/resources/linux/icons/hicolor/64x64/apps/ddrescueview.png and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/resources/linux/icons/hicolor/64x64/apps/ddrescueview.png differ diff -Nru ddrescueview-0.4~alpha3/resources/linux/linux-readme.txt ddrescueview-0.4~alpha4/resources/linux/linux-readme.txt --- ddrescueview-0.4~alpha3/resources/linux/linux-readme.txt 1970-01-01 00:00:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/resources/linux/linux-readme.txt 2020-08-30 22:11:32.000000000 +0000 @@ -0,0 +1,18 @@ +Supplementary Linux files +========================= + +The files in this folder (except this readme file) provide +additional integration into common Linux desktop environments. + +They include + - A manpage + - Icons for the program in various sizes + - A desktop file for starting the program through your main menu. + To make this work, you need to have placed the ddrescueview + executable in a directory on the $PATH, such as /usr/bin. + +Copy the three directories - applications, icons, man - into your /usr/share directory. +These directories should already exist on your installation. Merge the new files into them. +You will need elevated privileges to perform this operation. +Afterwards, you may need to rebuild your icon cache, using + update-icon-caches /usr/share/icons/hicolor diff -Nru ddrescueview-0.4~alpha3/resources/linux/man/man1/ddrescueview.1 ddrescueview-0.4~alpha4/resources/linux/man/man1/ddrescueview.1 --- ddrescueview-0.4~alpha3/resources/linux/man/man1/ddrescueview.1 1970-01-01 00:00:00.000000000 +0000 +++ ddrescueview-0.4~alpha4/resources/linux/man/man1/ddrescueview.1 2020-09-01 14:25:15.000000000 +0000 @@ -0,0 +1,53 @@ +.TH ddrescueview "1" "2020-09-01" "ddrescueview 0.4" "ddrescueview Manual Pages" +.SH NAME +ddrescueview \- graphical viewer for GNU ddrescue map files + +.SH SYNOPSIS +.B ddrescueview +[\fIOPTIONS\fR] [[-m domain-mapfile] rescue-mapfile] + +.SH DESCRIPTION +This small tool allows the user to graphically examine ddrescue's map files in a user friendly GUI application. The Main window displays a block grid with each block's color representing the block types it contains. Many people know this type of view from defragmentation programs. +.PP +\fIOPTIONS\fR: +.TP +-r (off|5s|10s|30s|1m|2m|5m) +Set refresh interval, e.g. -r 30s +.TP +-lp +Show (bottom) log panel on start +.TP +-gs (4|6|8|10|12|14|16|20|24) +Set grid size on start +.TP +-ub +Use binary unit prefixes instead of decimal +.TP +-x left +X position of window on screen, in pixels +.TP +-y top +Y position of window on screen, in pixels +.TP +-w width +ClientWidth of window, in pixels +.TP +-h height +ClientHeight of window, in pixels +.TP +-safe +Turn off optimizations + +.SH "SEE ALSO" +Project website: +.br +Full documentation at: + +.SH AUTHORS +Written by Martin Bittermann + +This manual page was written by Graham Inggs +.SH COPYRIGHT +Copyright 2013-2020 Martin Bittermann + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff -Nru ddrescueview-0.4~alpha3/source/About.lfm ddrescueview-0.4~alpha4/source/About.lfm --- ddrescueview-0.4~alpha3/source/About.lfm 2016-07-18 02:37:44.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/About.lfm 2020-08-30 21:30:41.000000000 +0000 @@ -15,7 +15,7 @@ OnShow = FormShow Position = poMainFormCenter ShowHint = True - LCLVersion = '1.4.0.4' + LCLVersion = '2.0.10.0' object AboutPanel: TPanel Left = 6 Height = 244 @@ -41,8 +41,8 @@ 'This program is free software released under the GNU GPL' '' 'Author: Martin Bittermann' - 'Project page: http://sourceforge.net/p/ddrescueview' - 'Manual: http://sourceforge.net/p/ddrescueview/wiki' + 'Project page: https://sourceforge.net/p/ddrescueview' + 'Manual: https://sourceforge.net/p/ddrescueview/wiki' '' 'Written in Object Pascal and built using the Lazarus IDE' ) @@ -72,40 +72,161 @@ BorderSpacing.Top = 4 BorderSpacing.Right = 8 Picture.Data = { - 055449636F6E3604000000000100020010101000010004002801000026000000 - 2020100001000400E80200004E01000028000000100000002000000001000400 - 000000000000000000000000000000000000000000000000000000000000A200 - 91166A000000FF00007C00006F6F6F00777777008E8E8E00C5C5C500F0FF0000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0888888889999880044844844977977004484484497797700888888889999880 - 0118118118448440011811811844844008888888888888800448448118448440 - 0448448118448440088888888888888004481184483382200448118448338220 - 0888888888888880065555555555555000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000800100002800000020000000 - 4000000001000400000000000000000000000000000000000000000000000000 - 000000000000A20091166A000000FF00007C00005F5F5F006F6F6F0077777700 - 8E8E8E00C5C5C500F0FF00000000000000000000000000000000000000000000 - 0000000000000000000000000000000005555555555555555555555555555550 - 05555555555555555555555555555550099999999999AAAA9999999999999990 - 044944944944A88A8898898898898890044944944944A88A8898898898898890 - 099999999999AAAA999999999999999004494494494494494494494494494490 - 0449449449449449449449449449449009999999999999999999999999999990 - 0449449449119119119449449449449004494494491191191194494494494490 - 0999999999999999999999999999999002294494494494491194494494494490 - 0229449449449449119449449449449009999999999999999999999999999990 - 0449449449449119449449449449229004494494494491194494494494492290 - 0999999999999999999999999999999003394494494494494494494494494490 - 0339449449449449449449449449449009999999999999999999999999999990 - 0449449449229339339229229229339004494494492293393392292292293390 - 0999999999999999999999999999999004494494493392293393393393394490 - 0449449449339229339339339339449009999999999999999999999999999990 - 0555555555555555555555555555555007777777777777777777777777777770 - 0066666666666666666666666666660000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 0000000000000000000000000000000000000000000000000000000000000000 - 00000000000000000000000000000000000000000000000080000001C0000003 + 1754506F727461626C654E6574776F726B477261706869632D13000089504E47 + 0D0A1A0A0000000D494844520000002000000020080300000044A48AC600000F + 737A5458745261772070726F66696C6520747970652065786966000078DAAD9A + 6972E43A0E84FFF314730471278FC335626E30C79F0FA06AB1DBBDB8DFB3A3AD + 924A2241209148506DD6FFFEBBCD7FF809D90713622EA9A674F1136AA8AEF1A1 + 5CAF9F751FCF357B05FDFBF8B1F75F6BBEFCC271F41CFDB998C3FDADBFAF3FEE + 4FCF23037DF1858D9F1EF0CF69DCFBC4B9DDD7DDE53E58B4A7B5D7FB4F79FDDB + 7B96BDD7595D0B0937A4B3A83385790CC38D1D2F797D2CF19BF917F99CF5B7F2 + 5BAE760D1BAE798DABF33B6CB5CEFA6BDB60A7B1CD6EBBECE438ECC0C6E096CB + 1C9D1BCEEBB5E2B3AB6EF8CB5B1FE4D76E977DF5D317EFFC70CB7BA2E6DDD316 + ABF3569D6FD8C2CCD372ABB30C6679E497BFE67737FCC9EFDEE3C24738B8A89F + EC09B07312072B6EF4F297DB0888DD77DCA23AF8F1FBFC316F81F54430AA9B0B + 0B6C573F43F4685FD8F20A00CF7D91E3C197CD53A2E6142581B923C6584F08AE + 647DB4C95ED9B96C6DF0AE10A086E5CE07D789808DD14D8C74C1FB446C0A3862 + 6E9EC956EF75D19DEBA40AF1893EF94C6CAA6F042B84087E722860A8451F438C + 31C51C4BACB199E4534831A59493E45CCB3E871C73CA39975C732BBE84124B2A + B994524BABAE7A5232D654732DB5D6D698B305D362E3E9C61DAD75D77D0F3DF6 + D4732FBDF63680CF08238E34F228A38E36DDF433CC38D3CCB3CC3ADBB20B2899 + 15565C69E555565D6D83B5ED77D871A79D77D975B767D4EEA8FEF0FB8DA8D93B + 6A4E2325F7E567D4B89AB30CA44358E199283123622E58229E250200DA49CCAE + 624370123989D9551D59111D464689CDB457333611C2B0AC8BDB3E63F78ADC1F + C7CDE0EBDFC5CDFD49E48C84EE5F889C33CB7F8ADB17519BC284432376B2507C + 7A79B20F6C3757DA6AC9407ECD7506C12CBEA8D04FDBCDA7DA0321F72DDAB883 + 78434FB79E5E310ACB6EB8D6F5D99DDC6B4053A792749227C2C28560C7357DF8 + 70521965B92DF7F969E58494E424DC0F8D680D37DAB0657C1B74FCD4867E1975 + 723709D2C396B577ACE7344E1B7113A1E7543E98E9B9DFFB99FB25CF6799F6B2 + 6A1066DA99AFA92769CA89ED7A12373492C544A955989FBD39B705B1D4EB1789 + 5A128BBD3FBA982E5D4CE74A3AEBEA3E8C362A5EBEE0903A6361785224AD48B8 + 07B68B9565029011CF498FBEF592F5914E106A5D7D16D707212648BBCDD657A8 + F2C134C0E4921854E3CCF827BB6565B9CCB36A928C287EA43C53AE7D32749B33 + 94C5A87EB5927ABFD6C2D065B8E2426B394007985EB965C5060C5BBAC8B29665 + 352561E112C3C449B97AC23FA70B8C4136E00A6864C719E1F3E40997EBA52A9C + D64C8C07ABB68BF1E26E4A5FA096F41DAC70AE1E59A44D7DF49156C27E838776 + 06C51D306FEA6A8D658F9957CBA32F20BFF3EA69B6B9C2EE7591A562CD9AF2C7 + 355B17A1ED7BAD656602235BEA341683BAD6E56CF40A1955FD8CC7FB942CC0AF + 16BF86452258CF1D8424679FC4E1C588C7977C6AD1B9093AC8C488DBA67C8037 + 6CA15EE4810D922999B8789B9F91C007D9562C492651C73B8B91E5545D43DABD + 6CFC35C83FDF16C62DC77A93E6642608115F8E4DED61A8218088A94E336202E2 + 51020430012071B83FC5D4B80D0EA9DDB74DCEADBC110F99F9A67875B2F80CEF + 35D2689A0A34FA1C595209F84CDCD859384896A5F9B872967F21424B54D4CCE8 + 7D3892D2B5D28BDC9447AA719B843706E91DD700F91B4F558C737DC324035661 + 5634CCCA1E249016DDC631842C2A29891FB1500292BB4918B4C694F8571C9217 + 6EF0D3E1A95421B9198620D401AF4274FA049A1B4E84F72AF4095BF62C4F7B93 + 06E4B022EB959103B80F200EDB57CFFAA154BB28341F12ABC1DDE81946A73A76 + D2667533A8202462544F6D9B1DA1F61BD6AE7B0E00197BC66468D7C559B26403 + 59425AD7EC67F3733409DD48CDCC69F3E5E7B52A0117DC4712DB074227F945B6 + 4865B83F49F831B3D9D659F2D80E9F16810FE0311FF053472F69900C59F1A6CF + 0E988444DB4E60050424EF1B6E4B12B43537E62D68C84C028F4964FB2E1D2730 + C9E694D8DA06487AC5679417027CEDB286CDDD497636894EF0DBE7814AB56B18 + 00468ACCB529557E0CE031286E51E6E92BC611E68E0E244E229D3DEE9A52F276 + F584B7EE1211C33BCFB019A8891104784A464E904EDCA3AC8E850EF1CADCD8DE + 2D184BD7B25C9CDBE1D5A419FA4855031B544B3C25DE49E29DE0198A7246B497 + 9D2FF5128E6109427C5AF62E52B1AC7491B44BB855A2696891AEF8FE84AF8564 + E84572C6520EEC6F46B807307F3382C4633C2E90DD023D2990511FF2F86D39DC + 098B2244238C2CD927F8A228E0ABD9283D30016379612C481282AAC427AD7599 + 0A9775A8AB90F664F1723095859D03FA6195B403C8EAB81E794F6C03D7D79A82 + 741238B6014222956D6C7044714C81C606B6D815B2B6D253F22C25409ECD5CE6 + D936254D395FA9E018593FA5BB563B444BF968EE23F44D214EC25DB44B0166B1 + 92C46E6DB982D5163954A8D993593BB90F2A5BC97467CAF058A436308194AB42 + E5BF0AB51B82430D4899ECD2ABE50D9E581ACA604B65F6DBB6B6E745B9A29824 + 3D185F3AA6472591097BEE9E4ABC9E83A3C3F21A8F3370D6A49314F7A1DEF625 + DA59E640D5EA34695D22BC5C1984076AA2C85D5426B901BAD8AADE70D3C37218 + 1D797C1CD517FEC425467D227DA0D630B7A976734A2F5874E4E6190F9B852B3D + 1C798C57D3A978548FDBF3E41AEC6A9DF872202252D5037041FE951730F498AB + 68CF7B5D7323C5B1BDEBB98D5491D8040A9F8381849360482C543811DA2074DD + 23CCB94796869BD50C821B70923577B996DA6635C052A92C4E8A2F51403100F9 + B4D34DEA41EF52D2607D04B4B2893C9B69B3A21435D20C7D96FA4B03D1AAF2F4 + 824CE6C123D500480BA3E068294A788640AD063C26DD9188857C5C07A94ED66C + A7BF3D485A43E41B1E9F0DCC4AC9A265E082D0194FBAED666F51CC3652CC4E58 + 6D09F2507230186BE70B79A4320F8F083B725D97D3954304088AFEA4303178D2 + DE7E82045713A1EF15626A684F8A30812FD5D3D13F646A15240B6D6AAD0A5AAB + C835E2090C6BF4958AB4CA03F1F4BCFA0CECEF792609EC028A0B350538E093B0 + 94C9AA9477D93541D5A269F7AA82DDD04FA2D8AA18F42D3FACA19D69D80358AD + 48927D2409119C22EF4046337F6B8B58B23C6C13B99772A238A2F159027C9CCB + 19427653049420D2B0EF88870B46B9621AA2DD05EE0E86D4FB92219965D68DAA + A5CA306741604EA2E56F3EAAFCA2FC08177993297DAD8B08B16D40118958810C + B2163EAA7037B92AEA0B412D83B4F9188416942FF3F95615C1F2E89B6DD11948 + 49F5292C362C80E4AEA94BDA4D4AA75CBDC056EA452A3F85111E2021B2781631 + 0559200B921538E753A6231CE50C5F77753CB55E6783942C6566A1F0C80884B6 + C8747257278B1E2F68E1CF1280AC01204AA5190D98D828B709598AF756D0C5CD + 06375094C638DCB4C9486A1E096889E2C4E11B8F017942658E524574A0548523 + C4A30FBA14514D979B45C35E982D8FA0A4C2AD6D49275D8F38B7190544D1A485 + 24B1ECF84EC01A85104F78D54414C2A3305809540D2B497CE1275A882356945D + 8E5619290624C37A3C427AD69EE48986E2E6064979BC2F7EAA4E329EB470D628 + AFE81C24A5D095309ED28A4B6A0B220FAC51AB5ED6505AC8071C9A50E4A2F344 + FA256D7EB6363FED6F6CB9CB89D9569609F140701E22AE4CB39764D0F4EF1D12 + D87228E1A08759FC0AD4C72992965680CB0C947D29E0015D7C94766A116902CD + 0BE61669E3F24DDE8342311571A4078553FA42EF7291DD0B73AA21E893670B0F + F0AC97168E065DF26B8AF4D0E4509D446DA16B82930F7EE5B07154DBA6CBE6C0 + 243FFC7254A14AE1F55AD6C9903B51BC8BAF1A29748F6E91E9C53445CF705269 + AFAFC6FFFEF0E635BE747B323EEA390DDF9F992B07384038FBF622C9AFE38B32 + 78CC607EBE0230F4D51A7EB204F3710DEF737C6F0AF39C8306624D2707A049B5 + 277577826A4453C9F1DA6FBEA3B67DF49D37AD075CD00A39FC5446761FDB4EE7 + 277B5D621B12674B460AD51FA667A85840317DE0324ACD87D174E13CB17C165A + EB47BEA2465AAC055264252F61A17545385E9FA5A9394EA0C84B164105BD4B73 + DA4A8A1B4D296CFA901569DF7DF5A5C443EB255DE6A2C3C67FCD1CED15582A86 + 165A104DC1A1FB085475CA5B22F5FBE1DA38946905F28F524D1112FE64696422 + 53546A5A82CA2F64108E3A5B235BB7465EDB0A67064BE7817968D12075639D5A + 68EEC2210074EAD386CC9275B697A6AA20F0775E320FA87CDB4B82A08E117720 + 4D9157087EA8A79EB1D4507E2F98E627D1FCB699E64B3B6FC0A9A11FCDFC9403 + E8DF162E3935724E8B8640F7CBA2354553406E5988B1C6D34F91F794F3B44431 + 5429C0EB87DA13648FED92F64DDAB869CBD0D186A066CA831EF9793A2C8463AD + B7FA10477D2A056648FBA50A39CA17B3F4AD8EBF2B81155DA9128366FE9487A2 + 7D993E3111E6C36691D5E621272EE075B0286D3A586CB245C1B7601117DEBD1A + A507817145D1F34F35214F39556C208EB820C14434EBB2C574AB8D031913F38C + 08092221AECF6FAED79CD314919D513465220D82942415FBA4C754B0BC174F72 + E3E46190CDA485FC6A02A21B0B799AA90B7BCA0A656ECD3ED97A205695F5D1BB + A80141F3CACA7EA57D34A6310054D66A62D33D9329DA15BACD7FEB27238EFAB9 + 9FA4B73ADD0F244373B195B10FE1D4AE0115414640CD2F22FAAD809A5F4474EF + 3F30138DED4E53B3B79EBE6CFD043E9B235896C3922D932242AA2391E239DA7B + BFE034C7FE870D83942390E7AFA50790264EB6074EEC447B2CDD9AF6A7D92A01 + 51651E5B12FF7447C23CB624B40B4EEF737C6F0AF3FB5D8F3F9BC2FC938D95F7 + 29CCDF2CE3AB29CC1F2DE305810D71AEB27EC480794D7C63E0F708D03D948380 + 21AF75747F041C4993F3EAB56144FA4420D9CFBE8558647547E3640F840E3367 + 4A886C8286933D708F39AF2DE6C7D71627EB6E275C5D76389AE48F0ADD28F923 + FB1BEB55A626750D9B55C59F6D14CDF2A789F28EA37F3671AAD6CF7E8A5A888B + FAE57A82B3296396929282B40A59772AC407BA57B19E1BEFE7DD17B192775BD2 + 46C5B3BF9CE4BF22E09E64F2FBDB0C299DBA1DBDE2BC093B17141B91D52D4E96 + 2B2FD16E361769725DF6DC681E5FFCEAA673FDAD6F97FF11B206EBF28A0B798F + 676CACDCB2E7FD72ED2E71CBBE98E68D68A484B7D3B63EA5D91D1579E3A77B4F + C26CEFF4AD7B4F8784D7ABC38E5A57C56937A306DD7A8251495A7485EC8C4FD4 + 9ADBB75A7BF4D755CB9178ED652D98FC548FB9413659CEFBAB7DDBAA4B68187B + 87E8C4B8647D979CA8511A629513557AD9879C30BA1215148FE062AFE3417D33 + D28BC4971644DEB6DC7BEE59AE0BF3CBB6BBBCBA546169F07CA5125E8F501DA7 + C713C9F3F971FD97F798D74DCF14D7B399D1B9CEE943F27AD1FEE6CCFCF9ADBF + 3E33FFCE3020FBAB2FF39077C17A4670287EFF07B081741DB339E04D000001E6 + 504C54450000000303030404050C041111051718111E261D2AA200002C2C2C20 + 20FFA200AC323335343338283D333B37403F3E443F3E45FF1700194FDB36593D + 1554FFF327015353545C5D5F5C5D655F6062606060C94D0668696A6B6C6D6D6D + 6FE042C96D6E6E7272727676787A7A7D797B7F80808081828280828682838685 + 878C86878A8989898A8B8F8C8C8C8D8E8F909090909193939393949494959595 + 96969694969E96979A97979700BEF798989898989970A96B99999966AE71989B + A19B9C9EFF8F009EA1A7A1A1A137CB37A0A1AAA2A2A2A4A4A4A5A5A5A6A6A6A8 + A8A800E73620E020AAAAAAABABAB0CEA13AAACB3ACACAC0FEA11A9ADB3AAADB2 + ADADAD2DE50CAFB0B1B1B1B1B2B2B2B0B3BA19EF20B2B3B78BC84FB2B4B7B4B4 + B400FF00B7B7B700EBFFB6B9C0B9B9B9BABABABBBBBBBABCC500FF64BDBDBDBE + BEBEBBBFC7C1C1C1C2C2C2C4C4C4C5C5C500FFF0A9E000C6C9D2C9C9C9C7CBD5 + CBCBCBCCCDD0CFD4DAD3D6DAD9DADCD9DBDDDADBDDDADBDED9DBE2DBDCDFDBDC + E0DBDDE0DBDDE1DCDDE1DCDDE2DBDEE2DCDEE2DCDEE3DCDEE4DCDFE3DCDFE4DD + DFE3DDDFE4DCE0E4DDE0E4DEE0E6DEE0E7DDE1E6DEE1E7DEE1E8DEE2E8DEE2E9 + DFE2E8DFE2E9DFE3EADFE3EBE0E3EAFFEE00E0E4ECE0E4EDE0E5EEE1E5EEE1E6 + EFE6E6E6E4E8F1EFF5F93B5806FD0000000174524E530040E6D8660000017649 + 44415438CB636060E0C00318808023253539212224C0CDD2C4C418088C0C0D8D + 0C8DCC6D9CC2437CCD812A38724B4A8AF2723253E3424202027C7D7D7DDCDCDC + 5DDD3C3C4332B273727339183874F102A082C958C182341E6EBEE285D3410A9C + E739DA69AA24CD9D3377F66CED59EAFE41C19165D3B38403E3BD780BC10AA6CC + 98366DC68CC9D3A64E9E3A69CAC4891326D494F7F5B246C51738480B801508F6 + 6B69488AEBF47475B777CC6C578E351393896E668C8F8F91E7E2072B68E9EAEA + 686BEF6C69696D6A69686C6C68A8AFAFAD63898A4FB710822848AC959335B057 + 2AADAEACAE12A992D5B352500BAB90B0F58B0FB576998ED317734D9999D84CC1 + BE50C40B800ABCBD55BDBDA5804854548A931344C2115010A84054948002A009 + 52B801B21570ED40060401D940055C5C0414106F0504B1B34B2173917D814B01 + F15600F542102E2B7029E0E424CD176888480530F3F28100AF15F9FAFA402485 + 8C800AF4F5092840320FBB15F3F1020EBC991F04005DD4E018B77D3A90000000 + 0049454E44AE426082 } Stretch = True end diff -Nru ddrescueview-0.4~alpha3/source/About.pas ddrescueview-0.4~alpha4/source/About.pas --- ddrescueview-0.4~alpha3/source/About.pas 2016-07-18 02:37:44.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/About.pas 2020-08-30 21:30:41.000000000 +0000 @@ -1,7 +1,7 @@ (* About.pas - About Box unit - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. diff -Nru ddrescueview-0.4~alpha3/source/BlockInspector.lfm ddrescueview-0.4~alpha4/source/BlockInspector.lfm --- ddrescueview-0.4~alpha3/source/BlockInspector.lfm 2016-07-18 02:59:08.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/BlockInspector.lfm 2020-08-28 21:21:45.000000000 +0000 @@ -1,7 +1,7 @@ object BlockForm: TBlockForm - Left = 1181 + Left = 1249 Height = 263 - Top = 833 + Top = 171 Width = 460 BorderIcons = [biSystemMenu] Caption = 'Block inspector' @@ -17,7 +17,7 @@ OnShow = FormShow Position = poMainFormCenter ShowHint = True - LCLVersion = '1.4.0.4' + LCLVersion = '2.0.10.0' object TopPanel: TPanel Left = 6 Height = 23 @@ -34,7 +34,7 @@ Left = 33 Height = 23 Top = 0 - Width = 66 + Width = 88 Align = alLeft BorderSpacing.Left = 4 OnChange = BlockEditChange @@ -53,10 +53,10 @@ OnDblClick = lblBlockHeadlineDblClick end object EditBlockInfo: TEdit - Left = 103 + Left = 125 Height = 15 Top = 4 - Width = 341 + Width = 319 Align = alClient BorderSpacing.Around = 4 BorderSpacing.CellAlignVertical = ccaCenter diff -Nru ddrescueview-0.4~alpha3/source/BlockInspector.pas ddrescueview-0.4~alpha4/source/BlockInspector.pas --- ddrescueview-0.4~alpha3/source/BlockInspector.pas 2016-07-18 02:59:08.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/BlockInspector.pas 2020-08-28 21:21:45.000000000 +0000 @@ -1,7 +1,7 @@ (* BlockInspector.pas - Grid Block Inspector unit - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. Binary files /tmp/tmp9sPrSv/y4lGbvCiif/ddrescueview-0.4~alpha3/source/ddrescueview.ico and /tmp/tmp9sPrSv/GaQzcMCu3l/ddrescueview-0.4~alpha4/source/ddrescueview.ico differ diff -Nru ddrescueview-0.4~alpha3/source/ddrescueview.lpi ddrescueview-0.4~alpha4/source/ddrescueview.lpi --- ddrescueview-0.4~alpha3/source/ddrescueview.lpi 2016-07-19 03:11:44.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/ddrescueview.lpi 2020-09-01 14:33:16.000000000 +0000 @@ -1,18 +1,21 @@ - + - - - + + <ResourceType Value="res"/> <UseXPManifest Value="True"/> + <XPManifest> + <TextName Value="ddrescueview"/> + <TextDesc Value="A graphical viewer for GNU ddrescue map files."/> + </XPManifest> <Icon Value="0"/> </General> <i18n> @@ -20,18 +23,17 @@ </i18n> <VersionInfo> <UseVersionInfo Value="True"/> - <AutoIncrementBuild Value="True"/> <MinorVersionNr Value="4"/> - <BuildNr Value="93"/> + <BuildNr Value="94"/> <Attributes pvaPreRelease="True"/> - <StringTable Comments="Graphical viewer for GNU ddrescue log files" InternalName="ddrescueview" LegalCopyright="GPL v3" ProductName="ddrescueview" ProductVersion="0.4 alpha 2"/> + <StringTable Comments="Graphical viewer for GNU ddrescue mapfiles" InternalName="ddrescueview" LegalCopyright="GPL v3" ProductName="ddrescueview" ProductVersion="0.4 alpha 4"/> </VersionInfo> - <MacroValues Count="1"> - <Macro1 Name="LCLWidgetType" Value="win32"/> - </MacroValues> - <BuildModes Count="3" Active="Common Debug (huge executable)"> - <Item1 Name="Win32 Release" Default="True"/> - <Item2 Name="GNU/Linux Release"> + <BuildModes Count="3"> + <Item1 Name="GNU/Linux Release" Default="True"/> + <Item2 Name="Win32 Release"> + <MacroValues Count="1"> + <Macro1 Name="LCLWidgetType" Value="win32"/> + </MacroValues> <CompilerOptions> <Version Value="11"/> <PathDelim Value="\"/> @@ -45,7 +47,9 @@ </Parsing> <CodeGeneration> <SmartLinkUnit Value="True"/> - <TargetOS Value="linux"/> + <TargetProcessor Value="80386"/> + <TargetCPU Value="i386"/> + <TargetOS Value="win32"/> <Optimizations> <OptimizationLevel Value="3"/> </Optimizations> @@ -53,6 +57,7 @@ <Linking> <Debugging> <GenerateDebugInfo Value="False"/> + <UseLineInfoUnit Value="False"/> <StripSymbols Value="True"/> </Debugging> <LinkSmart Value="True"/> @@ -64,6 +69,11 @@ </Win32> </Options> </Linking> + <Other> + <CompilerMessages> + <IgnoredMessages idx5091="True" idx5024="True" idx4080="True" idx4079="True"/> + </CompilerMessages> + </Other> </CompilerOptions> </Item2> <Item3 Name="Common Debug (huge executable)"> @@ -98,6 +108,11 @@ </Win32> </Options> </Linking> + <Other> + <CompilerMessages> + <IgnoredMessages idx5091="True" idx5024="True" idx4080="True" idx4079="True"/> + </CompilerMessages> + </Other> </CompilerOptions> </Item3> <SharedMatrixOptions Count="1"> @@ -107,30 +122,23 @@ <PublishOptions> <Version Value="2"/> <DestinationDirectory Value="$(ProjPath)\published\"/> - <IgnoreBinaries Value="False"/> - <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml|bmp|ico)"/> - <UseExcludeFileFilter Value="True"/> - <ExcludeFileFilter Value="*.(bak|ppu|o|so|exe|compiled|res|obj|or|a);*~;backup"/> - <SaveClosedEditorFilesInfo Value="True"/> + <CompressFinally Value="False"/> </PublishOptions> <RunParams> - <local> - <FormatVersion Value="1"/> - </local> + <FormatVersion Value="2"/> + <Modes Count="1"> + <Mode0 Name="default"/> + </Modes> </RunParams> <RequiredPackages Count="1"> <Item1> <PackageName Value="LCL"/> </Item1> </RequiredPackages> - <Units Count="16"> + <Units Count="8"> <Unit0> <Filename Value="ddrescueview.lpr"/> <IsPartOfProject Value="True"/> - <TopLine Value="9"/> - <CursorPos Y="43"/> - <UsageCount Value="218"/> - <Loaded Value="True"/> </Unit0> <Unit1> <Filename Value="GUI.pas"/> @@ -138,34 +146,14 @@ <ComponentName Value="MainForm"/> <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> - <UnitName Value="GUI"/> - <IsVisibleTab Value="True"/> - <EditorIndex Value="8"/> - <TopLine Value="242"/> - <CursorPos X="67" Y="271"/> - <UsageCount Value="218"/> - <Loaded Value="True"/> - <LoadedDesigner Value="True"/> </Unit1> <Unit2> <Filename Value="Parser.pas"/> <IsPartOfProject Value="True"/> - <UnitName Value="Parser"/> - <EditorIndex Value="4"/> - <TopLine Value="438"/> - <CursorPos X="11" Y="458"/> - <UsageCount Value="218"/> - <Loaded Value="True"/> </Unit2> <Unit3> <Filename Value="Shared.pas"/> <IsPartOfProject Value="True"/> - <UnitName Value="Shared"/> - <EditorIndex Value="5"/> - <TopLine Value="113"/> - <CursorPos X="31" Y="118"/> - <UsageCount Value="218"/> - <Loaded Value="True"/> </Unit3> <Unit4> <Filename Value="About.pas"/> @@ -173,13 +161,6 @@ <ComponentName Value="AboutBox"/> <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> - <UnitName Value="About"/> - <EditorIndex Value="3"/> - <TopLine Value="29"/> - <CursorPos X="51" Y="41"/> - <UsageCount Value="218"/> - <Loaded Value="True"/> - <LoadedDesigner Value="True"/> </Unit4> <Unit5> <Filename Value="BlockInspector.pas"/> @@ -187,216 +168,21 @@ <ComponentName Value="BlockForm"/> <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> - <UnitName Value="BlockInspector"/> - <EditorIndex Value="9"/> - <TopLine Value="10"/> - <CursorPos X="62" Y="27"/> - <UsageCount Value="218"/> - <Loaded Value="True"/> - <LoadedDesigner Value="True"/> </Unit5> <Unit6> <Filename Value="imgblockstore.pas"/> <IsPartOfProject Value="True"/> <UnitName Value="ImgBlockStore"/> - <EditorIndex Value="7"/> - <TopLine Value="87"/> - <CursorPos X="28" Y="262"/> - <UsageCount Value="425"/> - <Loaded Value="True"/> </Unit6> <Unit7> - <Filename Value="C:\Tools\Lazarus\lcl\include\application.inc"/> - <EditorIndex Value="-1"/> - <TopLine Value="984"/> - <CursorPos X="3" Y="992"/> - <UsageCount Value="4"/> - </Unit7> - <Unit8> <Filename Value="settings.pas"/> <IsPartOfProject Value="True"/> <ComponentName Value="SettingsForm"/> <HasResources Value="True"/> <ResourceBaseClass Value="Form"/> <UnitName Value="Settings"/> - <EditorIndex Value="6"/> - <TopLine Value="7"/> - <CursorPos X="6" Y="199"/> - <UsageCount Value="227"/> - <Loaded Value="True"/> - <LoadedDesigner Value="True"/> - </Unit8> - <Unit9> - <Filename Value="C:\Tools\Lazarus\fpc\2.6.4\source\rtl\objpas\classes\classesh.inc"/> - <EditorIndex Value="-1"/> - <TopLine Value="607"/> - <CursorPos X="15" Y="627"/> - <UsageCount Value="5"/> - </Unit9> - <Unit10> - <Filename Value="C:\Tools\Lazarus\fpc\2.6.4\source\rtl\objpas\classes\streams.inc"/> - <EditorIndex Value="-1"/> - <TopLine Value="423"/> - <CursorPos X="11" Y="435"/> - <UsageCount Value="5"/> - </Unit10> - <Unit11> - <Filename Value="C:\Tools\Lazarus\lcl\forms.pp"/> - <EditorIndex Value="-1"/> - <TopLine Value="1165"/> - <CursorPos X="15" Y="1384"/> - <UsageCount Value="37"/> - </Unit11> - <Unit12> - <Filename Value="C:\Tools\Lazarus\lcl\include\customform.inc"/> - <EditorIndex Value="-1"/> - <TopLine Value="931"/> - <CursorPos X="3" Y="941"/> - <UsageCount Value="36"/> - </Unit12> - <Unit13> - <Filename Value="C:\Tools\Lazarus\fpc\2.6.4\source\rtl\objpas\classes\stringl.inc"/> - <EditorIndex Value="-1"/> - <TopLine Value="520"/> - <CursorPos X="10" Y="526"/> - <UsageCount Value="5"/> - </Unit13> - <Unit14> - <Filename Value="C:\Tools\Lazarus\lcl\interfacebase.pp"/> - <UnitName Value="InterfaceBase"/> - <EditorIndex Value="1"/> - <TopLine Value="121"/> - <CursorPos X="17" Y="143"/> - <UsageCount Value="46"/> - <Loaded Value="True"/> - </Unit14> - <Unit15> - <Filename Value="C:\Tools\Lazarus\lcl\include\interfacebase.inc"/> - <EditorIndex Value="2"/> - <TopLine Value="52"/> - <CursorPos X="3" Y="54"/> - <UsageCount Value="46"/> - <Loaded Value="True"/> - </Unit15> + </Unit7> </Units> - <JumpHistory Count="29" HistoryIndex="28"> - <Position1> - <Filename Value="GUI.pas"/> - <Caret Line="268" Column="97" TopLine="246"/> - </Position1> - <Position2> - <Filename Value="GUI.pas"/> - <Caret Line="264" Column="22" TopLine="247"/> - </Position2> - <Position3> - <Filename Value="GUI.pas"/> - <Caret Line="1065" Column="3" TopLine="1061"/> - </Position3> - <Position4> - <Filename Value="GUI.pas"/> - <Caret Line="1093" Column="3" TopLine="1089"/> - </Position4> - <Position5> - <Filename Value="GUI.pas"/> - <Caret Line="526" Column="36" TopLine="512"/> - </Position5> - <Position6> - <Filename Value="GUI.pas"/> - <Caret Line="536" Column="22" TopLine="512"/> - </Position6> - <Position7> - <Filename Value="GUI.pas"/> - <Caret Line="204" Column="30" TopLine="188"/> - </Position7> - <Position8> - <Filename Value="GUI.pas"/> - <Caret Line="422" Column="30" TopLine="394"/> - </Position8> - <Position9> - <Filename Value="GUI.pas"/> - <Caret Line="234" Column="37" TopLine="220"/> - </Position9> - <Position10> - <Filename Value="GUI.pas"/> - <Caret Line="353" Column="16" TopLine="327"/> - </Position10> - <Position11> - <Filename Value="GUI.pas"/> - <Caret Line="205" Column="28" TopLine="178"/> - </Position11> - <Position12> - <Filename Value="GUI.pas"/> - <Caret Line="333" Column="52" TopLine="274"/> - </Position12> - <Position13> - <Filename Value="GUI.pas"/> - <Caret Line="394" Column="3" TopLine="372"/> - </Position13> - <Position14> - <Filename Value="GUI.pas"/> - <Caret Line="450" Column="3" TopLine="349"/> - </Position14> - <Position15> - <Filename Value="GUI.pas"/> - <Caret Line="394" Column="12" TopLine="384"/> - </Position15> - <Position16> - <Filename Value="GUI.pas"/> - <Caret Line="251" Column="45" TopLine="232"/> - </Position16> - <Position17> - <Filename Value="GUI.pas"/> - <Caret Line="597" Column="10" TopLine="581"/> - </Position17> - <Position18> - <Filename Value="GUI.pas"/> - <Caret Line="589" TopLine="581"/> - </Position18> - <Position19> - <Filename Value="GUI.pas"/> - <Caret Line="590" TopLine="581"/> - </Position19> - <Position20> - <Filename Value="GUI.pas"/> - <Caret Line="264" Column="5" TopLine="242"/> - </Position20> - <Position21> - <Filename Value="GUI.pas"/> - <Caret Line="396" Column="5" TopLine="386"/> - </Position21> - <Position22> - <Filename Value="settings.pas"/> - <Caret Line="115" Column="3" TopLine="100"/> - </Position22> - <Position23> - <Filename Value="GUI.pas"/> - <Caret Line="375" Column="52" TopLine="363"/> - </Position23> - <Position24> - <Filename Value="GUI.pas"/> - <Caret Line="437" Column="20" TopLine="433"/> - </Position24> - <Position25> - <Filename Value="GUI.pas"/> - <Caret Line="242" Column="63" TopLine="220"/> - </Position25> - <Position26> - <Filename Value="ddrescueview.lpr"/> - <Caret Line="43" TopLine="9"/> - </Position26> - <Position27> - <Filename Value="imgblockstore.pas"/> - <Caret Line="367" Column="9" TopLine="344"/> - </Position27> - <Position28> - <Filename Value="imgblockstore.pas"/> - <Caret Line="262" Column="47" TopLine="240"/> - </Position28> - <Position29> - <Filename Value="GUI.pas"/> - <Caret Line="371" Column="37" TopLine="347"/> - </Position29> - </JumpHistory> </ProjectOptions> <CompilerOptions> <Version Value="11"/> @@ -411,9 +197,7 @@ </Parsing> <CodeGeneration> <SmartLinkUnit Value="True"/> - <TargetProcessor Value="80386"/> - <TargetCPU Value="i386"/> - <TargetOS Value="win32"/> + <TargetOS Value="linux"/> <Optimizations> <OptimizationLevel Value="3"/> </Optimizations> @@ -421,7 +205,6 @@ <Linking> <Debugging> <GenerateDebugInfo Value="False"/> - <UseLineInfoUnit Value="False"/> <StripSymbols Value="True"/> </Debugging> <LinkSmart Value="True"/> @@ -433,43 +216,13 @@ </Win32> </Options> </Linking> + <Other> + <CompilerMessages> + <IgnoredMessages idx5091="True" idx5024="True" idx4080="True" idx4079="True"/> + </CompilerMessages> + </Other> </CompilerOptions> <Debugging> - <BreakPoints Count="1"> - <Item1> - <Kind Value="bpkSource"/> - <WatchScope Value="wpsLocal"/> - <WatchKind Value="wpkWrite"/> - <Source Value="C:\Tools\Lazarus\fpc\2.6.2\source\rtl\objpas\classes\persist.inc"/> - <Line Value="53"/> - </Item1> - </BreakPoints> - <Watches Count="6"> - <Item1> - <Expression Value="FOwner"/> - <DisplayStyle Value="wdfPointer"/> - </Item1> - <Item2> - <Expression Value="ASENDER"/> - <DisplayStyle Value="wdfPointer"/> - </Item2> - <Item3> - <Expression Value="MainForm"/> - <DisplayStyle Value="wdfPointer"/> - </Item3> - <Item4> - <Expression Value="aowner"/> - <DisplayStyle Value="wdfPointer"/> - </Item4> - <Item5> - <Expression Value="self"/> - <DisplayStyle Value="wdfPointer"/> - </Item5> - <Item6> - <Expression Value="sender"/> - <DisplayStyle Value="wdfPointer"/> - </Item6> - </Watches> <Exceptions Count="3"> <Item1> <Name Value="EAbort"/> diff -Nru ddrescueview-0.4~alpha3/source/ddrescueview.lpr ddrescueview-0.4~alpha4/source/ddrescueview.lpr --- ddrescueview-0.4~alpha3/source/ddrescueview.lpr 2016-07-18 22:26:19.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/ddrescueview.lpr 2020-08-20 23:13:42.000000000 +0000 @@ -1,7 +1,7 @@ (* ddrescueview.lpr - main program of ddrescueview - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. @@ -34,7 +34,9 @@ begin Application.Initialize; - Application.Title := 'ddrescueview'; + {$IFDEF WINDOWS} + Application.{%H-}MainFormOnTaskbar := True; + {$ENDIF} Application.CreateForm(TMainForm, MainForm); Application.CreateForm(TBlockForm, BlockForm); Application.CreateForm(TSettingsForm, SettingsForm); diff -Nru ddrescueview-0.4~alpha3/source/GUI.lfm ddrescueview-0.4~alpha4/source/GUI.lfm --- ddrescueview-0.4~alpha3/source/GUI.lfm 2016-07-19 02:30:11.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/GUI.lfm 2020-08-28 01:11:47.000000000 +0000 @@ -1,7 +1,7 @@ object MainForm: TMainForm - Left = 1242 + Left = 1251 Height = 439 - Top = 469 + Top = 468 Width = 615 AllowDropFiles = True Caption = 'ddrescueview' @@ -18,7 +18,7 @@ OnShow = FormShow Position = poScreenCenter ShowHint = True - LCLVersion = '1.4.0.4' + LCLVersion = '2.0.10.0' object TopPanel: TPanel Left = 0 Height = 96 @@ -621,6 +621,8 @@ BevelOuter = bvNone ClientHeight = 50 ClientWidth = 615 + Color = clForm + ParentColor = False TabOrder = 2 Visible = False object DbgLog: TMemo @@ -654,6 +656,8 @@ Top = 0 Width = 5 Align = alRight + Color = clForm + ParentColor = False ResizeAnchor = akRight end end @@ -665,7 +669,9 @@ Width = 615 Align = alBottom AutoSnap = False + Color = clForm MinSize = 50 + ParentColor = False ResizeAnchor = akBottom Visible = False end @@ -685,8 +691,8 @@ ShowHint = True end object MainMenu1: TMainMenu - left = 80 - top = 128 + Left = 80 + Top = 128 object FileMenu: TMenuItem Caption = 'File' object miOpenMapfile: TMenuItem @@ -719,6 +725,12 @@ Hint = 'Updates the block view immediately' OnClick = miRefreshClick end + object miCenterCurPos: TMenuItem + AutoCheck = True + Caption = 'Center on current position' + Hint = 'Center the block grid on the current rescue position whenever an update is done' + OnClick = miCenterCurPosClick + end object miZoomBar: TMenuItem Caption = 'Show zoom bar' Checked = True @@ -924,25 +936,32 @@ object OpenDialog1: TOpenDialog Filter = 'All files|*.*' Options = [ofReadOnly, ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing] - left = 160 - top = 128 + Left = 160 + Top = 128 end object updateTimer: TTimer Enabled = False OnTimer = miRefreshClick - left = 240 - top = 128 + Left = 240 + Top = 128 end object ApplicationEvents1: TApplicationProperties OnShowHint = ApplicationEvents1ShowHint - left = 336 - top = 128 + Left = 336 + Top = 128 end object SaveDialog1: TSaveDialog DefaultExt = '.png' Filter = 'Portable network graphics|*.png' Options = [ofOverwritePrompt, ofEnableSizing, ofViewDetail] - left = 432 - top = 128 + Left = 432 + Top = 128 + end + object RetryTimer: TTimer + Enabled = False + Interval = 100 + OnTimer = miRefreshClick + Left = 240 + Top = 192 end end diff -Nru ddrescueview-0.4~alpha3/source/GUI.pas ddrescueview-0.4~alpha4/source/GUI.pas --- ddrescueview-0.4~alpha3/source/GUI.pas 2016-07-19 03:48:29.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/GUI.pas 2020-08-28 01:12:58.000000000 +0000 @@ -1,7 +1,7 @@ (* GUI.pas - Main GUI unit - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. @@ -24,8 +24,9 @@ interface uses - SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Menus, ExtCtrls, - ComCtrls, StdCtrls, Buttons, Shared, Parser, ImgBlockStore, graphtype; + SysUtils, Classes, Graphics, graphtype, + Controls, Forms, Dialogs, Menus, ExtCtrls, ComCtrls, StdCtrls, Buttons, + Shared, Parser, ImgBlockStore; type TMouseCapImage = class(TImage) @@ -49,6 +50,7 @@ lblOutsideDomain: TLabel; lblPending: TLabel; lblRescued: TLabel; + miCenterCurPos: TMenuItem; SaveDialog1: TSaveDialog; saveFormImage: TMenuItem; miContigDom: TMenuItem; @@ -69,6 +71,7 @@ MainVSplitter: TSplitter; RSCol3Panel: TPanel; ShapeOutsideDomain: TShape; + RetryTimer: TTimer; View1: TMenuItem; miSettings: TMenuItem; miZoomBar: TMenuItem; @@ -138,6 +141,7 @@ procedure DbgLogDblClick(Sender: TObject); procedure FormResize(Sender: TObject); procedure FormShow(Sender: TObject); + procedure miCenterCurPosClick(Sender: TObject); procedure miContigDomClick(Sender: TObject); procedure miOpenDomFileClick(Sender: TObject); procedure rsLabelClick(Sender: TObject); @@ -176,10 +180,12 @@ Fhblocks : integer; Fvblocks : integer; FgridSize : integer; - FDraggingZoom : boolean; - FDraggingZoomOrigin : Integer; + FZoomBarScroll : boolean; + FZoomBarScrollOrigin : Integer; + FZoomBarSelectStart, FZoomBarSelectEnd : Longint; + FZoomBehaviour : boolean; // 0: zoom to center, 1: to mouse pos FSelectedBlock : Longint; - FZoomStartBlock, FZoomEndBlock : Longint; + FBlockSelectStart, FBlockSelectEnd : Longint; drawBlocks : procedure of object; procedure drawBlocksSlow; procedure drawBlocksFast; @@ -197,14 +203,13 @@ function BlockImageMouseActionAllowedGetBlock(X, Y: Integer) : Longint; public { Public declarations } - // for the Observer role - Procedure FPOObservedChanged(ASender : TObject; + Procedure FPOObservedChanged(ASender : TObject; // Observer role Operation : TFPObservedOperation; Data : Pointer); - // for the Observed role - procedure AttachObserver(AObserver : TObject); - procedure DetachObserver(AObserver : TObject); + procedure AttachObserver(AObserver : TObject); // Observed role + procedure DetachObserver(AObserver : TObject); // Observed role procedure SelectBlock(block : integer); procedure setDrawFunction(report: Boolean; which : integer); + procedure setZoomBehaviour(behaviour : boolean); function GridXYToBlock(X, Y : integer) : integer; property Parser : TMapParser read FParser; property GridBlockStore : TImgBlockStore read FGridBlockStore; @@ -221,7 +226,7 @@ {$R *.lfm} // Invocation syntax is: -// ddrescueview <options> -m domain-mapfile rescue-mapfile +// ddrescueview <options> [[-m domain-mapfile] rescue-mapfile] // where <options> can be: // -r (off|5s|10s|30s|1m|2m|5m) Set refresh interval, e.g. -r 30s // -lp Show (bottom) log panel on start @@ -340,6 +345,7 @@ DbgLog.DoubleBuffered:=true; FgridSize := 8; + FZoomBehaviour:=true; ZoomImage.Align:=alNone; // alClient only useful for Form Designer BlockImage.Align:=alNone; // at x-platform designtime, but disruptive at runtime @@ -420,6 +426,7 @@ MainVSplitter.MoveSplitter(MainVSplitter.MinSize - GridPanel.Height); BottomPanel.Height:=MainPanel.ClientHeight-MainVSplitter.MinSize-MainVSplitter.Height; end; + if BottomPanel.Height < MainVSplitter.MinSize then BottomPanel.Height := MainVSplitter.MinSize; end; end; @@ -446,7 +453,7 @@ nBlocksChanged := (hBlocksBefore <> Fhblocks) or (vBlocksBefore <> FvBlocks); if nBlocksChanged then begin - FZoomStartBlock:=-1; FZoomEndBlock:=FhBlocks*FvBlocks; + FBlockSelectStart:=-1; FBlockSelectEnd:=FhBlocks*FvBlocks; BlockImage.Picture.Bitmap.SetSize(BlockImage.Width, BlockImage.Height); if drawBlocks=nil then setDrawFunction(false, 0); // decide here which draw function to use FGridBlockStore.NumBlocks:=FhBlocks*FvBlocks; // will trigger update @@ -459,6 +466,7 @@ ZoomImage.Height:=BlockImage.Height; ZoomImage.Width:=ZoomPanel.ClientWidth; ZoomImage.Picture.Bitmap.SetSize(ZoomImage.Width, ZoomImage.Height); + FZoomBarSelectStart := -1; FZoomBarSelectEnd := ZoomImage.Height; FZoomBlockStore.NumBlocks:=ZoomImage.Height; // will trigger update end; if zoomImageChanged or nBlocksChanged then SelectBlock(-1); // unselect block @@ -470,7 +478,7 @@ procedure TMainForm.updateStatusTexts; var rs : TRescueStatus; - newCap : String; + newCap : String; // new caption for main window begin CommentsMemo.Clear; newCap := PROGRAM_TITLE; @@ -489,7 +497,10 @@ StatusBar.Panels.Items[0].Text:='No file opened'; end; end; - if Caption<>newCap then Caption:=newCap; + if Caption<>newCap then begin + Caption:=newCap; + Application.Title:=newCap; + end; EditInputSize.Text:=SFORMATS[lblInputSize.Tag]^.SizeStr(rs.devicesize); EditDomainSize.Text:=SFORMATS[lblDomainSize.Tag]^.SizeStr(rs.devicesize-rs.outsidedomain); EditErrorCount.Text:=IntToStr(rs.errors); @@ -555,7 +566,7 @@ procedure TMainForm.setDrawFunction(report: Boolean; which : integer); var Desc: TRawImageDescription; - capable: Boolean; + capable: Boolean = false; begin case which of 0: begin @@ -590,7 +601,7 @@ capable:=false; if report then DbgLog.Lines.Add('!! Line order is not top-to-bottom.'); end; - if Desc.BytesPerLine < (Desc.BitsPerPixel div 8)*Desc.Width then begin + if Desc.BytesPerLine < LongWord(Desc.BitsPerPixel div 8)*Desc.Width then begin capable:=false; if report then DbgLog.Lines.Add('!! BytesPerLine sanity check failed.'); end; @@ -608,6 +619,11 @@ end; end; +procedure TMainForm.setZoomBehaviour(behaviour: boolean); +begin + FZoomBehaviour:=behaviour; +end; + //get block colors from GridBlockStore and draw them on the BlockImage procedure TMainForm.drawBlocksSlow; var iImgBlock : Longint; @@ -619,7 +635,7 @@ for iImgBlock := 0 to FGridBlockStore.NumBlocks-1 do begin curImgBlock := FGridBlockStore[iImgBlock]; // get current block Brush.Color:=blendColors(COLOR_HIGHLIGHT, curImgBlock and $ffffff, - 112*LongInt(not InRangeEx(iImgBlock, FZoomStartBlock, FZoomEndBlock))); + 112*LongInt(not InRangeEx(iImgBlock, FBlockSelectStart, FBlockSelectEnd))); if LongBool(curImgBlock and MASK_ACTIVE) then begin // current pos marker Pen.Color := COLOR_ACTIVE; Rectangle(resizeRect(getImgBlockRect(iImgBlock), 1)); @@ -685,7 +701,7 @@ if (curBlockData and MASK_ACTIVE) <> 0 then actblock:=iImgBlock; // modify color if user is currently left-drag zooming on this block curBlockData := blendColors(COLOR_HIGHLIGHT, curBlockData and $ffffff, - 112*LongInt(not InRangeEx(iImgBlock, FZoomStartBlock, FZoomEndBlock))); + 112*LongInt(not InRangeEx(iImgBlock, FBlockSelectStart, FBlockSelectEnd))); // populate the color row memory area with gridblock color PixPtr:=PByte(colorRow); for x:=0 to Fgridsize-2 do begin // the pixels of a gridblock-sized line @@ -719,6 +735,7 @@ end; end; BlockImage.Refresh; + //DbgLog.Lines.Add('Grid blocks drawn: '+inttostr(FGridBlockStore.NumBlocks)); end; // draw stuff in the top bar. @@ -797,10 +814,15 @@ iImgBlock, zoomWndFirstPx, zoomWndLastPx, cPosBlock : Longint; begin if FZoomBlockStore.Parser.hasFile() then begin - zoomWndFirstPx:=FZoomBlockStore.getBlockFromOffset(FGridBlockStore.SectSize* - FGridBlockStore.SectOffset); - zoomWndLastPx:=FZoomBlockStore.getBlockFromOffset(FGridBlockStore.SectSize* - (FGridBlockStore.SectOffset+FGridBlockStore.SectCount)); + if FZoomBarSelectStart <> -1 then begin + zoomWndFirstPx:=min(FZoomBarSelectStart, FZoomBarSelectEnd); + zoomWndLastPx:=max(FZoomBarSelectStart, FZoomBarSelectEnd); + end else begin + zoomWndFirstPx:=FZoomBlockStore.getBlockFromOffset(FGridBlockStore.SectSize* + FGridBlockStore.SectOffset); + zoomWndLastPx:=FZoomBlockStore.getBlockFromOffset(FGridBlockStore.SectSize* + (FGridBlockStore.SectOffset+FGridBlockStore.SectCount)-1); + end; end else begin zoomWndFirstPx:=0; zoomWndLastPx:=ZoomImage.Height-1; @@ -849,6 +871,7 @@ end; end; ZoomImage.Refresh; + //DbgLog.Lines.Add('ZoomBar Lines drawn: '+inttostr(FZoomBlockStore.NumBlocks)); end; // select an img block from the block grid. This happens when a block is clicked. @@ -861,7 +884,7 @@ end; end; -// thats a long funtion name. Returns block number if allowed, -1 otherwise. +// thats a long funtion name. Returns grid block number if allowed, -1 otherwise. function TMainForm.BlockImageMouseActionAllowedGetBlock(X, Y: Integer) : Longint; var imgBlock: Longint; begin @@ -880,18 +903,16 @@ begin imgBlock:=BlockImageMouseActionAllowedGetBlock(X, Y); if imgBlock = -1 then exit; // mouse action not allowed - if FZoomStartBlock <> -1 then exit; // no additional actions allowed + if FBlockSelectStart <> -1 then exit; // no additional actions allowed if (Button = mbLeft) and Assigned(BlockForm) then begin SelectBlock(imgBlock); // Block Inspector initialization if not BlockForm.Visible then BlockForm.Show; - end; - - if Button = mbRight then begin + end else if (Button = mbRight) and not miCenterCurPos.Checked then begin TMouseCapImage(BlockImage).MouseCapture:=true; - FZoomStartBlock:=imgBlock; - FZoomEndBlock:=imgBlock; + FBlockSelectStart:=imgBlock; + FBlockSelectEnd:=imgBlock; drawBlocks; end; end; @@ -899,12 +920,12 @@ procedure TMainForm.BlockImageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var imgBlock: Longint; begin - if FZoomStartBlock = -1 then exit; // must be in zooming mode + if FBlockSelectStart = -1 then exit; // must be in zooming mode imgBlock:=BlockImageMouseActionAllowedGetBlock(EnsureRange(X, 0, BlockImage.Width-2), EnsureRange(Y, 0, BlockImage.Height-2)); if imgBlock = -1 then exit; // mouse action not allowed - if imgBlock<>FZoomEndBlock then begin - FZoomEndBlock:=imgBlock; + if imgBlock<>FBlockSelectEnd then begin + FBlockSelectEnd:=imgBlock; drawBlocks; end; end; @@ -914,11 +935,11 @@ var StartBlock, EndBlock : Longint; begin if Button = mbRight then begin - if FZoomStartBlock = -1 then exit; // must be in zooming mode + if FBlockSelectStart = -1 then exit; // must be in zooming mode TMouseCapImage(BlockImage).MouseCapture:=false; - StartBlock:=min(FZoomStartBlock, FZoomEndBlock); - EndBlock:=max(FZoomStartBlock, FZoomEndBlock); - FZoomStartBlock:=-1; FZoomEndBlock:=FhBlocks*FvBlocks; + StartBlock:=min(FBlockSelectStart, FBlockSelectEnd); + EndBlock:=max(FBlockSelectStart, FBlockSelectEnd); + FBlockSelectStart:=-1; FBlockSelectEnd:=FhBlocks*FvBlocks; drawBlocks; FGridBlockStore.zoomInRange(StartBlock, EndBlock); drawZoomImage; @@ -933,24 +954,35 @@ begin imgBlock:=BlockImageMouseActionAllowedGetBlock(MousePos.x, MousePos.y); if imgBlock = -1 then exit; - SelectBlock(-1); // unselect block + //SelectBlock(-1); // unselect block if WheelDelta>0 then begin // zoom in - FGridBlockStore.zoom(imgBlock, 1/1.5); + if FZoomBehaviour then FGridBlockStore.zoomBlockToBlock(imgBlock, imgBlock, 1/1.5) + else FGridBlockStore.zoomToCenter(imgBlock, 1/1.5); end else if WheelDelta<0 then begin // zoom out - FGridBlockStore.zoom(imgBlock, 1.5); + if FZoomBehaviour then FGridBlockStore.zoomBlockToBlock(imgBlock, imgBlock, 1.5) + else FGridBlockStore.zoomToCenter(imgBlock, 1.5); end; drawZoomImage; end; - // mouse down on zoom bar, start dragging action if all requirements met. procedure TMainForm.ZoomImageMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin + if FZoomBarSelectStart <> -1 then exit; // no additional actions allowed + if miCenterCurPos.Checked then exit; // neither scrolling nor selecting makes sense if FZoomBlockStore.Parser.hasFile() then begin - if ZoomImage.Cursor=crHandPoint then begin - FDraggingZoom:=true; - FDraggingZoomOrigin:=Y; + if (Button=mbLeft) and (ZoomImage.Cursor=crHandPoint) then begin + FZoomBarScroll:=true; + FZoomBarScrollOrigin:=Y; + end else if Button=mbRight then begin + if not (FZoomBlockStore.getOffsetFromBlock(Y) >= + FZoomBlockStore.Parser.rescueStatus.devicesize) then begin + TMouseCapImage(ZoomImage).MouseCapture:=true; + FZoomBarSelectStart:=Y; + FZoomBarSelectEnd:=Y; + ZoomImageMouseMove(self, Shift, X, Y); // update immediately + end; end; end; end; @@ -960,14 +992,16 @@ var zoomWndFirstPx, zoomWndLastPx, YOffsetBefore, YOffsetAfter : Longint; zoomShift, adjustedShift, deviceSectors : Int64; // all values in device sectors + StartBlock, EndBlock : Longint; + newSectOffset, newSectCount : Int64; begin if FGridBlockStore.Parser.hasFile() then begin - if FDraggingZoom and (FDraggingZoomOrigin<>Y) then begin + if FZoomBarScroll and (FZoomBarScrollOrigin<>Y) then begin // user dragged zoomed-in area, or 'window', of the device. with FGridBlockStore do if (SectInBlock*FhBlocks) <> 0 then begin // calculate how much the user tries to shift the window (in sectors). // this can be way outside the zoom panel -> outside the device! - zoomShift:=FZoomBlockStore.SectInBlock*Int64(Y-FDraggingZoomOrigin); + zoomShift:=FZoomBlockStore.SectInBlock*Int64(Y-FZoomBarScrollOrigin); // adjust the shift, so it is aligned to a multiple of one grid line. // this eases the scrolling on the eyes, the blocks will not jump erratically. adjustedShift:=(zoomShift div (SectInBlock*FhBlocks)) * SectInBlock*FhBlocks; @@ -979,16 +1013,42 @@ SectOffset:=max(0, min(SectOffset+adjustedShift, deviceSectors-SectCount)); // find out by how many pixels the window was actually shifted, after adjustment. YOffsetAfter:=FZoomBlockStore.getBlockFromOffset(SectSize*SectOffset); - FDraggingZoomOrigin+=YOffsetAfter-YOffsetBefore; + FZoomBarScrollOrigin+=YOffsetAfter-YOffsetBefore; + end; + FGridBlockStore.FPOObservedChanged(self, ooChange, Pointer(0)); + drawZoomImage; + end else if FZoomBarSelectStart <> -1 then begin + Y:=EnsureRange(Y, 0, ZoomImage.Height-1); + if ((Y<>FZoomBarSelectEnd) or (FZoomBarSelectStart=FZoomBarSelectEnd)) + and (FZoomBlockStore.getOffsetFromBlock(Y) < + FZoomBlockStore.Parser.rescueStatus.devicesize) then begin + FZoomBarSelectEnd:=Y; + StartBlock:=min(FZoomBarSelectStart, FZoomBarSelectEnd); + EndBlock:=max(FZoomBarSelectStart, FZoomBarSelectEnd); + newSectOffset := FZoomBlockStore.getOffsetFromBlock(StartBlock) div + FZoomBlockStore.SectSize; + newSectCount := FZoomBlockStore.getOffsetFromBlock(EndBlock) div + FZoomBlockStore.SectSize - newSectOffset + FZoomBlockStore.SectInBlock; + if FZoomBarSelectEnd < FZoomBlockStore.NumBlocks-1 then + newSectCount := max(1, newSectCount div FGridBlockStore.NumBlocks * + FGridBlockStore.NumBlocks) + else newSectCount := min(newSectCount, + FZoomBlockStore.Parser.rescueStatus.devicesize div FZoomBlockStore.SectSize - + newSectOffset); + FGridBlockStore.setZoom(newSectOffset, newSectCount); + FGridBlockStore.FPOObservedChanged(self, ooChange, Pointer(0)); + drawZoomImage; end; - FPONotifyObservers(self, ooChange, nil); end; + // select the correct mouse cursor zoomWndFirstPx:=FZoomBlockStore.getBlockFromOffset(FGridBlockStore.SectSize * FGridBlockStore.SectOffset); zoomWndLastPx:=FZoomBlockStore.getBlockFromOffset(FGridBlockStore.SectSize * (FGridBlockStore.SectOffset+FGridBlockStore.SectCount)); - if InRange(Y, zoomWndFirstPx, zoomWndLastPx) then ZoomImage.Cursor:=crHandPoint + if InRange(Y, zoomWndFirstPx, zoomWndLastPx) and + (FZoomBarSelectStart = -1) and not miCenterCurPos.Checked then + ZoomImage.Cursor:=crHandPoint else ZoomImage.Cursor:=crDefault; end; end; @@ -996,7 +1056,12 @@ procedure TMainForm.ZoomImageMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin - FDraggingZoom:=false; + if Button = mbLeft then FZoomBarScroll:=false + else if (Button = mbRight) and (FZoomBarSelectStart <> -1) then begin + TMouseCapImage(ZoomImage).MouseCapture:=false; + FZoomBarSelectStart:=-1; FZoomBarSelectEnd:=ZoomImage.Height; + //drawZoomImage; + end; end; // user wants to open a file (file open dialog) @@ -1023,6 +1088,13 @@ FParser.CloseFile; end; +// user toggles option 'Center on Current position' +procedure TMainForm.miCenterCurPosClick(Sender: TObject); +begin + GridBlockStore.LockOnCurPos:=miCenterCurPos.Checked; + drawZoomImage; +end; + // user wants to show the bottom panel (debug log and mapfile comments) procedure TMainForm.miShowMemosClick(Sender: TObject); begin @@ -1082,10 +1154,20 @@ // refresh requested, either from the menu or programmatically procedure TMainForm.miRefreshClick(Sender: TObject); begin + if Sender = RetryTimer then begin + DbgLog.Lines.Add('Retrying to refresh mapfile.'); + RetryTimer.Enabled := false; + end; StatusBar.Panels.Items[0].Text:=buildStatusBarText(FParser.MapFileName, true, false); StatusBar.Refresh; Application.ProcessMessages; - FParser.parse(); + if not FParser.parse(true) then begin + // The rescue device size has changed. This is most likely caused by + // ddrescue currently writing to the mapfile. The Information in the Parser + // has not been changed, so we need to retry parsing in 100ms. + DbgLog.Lines.Add('Incomplete mapfile on refresh! Retrying in 100ms...'); + RetryTimer.Enabled := true; + end; end; // user clicked the little (x) button on the zoom bar. @@ -1172,6 +1254,7 @@ procedure TMainForm.autoParseClick(Sender: TObject); var interval : integer; begin + RetryTimer.Enabled := false; if Sender is TMenuItem then begin TMenuItem(Sender).Checked := true; interval := TMenuItem(Sender).Tag * 1000; diff -Nru ddrescueview-0.4~alpha3/source/imgblockstore.pas ddrescueview-0.4~alpha4/source/imgblockstore.pas --- ddrescueview-0.4~alpha3/source/imgblockstore.pas 2016-07-19 13:22:41.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/imgblockstore.pas 2020-08-28 01:03:50.000000000 +0000 @@ -1,7 +1,7 @@ (* ImgBlockStore.pas - Image Block Storage unit - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. @@ -45,16 +45,22 @@ FSectInBlock : Int64; // device sectors per imgBlock FByteInBlock : Int64; // # of bytes in every imgBlock, multiple of FDevBSize FOwner : TObject; - FNoZoom : Boolean; + FNoZoom : Boolean; // prevent zooming. Always show full device + FLockOnCurPos : Boolean; // center around current position if possible but allow zoom + FBlockstatusMasks : array[0..255] of Longword; // LUT, maps log entry statuses to Block Status masks procedure assignParser(source : TMapParser); procedure buildBlocks; function BlockStatusToMask(status: char) : Longword; function ColorizeBlockMask(mask: Longint) : Longint; function getBlock(i: Longint): Longword; procedure sanitizeZoom(); + function binSearchStartEntry() : integer; + function binSearchEndEntry() : integer; procedure setDevBSize(size : Int64); + procedure SetLockOnCurPos(lock: Boolean); procedure setNumBlocks(num : Longint); procedure setSectOffset(offset : Int64); + procedure setSectCount(count : Int64); public constructor Create(AOwner : TObject); virtual; destructor Destroy; override; @@ -63,14 +69,17 @@ property NumBlocks : Longint read FNumBlocks write setNumBlocks; property SectSize : Int64 read FSectSize write setDevBSize; property SectOffset : Int64 read FZoom.SectOffset write setSectOffset; - property SectCount : Int64 read FZoom.SectCount; + property SectCount : Int64 read FZoom.SectCount write setSectCount; property ByteInBlock : Int64 read FByteInBlock; property SectInBlock : Int64 read FSectInBlock; property NoZoom : Boolean read FNoZoom write FNoZoom; + property LockOnCurPos : Boolean read FLockOnCurPos write SetLockOnCurPos; function getOffsetFromBlock(block : Int64) : Int64; function getBlockFromOffset(offset : Int64) : Int64; function activeBlock() : Int64; - Procedure zoom(block: Longint; factor: double); + procedure setZoom(Offset, Count: Int64); + procedure zoomToCenter(block: Longint; factor: double); + procedure zoomBlockToBlock(srcBlock, destBlock: Longint; factor: double); procedure zoomInRange(block1, block2: Longint); Procedure FPOObservedChanged(ASender : TObject; //for the Observer role Operation : TFPObservedOperation; Data : Pointer); @@ -81,12 +90,15 @@ // creates the ImgBlockStore and sets up listening for the owner. constructor TImgBlockStore.Create(AOwner : TObject); +var c : byte; begin inherited Create; FSectSize := DEF_BSIZE; FByteInBlock := DEF_BSIZE; FSectInBlock := 1; FOwner := AOwner; + // Precompute the Block Status Masks LUT + for c:= 0 to 255 do FBlockstatusMasks[c]:=BlockStatusToMask(char(c)); // listen for requests from the owner if (AOwner<>nil) and (AOwner is IAttachableObserved) then (AOwner as IAttachableObserved).AttachObserver(self); @@ -108,14 +120,13 @@ if Operation in [ooAddItem, ooDeleteItem] then begin // new or closed file! if Operation = ooAddItem then FSectSize:=FParser.rescueStatus.suggestedBlockSize; FZoom.SectCount:=0; // reset zoom - sanitizeZoom(); end; - buildBlocks; - FPONotifyObservers(self, ooChange, nil); - end else begin // someone else sent an update request - buildBlocks; - FPONotifyObservers(self, ooChange, nil); end; + sanitizeZoom(); + buildBlocks; + // log the update to mainform textbox + //MainForm.DbgLog.Lines.Add('ImgBlockStore update: ' + BoolToStr(FNoZoom, 'Zoom', 'Grid')); + FPONotifyObservers(self, ooChange, nil); end; // Assign a MapParser to the img Blocks. @@ -174,6 +185,10 @@ if (not Assigned(FParser)) or (FNumBlocks = 0) or (FSectSize = 0) then exit; with FParser do begin deviceSectors:=rescueStatus.devicesize div FSectSize; + // first, if FLockOnCurPos is true, keep the current position locked in the center: + if FLockOnCurPos and not FNoZoom then + FZoom.SectOffset:=(rescueStatus.pos div FSectSize)-(FZoom.SectCount div 2); + if (FZoom.SectCount=0) or FNoZoom then begin FZoom.SectOffset:=0; FZoom.SectCount:=deviceSectors; @@ -191,6 +206,44 @@ end; end; +// Binary Search in the Parser's Log for the starting entry inside the BlockStore's Zoom +function TImgBlockStore.binSearchStartEntry(): integer; +var + chunkStart, chunkEnd, chunkSize, chunkMid : integer; + searchOffset : Int64; +begin + searchOffset := FZoom.SectOffset*FSectSize; + chunkStart := 0; + chunkEnd := Length(FParser.map)-1; + chunkSize := chunkEnd-chunkStart+1; + while chunkSize > 1 do begin + chunkMid := chunkStart + (chunkSize div 2); + if searchOffset < (FParser.map[chunkMid-1].offset+FParser.map[chunkMid-1].length) then chunkEnd := chunkMid-1 + else chunkStart := chunkMid; + chunkSize := chunkEnd-chunkStart+1; + end; + result:=chunkStart; +end; + +// Binary Search in the Parser's Log for the last entry making up the BlockStore's Zoom +function TImgBlockStore.binSearchEndEntry(): integer; +var + chunkStart, chunkEnd, chunkSize, chunkMid : integer; + searchOffset : Int64; +begin + searchOffset := (FZoom.SectOffset+FZoom.SectCount)*FSectSize; + chunkStart := 0; + chunkEnd := Length(FParser.map)-1; + chunkSize := chunkEnd-chunkStart+1; + while chunkSize > 1 do begin + chunkMid := chunkStart + (chunkSize div 2); + if searchOffset <= FParser.map[chunkMid].offset then chunkEnd := chunkMid-1 + else chunkStart := chunkMid; + chunkSize := chunkEnd-chunkStart+1; + end; + result:=chunkEnd; +end; + (* Calculate image blocks from map for fast drawing. Blocks will be stored in the imgBlocks[] array. Blocks contain type information and a color derived from the mix of types. @@ -199,10 +252,11 @@ small rescue devices, high number of imgBlocks or big sector size *) procedure TImgBlockStore.buildBlocks; var - mapLen, mapBlock, imgBlock: integer; - imgStartBlock, imgEndBlock: Int64; + mapLen, mapBlock, imgBlock : integer; + imgStartBlock, imgEndBlock : Int64; + blockStatusMask : Longword; {$IFDEF VerboseProfiler} - lTimeStart: TDateTime; + lTimeStart : TDateTime; {$ENDIF} begin if not Assigned(FParser) then mapLen := 0 @@ -231,18 +285,14 @@ with FParser do begin // if zoom not yet set, or zoom is disabled, do sanitization if (FZoom.SectCount=0) or FNoZoom then sanitizeZoom(); - // iterate over map and collect block info - for mapBlock := 0 to mapLen-1 do begin - // skip blocks before zoomed-in area - if (map[mapBlock].offset+map[mapBlock].length) <= FZoom.SectOffset*FSectSize then Continue; - // skip blocks after zoomed-in area - if (map[mapBlock].offset) >= (FZoom.SectOffset+FZoom.SectCount)*FSectSize then Break; - // first img block which intersects current map entry + for mapBlock := binSearchStartEntry() to binSearchEndEntry() do begin + // process img blocks that intersect current map entry imgStartBlock := (map[mapBlock].offset-FZoom.SectOffset*FSectSize) div FByteInBlock; imgEndBlock := (map[mapBlock].offset+map[mapBlock].length-FZoom.SectOffset*FSectSize-1) div FByteInBlock; + blockStatusMask := FBlockstatusMasks[ord(map[mapBlock].status)]; for imgBlock := Max(0,imgStartBlock) to Min(FNumBlocks-1, imgEndBlock) do begin - FImgBlocks[imgBlock]:=FImgBlocks[imgBlock] or BlockStatusToMask(map[mapBlock].status); + FImgBlocks[imgBlock]:=FImgBlocks[imgBlock] or blockStatusMask; end; end; @@ -322,6 +372,16 @@ FPONotifyObservers(self, ooChange, nil); end; +procedure TImgBlockStore.SetLockOnCurPos(lock: Boolean); +begin + FLockOnCurPos:=lock; + if FLockOnCurPos then begin + sanitizeZoom(); + buildBlocks; + FPONotifyObservers(self, ooChange, nil); + end; +end; + procedure TImgBlockStore.setNumBlocks(num: Longint); begin FNumBlocks:=num; @@ -330,13 +390,28 @@ FPONotifyObservers(self, ooChange, nil); end; -// shift the zoomed section by cahanging the offset +// shift the zoomed section by changing the offset procedure TImgBlockStore.setSectOffset(offset: Int64); begin FZoom.SectOffset:=offset; sanitizeZoom(); end; +// resize zoomed section +procedure TImgBlockStore.setSectCount(count: Int64); +begin + FZoom.SectCount:=count; + sanitizeZoom(); +end; + +//set zoomed section +procedure TImgBlockStore.setZoom(Offset, Count: Int64); +begin + FZoom.SectOffset:=Offset; + FZoom.SectCount:=Count; + sanitizeZoom(); +end; + // returns a bit mask for each known block type function TImgBlockStore.BlockStatusToMask(status: char) : Longword; begin @@ -354,7 +429,7 @@ // zoom in or out by some factor, centered around a given imgBlock // factor <1 zooms in, factor >1 zooms out. -procedure TImgBlockStore.zoom(block: Longint; factor: double); +procedure TImgBlockStore.zoomToCenter(block: Longint; factor: double); var zoomCenter, zoomLength, deviceSectors : Int64; // all values in sectors begin @@ -376,6 +451,34 @@ sanitizeZoom(); buildBlocks; FPONotifyObservers(self, ooChange, nil); +end; + +// Zooms the view in or out. After the zoom, the device position of srcBlock +// will be at destBlock. +procedure TImgBlockStore.zoomBlockToBlock(srcBlock, destBlock: Longint; factor: double); +var + zoomLength, deviceSectors, srcBlockSect, newSectInBlock : Int64; // all values in sectors +begin + if not Assigned(FParser) then exit; + if not FParser.hasFile() then exit; + + deviceSectors:=FParser.rescueStatus.devicesize div FSectSize; + zoomLength := Round(FZoom.SectCount*factor); // desired new window size + if factor < 1.0 then begin // zooming in + // if already at 1 sector/block -> do nothing + if FSectInBlock = 1 then exit; + // reduce window by at least 1 sector/block (needed for rounding reasons) + zoomLength := Min(FZoom.SectCount-FnumBlocks, zoomLength); + end; + zoomLength := Max(FnumBlocks, zoomLength); // not further in than 1 sector/block + zoomLength := Min(deviceSectors, zoomLength); // not further out than whole device + srcBlockSect := getOffsetFromBlock(srcBlock) div FSectSize + FSectInBlock div 2; + newSectInBlock := zoomLength div FNumBlocks + Int64((zoomLength mod FNumBlocks)<>0); + FZoom.SectOffset := srcBlockSect - (newSectInBlock*destBlock + newSectInBlock div 2); + FZoom.SectCount := zoomLength; + sanitizeZoom(); + buildBlocks; + FPONotifyObservers(self, ooChange, nil); end; // zoom into an area bounded by two blocks. Assumes block1 <= block2. diff -Nru ddrescueview-0.4~alpha3/source/Parser.pas ddrescueview-0.4~alpha4/source/Parser.pas --- ddrescueview-0.4~alpha3/source/Parser.pas 2016-07-20 03:01:43.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/Parser.pas 2020-08-21 00:10:45.000000000 +0000 @@ -1,7 +1,7 @@ (* Parser.pas - Mapfile parser unit - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. @@ -27,6 +27,9 @@ uses Classes, Shared; type + + { TSimpleParser } + TSimpleParser = class(TObservablePersistent) private FMap : TMap; @@ -43,7 +46,7 @@ destructor Destroy; override; procedure OpenFile(filename : String); procedure CloseFile; - procedure parse(); + function parse(forceSameDevSize : Boolean) : Boolean; function hasFile() : boolean; property rescueStatus : TRescueStatus read FRescueStatus; property map : TMap read FMap; @@ -52,6 +55,9 @@ property MapFileName :String read FFileName; end; + + { TMapParser } + // This parser can also embed a domain mapfile parser TMapParser = class(TObservablePersistent) private @@ -64,21 +70,25 @@ function getMap(): TMap; procedure postParse(); procedure setContiguous(mode: Boolean); + function getCommentLines(): TStringList; + function getVersion(): String; + function getMapFileName(): String; + function getDomFileName(): String; public constructor Create; destructor Destroy; override; procedure OpenFile(filename : String); procedure OpenDomainFile(filename : String); procedure CloseFile; - procedure parse(); + function parse(forceSameDevSize : Boolean) : Boolean; function hasFile() : boolean; function hasDomFile() : Boolean; property rescueStatus : TRescueStatus read FRescueStatus; property map : TMap read getMap; - property CommentLines : TStringList read FMapParser.FComments; - property Version : String read FMapParser.FVersion; - property MapFileName : String read FMapParser.FFileName; - property DomFileName : String read FDomParser.FFileName; + property CommentLines : TStringList read GetCommentLines; + property Version : String read getVersion; + property MapFileName : String read getMapFileName; + property DomFileName : String read getDomFileName; property ContiguousDomain : Boolean read FContiguous write setContiguous; end; @@ -223,10 +233,11 @@ end; end; -procedure TMapParser.parse; +function TMapParser.parse(forceSameDevSize : Boolean) : Boolean; begin - if FMapParser.hasFile() then FMapParser.parse(); - if FDomParser.hasFile() then FDomParser.parse(); + result := True; + if FMapParser.hasFile() then result := FMapParser.parse(forceSameDevSize); + if FDomParser.hasFile() then FDomParser.parse(false); postParse; end; @@ -269,7 +280,7 @@ FMapStream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone); FComments := TStringList.Create; FFileName := filename; - parse(); // start parsing after opening + parse(false); // start parsing after opening except on E: Exception do begin CloseFile; @@ -309,17 +320,22 @@ (* Parse the mapfile. After parsing, the results are available in these properties: map, rescueStatus and Comments *) -procedure TSimpleParser.parse(); +function TSimpleParser.parse(forceSameDevSize : Boolean) : Boolean; //success var line : string; token : array[0..2] of string; i, mapEntry, lineIdx, idx : Integer; mapStrings : TStringList = nil; prevHadFile, statuslineFound : boolean; + newMap : TMap; + newRescueStatus : TRescueStatus; + newComments : TStringList; + newVersion : String; {$IFDEF VerboseProfiler} lTimeStart: TDateTime; {$ENDIF} begin + result:=False; // make sure the file is open if not hasFile then begin logMsg('Parser: No mapfile opened.'); @@ -359,11 +375,11 @@ // reserve space in the map. Less entries will be actually needed, due // to comment lines and the status line being counted. - SetLength(FMap, mapStrings.Count); + SetLength(newMap, mapStrings.Count); // initialize many things to their initial values - FRescueStatus := emptyRescueStatus; - FComments.Clear; - FVersion:=''; + newRescueStatus := emptyRescueStatus; + newComments := TStringList.Create; + newVersion:=''; lineIdx := 0; mapEntry := 0; prevHadFile := Length(FMap) > 0; @@ -376,7 +392,7 @@ if isCommentLine(line) then begin if not statuslineFound then begin //process comments only until the status line is found // copy comment line into FComments (but not the #currentpos one...) - if pos('# current_pos', line) = 0 then FComments.Add(line); + if pos('# current_pos', line) = 0 then newComments.Add(line); if pos('Command line:', line) > 0 then begin // try to find ddrescue's block size argument repeat // not a loop, but goto replacement idx := pos(' -b', line); @@ -389,11 +405,11 @@ token[0] :=TrimLeft(Copy(line, idx, Length(line))); idx := pos(' ', token[0]); //space after argument if idx <> 0 then token[0] :=Copy(token[0], 1, idx-1); - FRescueStatus.suggestedBlockSize:=StrToIntDef(token[0], DEF_BSIZE); + newRescueStatus.suggestedBlockSize:=StrToIntDef(token[0], DEF_BSIZE); until true; end; idx:=pos('ddrescue version ', line); // get ddrescue version - if idx > 0 then FVersion := Copy(line, idx+17, 1337); + if idx > 0 then newVersion := Copy(line, idx+17, 1337); end; end else if Length(line) > 0 then begin // split line into maximum of 3 tokens @@ -409,24 +425,24 @@ end; if (not statuslineFound) and (token[0] <> '') and (token[1] <> '') then begin // found the status line - FRescueStatus.pos:=StrToInt64Def(token[0], 0); - FRescueStatus.curOperation:=token[1][1]; - if token[2] <> '' then FRescueStatus.current_pass:=StrToIntDef(token[2], 0); - FRescueStatus.strCurOperation:=OperationToText(FRescueStatus.curOperation, FRescueStatus.current_pass); + newRescueStatus.pos:=StrToInt64Def(token[0], 0); + newRescueStatus.curOperation:=token[1][1]; + if token[2] <> '' then newRescueStatus.current_pass:=StrToIntDef(token[2], 0); + newRescueStatus.strCurOperation:=OperationToText(newRescueStatus.curOperation, newRescueStatus.current_pass); statuslineFound := true; end else if (token[0] <> '') and (token[1] <> '') and (token[2] <> '') then begin // standard block line - FMap[mapEntry].offset:=StrToInt64(token[0]); - FMap[mapEntry].length:=StrToInt64(token[1]); - FMap[mapEntry].status:=token[2][1]; - case FMap[mapEntry].status of - '?' : inc(FRescueStatus.nontried, FMap[mapEntry].length); - '+' : inc(FRescueStatus.rescued, FMap[mapEntry].length); - '*' : inc(FRescueStatus.nontrimmed, FMap[mapEntry].length); - '/' : inc(FRescueStatus.nonscraped, FMap[mapEntry].length); + newMap[mapEntry].offset:=StrToInt64(token[0]); + newMap[mapEntry].length:=StrToInt64(token[1]); + newMap[mapEntry].status:=token[2][1]; + case newMap[mapEntry].status of + '?' : inc(newRescueStatus.nontried, newMap[mapEntry].length); + '+' : inc(newRescueStatus.rescued, newMap[mapEntry].length); + '*' : inc(newRescueStatus.nontrimmed, newMap[mapEntry].length); + '/' : inc(newRescueStatus.nonscraped, newMap[mapEntry].length); '-' : begin - inc(FRescueStatus.bad, FMap[mapEntry].length); - inc(FRescueStatus.errors); + inc(newRescueStatus.bad, newMap[mapEntry].length); + inc(newRescueStatus.errors); end; end; inc(mapEntry); @@ -436,19 +452,22 @@ end; lineIdx+=1; end; - SetLength(FMap, mapEntry); // trim array to actually needed size + SetLength(newMap, mapEntry); // trim array to actually needed size except on E : Exception do begin logMsg('Error parsing mapfile on line '+IntToStr(lineIdx+1)+': '+ E.Message+'('+E.ClassName+')'); - FRescueStatus := emptyRescueStatus; // some fail-safe values - FRescueStatus.strCurOperation:='PARSER ERROR'; - SetLength(FMap, 1); - FMap[0].offset:=0; - FMap[0].length:=DEF_BSIZE*(1 shl 18); // one block of 2^18 bad sectors - FMap[0].status:='-'; - FRescueStatus.bad:=FMap[0].length; - FRescueStatus.devicesize:=FMap[0].length; + if not forceSameDevSize then begin + // Set some fail-safe values only if Same Device Size parsing is not forced + newRescueStatus := emptyRescueStatus; + newRescueStatus.strCurOperation:='PARSER ERROR'; + SetLength(newMap, 1); + newMap[0].offset:=0; + newMap[0].length:=DEF_BSIZE*(1 shl 18); // one block of 2^18 bad sectors + newMap[0].status:='-'; + newRescueStatus.bad:=newMap[0].length; + newRescueStatus.devicesize:=newMap[0].length; + end; end; end; FreeAndNil(mapStrings); @@ -457,16 +476,31 @@ logMsg(Format('[TSimpleParser.parse] Parse Duration: %d ms', [DateTimeToMilliseconds(Now() - lTimeStart)])); {$ENDIF} - // notify listeners - if Length(FMap) > 0 then begin - // calculate device's size from last block's offset and length - FRescueStatus.devicesize:=FMap[Length(FMap)-1].offset + FMap[Length(FMap)-1].length; - if prevHadFile then FPONotifyObservers(self, ooChange, nil) - else FPONotifyObservers(self, ooAddItem, nil); // notify of new file + // calculate device's size from last block's offset and length + if Length(newMap) > 0 then begin + newRescueStatus.devicesize:=newMap[Length(newMap)-1].offset + newMap[Length(newMap)-1].length; end else begin logMsg('Parser: No blocks in mapfile!'); - FPONotifyObservers(self, ooChange, nil); // notify any observers of the changes + newRescueStatus.devicesize := 0; end; + + + if (newRescueStatus.devicesize <> FRescueStatus.devicesize) and forceSameDevSize then begin + // Do NOT swap the new data set in, since it has an invalid device size + // and it's specified that we don't want that. Just deallocate memory we used. + newComments.Free; + end else begin + // swap new data set in + FRescueStatus := newRescueStatus; + FMap := newMap; + FComments.Free; + FComments := newComments; + FVersion := newVersion; + result := true; + end; + + if prevHadFile then FPONotifyObservers(self, ooChange, nil) // notify observers of the changes + else FPONotifyObservers(self, ooAddItem, nil); // notify of new file end; function TSimpleParser.hasFile: boolean; @@ -474,4 +508,22 @@ hasFile:=Assigned(FMapStream); end; +function TMapParser.getCommentLines(): TStringList; +begin + getCommentLines:=FMapParser.FComments;end; + +function TMapParser.getVersion(): String; +begin + getVersion:=FMapParser.FVersion; +end; + +function TMapParser.getMapFileName(): String; +begin + getMapFileName:=FMapParser.FFileName; +end; + +function TMapParser.getDomFileName(): String; +begin + getDomFileName:=FDomParser.FFileName; +end; end. diff -Nru ddrescueview-0.4~alpha3/source/settings.lfm ddrescueview-0.4~alpha4/source/settings.lfm --- ddrescueview-0.4~alpha3/source/settings.lfm 2015-05-19 16:10:52.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/settings.lfm 2020-08-26 14:20:05.000000000 +0000 @@ -1,7 +1,7 @@ object SettingsForm: TSettingsForm - Left = 1292 + Left = 1438 Height = 375 - Top = 127 + Top = 5 Width = 360 AutoSize = True BorderIcons = [biSystemMenu] @@ -15,7 +15,7 @@ OnShow = FormShow Position = poMainFormCenter ShowHint = True - LCLVersion = '1.4.0.4' + LCLVersion = '2.0.10.0' object Panel4: TPanel Left = 0 Height = 29 @@ -111,13 +111,7 @@ BorderSpacing.Around = 6 Color = clForm Constraints.MaxWidth = 32 - EditLabel.AnchorSideTop.Control = EditOutsideDomain - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = EditOutsideDomain - EditLabel.AnchorSideBottom.Side = asrBottom - EditLabel.Left = 41 EditLabel.Height = 15 - EditLabel.Top = 9 EditLabel.Width = 77 EditLabel.Caption = 'Not in domain' EditLabel.ParentColor = False @@ -185,13 +179,7 @@ BorderSpacing.Around = 6 Color = clForm Constraints.MaxWidth = 32 - EditLabel.AnchorSideTop.Control = EditNontried - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = EditNontried - EditLabel.AnchorSideBottom.Side = asrBottom - EditLabel.Left = 66 EditLabel.Height = 15 - EditLabel.Top = 9 EditLabel.Width = 52 EditLabel.Caption = 'Non-tried' EditLabel.ParentColor = False @@ -226,13 +214,7 @@ BorderSpacing.Around = 6 Color = clForm Constraints.MaxWidth = 32 - EditLabel.AnchorSideTop.Control = EditFinished - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = EditFinished - EditLabel.AnchorSideBottom.Side = asrBottom - EditLabel.Left = 74 EditLabel.Height = 15 - EditLabel.Top = 9 EditLabel.Width = 44 EditLabel.Caption = 'Rescued' EditLabel.ParentColor = False @@ -300,13 +282,7 @@ BorderSpacing.Around = 6 Color = clForm Constraints.MaxWidth = 32 - EditLabel.AnchorSideTop.Control = EditNontrimmed - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = EditNontrimmed - EditLabel.AnchorSideBottom.Side = asrBottom - EditLabel.Left = 44 EditLabel.Height = 15 - EditLabel.Top = 9 EditLabel.Width = 74 EditLabel.Caption = 'Non-trimmed' EditLabel.ParentColor = False @@ -374,13 +350,7 @@ BorderSpacing.Around = 6 Color = clForm Constraints.MaxWidth = 32 - EditLabel.AnchorSideTop.Control = EditNonscraped - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = EditNonscraped - EditLabel.AnchorSideBottom.Side = asrBottom - EditLabel.Left = 49 EditLabel.Height = 15 - EditLabel.Top = 9 EditLabel.Width = 69 EditLabel.Caption = 'Non-scraped' EditLabel.ParentColor = False @@ -447,13 +417,7 @@ BorderSpacing.Around = 6 Color = clForm Constraints.MaxWidth = 32 - EditLabel.AnchorSideTop.Control = EditBadSect - EditLabel.AnchorSideTop.Side = asrCenter - EditLabel.AnchorSideRight.Control = EditBadSect - EditLabel.AnchorSideBottom.Side = asrBottom - EditLabel.Left = 57 EditLabel.Height = 15 - EditLabel.Top = 9 EditLabel.Width = 61 EditLabel.Caption = 'Bad Sectors' EditLabel.ParentColor = False @@ -603,6 +567,19 @@ Checked = True OnChange = cbFastDrawingChange State = cbChecked + TabOrder = 1 + end + object cbAltZoom: TCheckBox + Left = 5 + Height = 19 + Top = 5 + Width = 130 + Align = alLeft + BorderSpacing.Around = 4 + Caption = 'Zoom to mouse pos.' + Checked = True + OnChange = cbAltZoomChange + State = cbChecked TabOrder = 0 end end diff -Nru ddrescueview-0.4~alpha3/source/settings.pas ddrescueview-0.4~alpha4/source/settings.pas --- ddrescueview-0.4~alpha3/source/settings.pas 2015-05-19 16:10:52.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/settings.pas 2020-08-26 14:20:05.000000000 +0000 @@ -1,7 +1,7 @@ (* Settings.pas - Settings GUI unit - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. @@ -36,6 +36,7 @@ btnClose: TButton; btnDefaults: TButton; cbFastDrawing: TCheckBox; + cbAltZoom: TCheckBox; colBtnActive: TColorButton; colBtnOutsideDomain: TColorButton; colBtnSelected: TColorButton; @@ -73,6 +74,7 @@ tbNontrimmed: TTrackBar; procedure btnCloseClick(Sender: TObject); procedure btnDefaultsClick(Sender: TObject); + procedure cbAltZoomChange(Sender: TObject); procedure cbFastDrawingChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); @@ -172,10 +174,17 @@ COLOR_BAD_SECT:=DEF_COLOR_BAD_SECT; COLOR_ACTIVE:=DEF_COLOR_ACTIVE; COLOR_SELECTED:=DEF_COLOR_SELECTED; + cbAltZoom.Checked:=true; + cbFastDrawing.Checked:=true; FormShow(self); FPONotifyObservers(self, ooChange, nil); end; +procedure TSettingsForm.cbAltZoomChange(Sender: TObject); +begin + MainForm.setZoomBehaviour(cbAltZoom.Checked); +end; + procedure TSettingsForm.cbFastDrawingChange(Sender: TObject); begin MainForm.setDrawFunction(false, Integer(cbFastDrawing.Checked)+1); diff -Nru ddrescueview-0.4~alpha3/source/Shared.pas ddrescueview-0.4~alpha4/source/Shared.pas --- ddrescueview-0.4~alpha3/source/Shared.pas 2016-07-19 21:42:46.000000000 +0000 +++ ddrescueview-0.4~alpha4/source/Shared.pas 2020-08-28 01:23:24.000000000 +0000 @@ -1,7 +1,7 @@ (* Shared.pas - Shared functionality - Copyright (C) 2013 - 2015 Martin Bittermann (martinbittermann@gmx.de) + Copyright (C) 2013 - 2020 Martin Bittermann (martinbittermann@gmx.de) This file is part of ddrescueview. @@ -130,7 +130,7 @@ PROGRAM_TITLE = 'ddrescueview'; VERSION_MAJOR = '0'; VERSION_MINOR = '4'; - VERSION_SUFFIX = 'alpha 3'; + VERSION_SUFFIX = 'alpha 4'; emptyRescueStatus : TRescueStatus = (devicesize : 0; suggestedBlockSize : DEF_BSIZE; pos : 0; rescued : 0; nontried : 0; bad : 0; nonscraped : 0; nontrimmed : 0; outsidedomain : 0;