2023-01-22 15:20:23 +01:00
|
|
|
(*
|
|
|
|
Copyright 2016-2023 Anton Krotov
|
|
|
|
|
|
|
|
This file is part of fb2read.
|
|
|
|
|
|
|
|
fb2read 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.
|
|
|
|
|
|
|
|
fb2read is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with fb2read. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*)
|
|
|
|
|
|
|
|
MODULE FB2READ;
|
|
|
|
|
|
|
|
IMPORT
|
|
|
|
|
|
|
|
DOM, SU := SysUtils, S := Strings, W := Window, Settings, OpenDlg,
|
|
|
|
G := Graph, SelEnc, Ini, File, box_lib, Font, SearchForm, Toolbar;
|
|
|
|
|
|
|
|
|
|
|
|
CONST
|
|
|
|
|
|
|
|
CLOSE = 1;
|
|
|
|
BACK = 16;
|
|
|
|
FORWARD = 17;
|
|
|
|
CONTENTS = 18;
|
|
|
|
DESCR = 19;
|
|
|
|
SETTINGS = 20;
|
|
|
|
SEARCH = 21;
|
|
|
|
|
2023-02-01 14:36:55 +01:00
|
|
|
KEY_DOWN = 80;
|
|
|
|
KEY_UP = 72;
|
|
|
|
KEY_PG_DOWN = 81;
|
|
|
|
KEY_PG_UP = 73;
|
|
|
|
KEY_HOME = 71;
|
|
|
|
KEY_END = 79;
|
|
|
|
KEY_F2 = 60;
|
|
|
|
KEY_F3 = 61;
|
|
|
|
KEY_F4 = 62;
|
|
|
|
KEY_F10 = 68;
|
2023-01-22 15:20:23 +01:00
|
|
|
|
|
|
|
TOOLBAR_LEFT = 5;
|
|
|
|
TOOLBAR_TOP = 6;
|
|
|
|
BUTTON_HEIGHT = 24;
|
|
|
|
|
|
|
|
CANVAS_LEFT = 1;
|
|
|
|
CANVAS_TOP = 2 * TOOLBAR_TOP + Toolbar.BtnSize;
|
|
|
|
|
|
|
|
WINDOW_BEVEL = 4;
|
|
|
|
|
|
|
|
SCROLLBAR_WIDTH = 20;
|
|
|
|
STATUSBAR_HEIGHT = 18;
|
|
|
|
|
|
|
|
VAR
|
|
|
|
|
2023-02-01 14:36:55 +01:00
|
|
|
Window : W.tWindow;
|
2023-01-22 15:20:23 +01:00
|
|
|
toolbar : Toolbar.tToolbar;
|
|
|
|
SkinHeight : INTEGER;
|
|
|
|
Open : OpenDlg.Dialog;
|
|
|
|
FileName : S.STRING;
|
|
|
|
sb : box_lib.scrollbar;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE ToolbarEnable;
|
|
|
|
BEGIN
|
|
|
|
Toolbar.enable(toolbar, BACK, DOM.BackEnabled());
|
|
|
|
Toolbar.enable(toolbar, FORWARD, DOM.FrwEnabled());
|
|
|
|
Toolbar.enable(toolbar, CONTENTS, DOM.ContentsEnabled());
|
|
|
|
Toolbar.enable(toolbar, DESCR, DOM.DescrEnabled());
|
|
|
|
END ToolbarEnable;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE ToolBar;
|
|
|
|
BEGIN
|
|
|
|
sb := box_lib.kolibri_scrollbar(sb, (G.Buffer.Width + CANVAS_LEFT) * 65536 + SCROLLBAR_WIDTH + 1,
|
|
|
|
CANVAS_TOP * 65536 + G.Buffer.Height, SCROLLBAR_WIDTH, sb.max_area, sb.cur_area, sb.position, SU.lightColor, SU.btnColor, 0, 0);
|
|
|
|
box_lib.scrollbar_v_draw(sb);
|
|
|
|
ToolbarEnable;
|
|
|
|
Toolbar.draw(toolbar);
|
|
|
|
END ToolBar;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE Resize;
|
|
|
|
VAR Width, Height: INTEGER;
|
|
|
|
BEGIN
|
2023-02-01 14:36:55 +01:00
|
|
|
SU.GetWindowPos(Window.left, Window.top);
|
2023-01-22 15:20:23 +01:00
|
|
|
SU.GetWindowSize(Width, Height);
|
2023-02-01 14:36:55 +01:00
|
|
|
IF (Window.width # Width) OR (Window.height # Height) OR (SkinHeight # SU.SkinHeight()) THEN
|
2023-01-22 15:20:23 +01:00
|
|
|
SU.MinMax(Width, 640, 65535);
|
|
|
|
SU.MinMax(Height, 400, 65535);
|
2023-02-01 14:36:55 +01:00
|
|
|
Window.dWidth := Width - Window.width;
|
|
|
|
Window.dHeight := Height - Window.height;
|
|
|
|
Window.width := Width;
|
|
|
|
Window.height := Height;
|
2023-01-22 15:20:23 +01:00
|
|
|
SU.SetWindowSize(Width, Height);
|
|
|
|
DOM.Resize(G.Buffer.Width + Window.dWidth, G.Buffer.Height + Window.dHeight + (SkinHeight - SU.SkinHeight()));
|
|
|
|
SkinHeight := SU.SkinHeight()
|
|
|
|
END
|
|
|
|
END Resize;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE DrawStatus;
|
|
|
|
BEGIN
|
2023-02-01 14:36:55 +01:00
|
|
|
SU.DrawRect(0, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1, Window.width - 2 * WINDOW_BEVEL - 1, STATUSBAR_HEIGHT, SU.winColor);
|
2023-01-22 15:20:23 +01:00
|
|
|
IF DOM.urlstr # "" THEN
|
2023-02-01 14:36:55 +01:00
|
|
|
SU.OutText(CANVAS_LEFT, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 2, DOM.urlstr,
|
|
|
|
MIN(LENGTH(DOM.urlstr), (Window.width - 2 * WINDOW_BEVEL - 1 - CANVAS_LEFT * 2) DIV 8), SU.textColor)
|
2023-01-22 15:20:23 +01:00
|
|
|
ELSIF DOM.found() THEN
|
2023-02-01 14:36:55 +01:00
|
|
|
SU.OutText(CANVAS_LEFT, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 2,
|
2023-01-22 15:20:23 +01:00
|
|
|
"F2 - first | F3 - next | F4 - prev. | F10 - exit", 48, SU.textColor)
|
|
|
|
END
|
|
|
|
END DrawStatus;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE DrawWindow;
|
|
|
|
BEGIN
|
2023-04-11 23:53:43 +02:00
|
|
|
SU.GetSystemColors;
|
|
|
|
SU.WindowRedrawStatus(1);
|
|
|
|
IF Window.created THEN
|
|
|
|
IF ~SU.RolledUp() THEN
|
|
|
|
Resize;
|
|
|
|
DOM.SetWinSize(Window.width, Window.height)
|
|
|
|
END
|
|
|
|
ELSE
|
|
|
|
Window.created := TRUE
|
|
|
|
END;
|
|
|
|
SU.DefineAndDrawWindow(Window.left, Window.top, Window.width, Window.height,
|
|
|
|
SU.winColor, LSL(ORD({0, 1, 2}), 4) + 4 - ORD(DOM.loaded), Window.caption);
|
|
|
|
IF ~SU.RolledUp() THEN
|
|
|
|
SU.DrawRect(0, 0, Window.width - 2 * WINDOW_BEVEL - 1, CANVAS_TOP, SU.winColor);
|
|
|
|
SU.DrawRect(0, Window.height - SkinHeight - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1, Window.width - 2 * WINDOW_BEVEL - 1, STATUSBAR_HEIGHT, SU.winColor);
|
|
|
|
SU.DrawRect(0, 0, CANVAS_LEFT, Window.height - SkinHeight - WINDOW_BEVEL, SU.winColor);
|
|
|
|
SU.DrawRect(Window.width - 2 * WINDOW_BEVEL - CANVAS_LEFT - 1 - SCROLLBAR_WIDTH - 2, 0, CANVAS_LEFT + SCROLLBAR_WIDTH + 2, Window.height - SkinHeight - WINDOW_BEVEL, SU.winColor);
|
|
|
|
IF DOM.loaded THEN
|
|
|
|
ToolBar;
|
|
|
|
DOM.Draw;
|
|
|
|
DrawStatus
|
|
|
|
END
|
|
|
|
END;
|
|
|
|
SU.WindowRedrawStatus(2)
|
2023-01-22 15:20:23 +01:00
|
|
|
END DrawWindow;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE ConvMousePos(VAR X, Y: INTEGER);
|
|
|
|
BEGIN
|
2023-02-01 14:36:55 +01:00
|
|
|
X := X - Window.left - WINDOW_BEVEL - 1;
|
|
|
|
Y := Y - Window.top - SkinHeight
|
2023-01-22 15:20:23 +01:00
|
|
|
END ConvMousePos;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE DrawToolbar;
|
|
|
|
BEGIN
|
|
|
|
ToolbarEnable;
|
|
|
|
Toolbar.drawIcons(toolbar)
|
|
|
|
END DrawToolbar;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE ButtonClick;
|
|
|
|
BEGIN
|
|
|
|
CASE SU.GetButtonCode() OF
|
|
|
|
|0 :
|
|
|
|
|CLOSE : SearchForm.close(FALSE);
|
|
|
|
Settings.Close;
|
|
|
|
DOM.Close
|
|
|
|
|BACK : DOM.Back
|
|
|
|
|FORWARD : DOM.Forward
|
|
|
|
|CONTENTS : DOM.Contents
|
|
|
|
|DESCR : DOM.Descr
|
|
|
|
|SEARCH : DOM.OpenSearch
|
|
|
|
|SETTINGS : Settings.Open
|
|
|
|
END;
|
|
|
|
DOM.Draw;
|
|
|
|
DrawStatus
|
|
|
|
END ButtonClick;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE KeyDown;
|
2023-02-01 14:36:55 +01:00
|
|
|
VAR
|
|
|
|
key: INTEGER;
|
|
|
|
shift, ctrl: BOOLEAN;
|
2023-01-22 15:20:23 +01:00
|
|
|
BEGIN
|
2023-02-01 14:36:55 +01:00
|
|
|
SU.getKBState(shift, ctrl);
|
|
|
|
key := SU.GetKey() DIV 65536;
|
|
|
|
CASE key OF
|
|
|
|
|KEY_DOWN : DOM.Scroll(1)
|
|
|
|
|KEY_UP : DOM.Scroll(-1)
|
|
|
|
|KEY_PG_DOWN : DOM.PageDown
|
|
|
|
|KEY_PG_UP : DOM.PageUp
|
|
|
|
|KEY_HOME : DOM.Home
|
|
|
|
|KEY_END : DOM.End
|
|
|
|
|KEY_F2 : DOM.Find(0)
|
|
|
|
|KEY_F3 : DOM.Find(1)
|
|
|
|
|KEY_F4 : DOM.Find(-1)
|
|
|
|
|KEY_F10 : DOM.CloseSearch
|
|
|
|
|33 : IF ctrl THEN DOM.OpenSearch END (* ctrl-F *)
|
|
|
|
ELSE
|
|
|
|
END;
|
|
|
|
DOM.Draw;
|
|
|
|
DrawStatus
|
2023-01-22 15:20:23 +01:00
|
|
|
END KeyDown;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE CanvasIsClicked(X, Y: INTEGER): BOOLEAN;
|
|
|
|
RETURN
|
|
|
|
(CANVAS_LEFT <= X) & (X < CANVAS_LEFT + G.Buffer.Width) &
|
|
|
|
(CANVAS_TOP <= Y) & (Y < CANVAS_TOP + G.Buffer.Height)
|
|
|
|
END CanvasIsClicked;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE MouseEvent;
|
|
|
|
VAR
|
|
|
|
mouse_status : SET;
|
|
|
|
X, Y : INTEGER;
|
|
|
|
scroll : INTEGER;
|
|
|
|
BEGIN
|
|
|
|
SU.MousePos(X, Y);
|
|
|
|
mouse_status := SU.MouseStatus();
|
|
|
|
scroll := SU.MouseVScroll();
|
|
|
|
IF SU.L_BUTTON IN mouse_status THEN
|
|
|
|
ConvMousePos(X, Y);
|
|
|
|
IF CanvasIsClicked(X, Y) THEN
|
|
|
|
X := X - CANVAS_LEFT;
|
|
|
|
Y := Y - CANVAS_TOP;
|
|
|
|
DOM.Click(X, Y, TRUE)
|
|
|
|
END
|
|
|
|
ELSIF scroll # 0 THEN
|
2023-02-01 14:36:55 +01:00
|
|
|
DOM.Scroll(scroll*2);
|
2023-01-22 15:20:23 +01:00
|
|
|
DOM.Draw
|
|
|
|
ELSE
|
|
|
|
ConvMousePos(X, Y);
|
|
|
|
IF CanvasIsClicked(X, Y) THEN
|
|
|
|
X := X - CANVAS_LEFT;
|
|
|
|
Y := Y - CANVAS_TOP;
|
|
|
|
DOM.Click(X, Y, FALSE)
|
|
|
|
END
|
|
|
|
END
|
|
|
|
END MouseEvent;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE Empty;
|
|
|
|
END Empty;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE OpenFile;
|
|
|
|
BEGIN
|
|
|
|
Open := OpenDlg.Create(Empty, 0, Ini.Default, Ini.Files);
|
|
|
|
OpenDlg.Show(Open, 500, 400);
|
|
|
|
WHILE Open.status = 2 DO
|
|
|
|
SU.Pause(30)
|
|
|
|
END;
|
|
|
|
IF Open.status = 0 THEN
|
|
|
|
SU.Halt
|
|
|
|
END;
|
|
|
|
COPY(Open.FilePath, FileName);
|
|
|
|
OpenDlg.Destroy(Open)
|
|
|
|
END OpenFile;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE IsFB2(FileName: S.STRING): BOOLEAN;
|
|
|
|
VAR temp: S.STRING;
|
|
|
|
BEGIN
|
|
|
|
temp := FileName;
|
|
|
|
S.Reverse(temp);
|
|
|
|
temp[4] := 0X;
|
|
|
|
S.UCase(temp)
|
|
|
|
RETURN temp = "2BF."
|
|
|
|
END IsFB2;
|
|
|
|
|
|
|
|
|
|
|
|
PROCEDURE main(title: ARRAY OF CHAR);
|
2023-04-11 23:53:43 +02:00
|
|
|
VAR
|
|
|
|
WinW, X1, Y1, X2, Y2, scr_pos, ignore: INTEGER;
|
|
|
|
Win2: W.tWindow; resize: BOOLEAN;
|
|
|
|
FilePath: S.STRING; defpath: BOOLEAN;
|
2023-01-22 15:20:23 +01:00
|
|
|
BEGIN
|
|
|
|
SkinHeight := SU.SkinHeight();
|
|
|
|
sb := box_lib.kolibri_new_scrollbar(10 * 65536 + 200, 10 * 65536 + 30, 25, 15, 10, 0, 0, 0, 0, 0);
|
|
|
|
DOM.SetScrollBar(sb);
|
|
|
|
defpath := TRUE;
|
|
|
|
SU.GetParam(FileName);
|
|
|
|
IF FileName = "" THEN
|
|
|
|
OpenFile
|
|
|
|
END;
|
|
|
|
|
|
|
|
IF FileName[0] = "!" THEN
|
|
|
|
FileName[0] := "/";
|
|
|
|
defpath := FALSE
|
|
|
|
END;
|
|
|
|
|
|
|
|
IF defpath THEN
|
|
|
|
FilePath := FileName;
|
|
|
|
S.GetPath(FilePath);
|
|
|
|
Ini.SetDefaultPath(FilePath);
|
|
|
|
DOM.SetColors;
|
|
|
|
DOM.Set_b_pict(Ini.b_pict);
|
|
|
|
Ini.Save(DOM.Settings.Colors, DOM.Settings.b_pict)
|
|
|
|
END;
|
|
|
|
|
|
|
|
IF ~IsFB2(FileName) THEN
|
|
|
|
SelEnc.Show(FileName)
|
|
|
|
END;
|
|
|
|
|
|
|
|
SU.SetEventsMask({0, 1, 2, 5, 31});
|
|
|
|
SU.GetScreenArea(X1, Y1, X2, Y2);
|
|
|
|
WinW := (X2 - X1) DIV 2;
|
2023-04-11 23:53:43 +02:00
|
|
|
SU.MinMax(WinW, 640, 65535);
|
|
|
|
W.init(Window, (X2 - X1 - WinW) DIV 2, Y1, WinW, Y2 - Y1, title);
|
2023-01-22 15:20:23 +01:00
|
|
|
Settings.Default;
|
2023-02-01 14:36:55 +01:00
|
|
|
DOM.GetWinSize(FileName, Window.width, Window.height);
|
2023-01-22 15:20:23 +01:00
|
|
|
|
|
|
|
Win2 := Window;
|
|
|
|
resize := FALSE;
|
2023-02-01 14:36:55 +01:00
|
|
|
IF Win2.width > X2 - X1 THEN
|
|
|
|
Win2.width := X2 - X1;
|
2023-01-22 15:20:23 +01:00
|
|
|
resize := TRUE
|
|
|
|
END;
|
|
|
|
|
2023-02-01 14:36:55 +01:00
|
|
|
IF Win2.height > Y2 - Y1 THEN
|
|
|
|
Win2.height := Y2 - Y1;
|
2023-01-22 15:20:23 +01:00
|
|
|
resize := TRUE
|
|
|
|
END;
|
|
|
|
|
|
|
|
DOM.Init(CANVAS_LEFT, CANVAS_TOP,
|
2023-02-01 14:36:55 +01:00
|
|
|
Window.width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH - 2,
|
|
|
|
Window.height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL - STATUSBAR_HEIGHT + 1);
|
2023-01-22 15:20:23 +01:00
|
|
|
DOM.SetColors;
|
|
|
|
DOM.Set_b_pict(Ini.b_pict);
|
|
|
|
Window := Win2;
|
2023-02-01 14:36:55 +01:00
|
|
|
G.InitSize(Window.width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH, Window.height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL + 1 - STATUSBAR_HEIGHT);
|
|
|
|
S.Append(Window.caption, " - ");
|
|
|
|
S.Append(Window.caption, FileName);
|
2023-01-22 15:20:23 +01:00
|
|
|
|
|
|
|
Toolbar.create(toolbar, TOOLBAR_LEFT, TOOLBAR_TOP);
|
2023-04-11 23:53:43 +02:00
|
|
|
Toolbar.add(toolbar, BACK, 30, "");
|
|
|
|
Toolbar.add(toolbar, FORWARD, 31, "");
|
|
|
|
Toolbar.delimiter(toolbar);
|
|
|
|
Toolbar.add(toolbar, CONTENTS, 3, "");
|
|
|
|
Toolbar.delimiter(toolbar);
|
|
|
|
Toolbar.add(toolbar, SEARCH, 49, "");
|
|
|
|
Toolbar.delimiter(toolbar);
|
|
|
|
Toolbar.add(toolbar, DESCR, 66, "");
|
|
|
|
Toolbar.delimiter(toolbar);
|
|
|
|
Toolbar.add(toolbar, SETTINGS, 60, "");
|
|
|
|
|
|
|
|
DOM.Open(FileName, DrawWindow, DrawStatus, DrawToolbar);
|
|
|
|
IF resize THEN
|
|
|
|
DOM.Resize(Window.width - 2 * CANVAS_LEFT - 2 * WINDOW_BEVEL - 1 - SCROLLBAR_WIDTH,
|
|
|
|
Window.height - SkinHeight - CANVAS_TOP - WINDOW_BEVEL + 1 - STATUSBAR_HEIGHT)
|
|
|
|
END;
|
2023-01-22 15:20:23 +01:00
|
|
|
|
2023-04-11 23:53:43 +02:00
|
|
|
DrawWindow;
|
|
|
|
scr_pos := sb.position;
|
|
|
|
WHILE TRUE DO
|
|
|
|
CASE SU.WaitForEvent() OF
|
|
|
|
|1 : DrawWindow
|
|
|
|
|2 :
|
|
|
|
IF ~SU.RolledUp() THEN
|
|
|
|
KeyDown
|
|
|
|
ELSE
|
|
|
|
ignore := SU.GetKey()
|
|
|
|
END
|
|
|
|
|3 : ButtonClick
|
|
|
|
|6 :
|
|
|
|
IF ~SU.RolledUp() THEN
|
|
|
|
box_lib.scrollbar_v_mouse(sb);
|
|
|
|
IF sb.position # scr_pos THEN
|
|
|
|
DOM.ScrollBar;
|
|
|
|
DOM.Draw;
|
|
|
|
scr_pos := sb.position;
|
|
|
|
END;
|
|
|
|
MouseEvent
|
|
|
|
ELSE
|
|
|
|
ignore := SU.MouseVScroll()
|
|
|
|
END
|
|
|
|
END
|
|
|
|
END
|
2023-01-22 15:20:23 +01:00
|
|
|
END main;
|
|
|
|
|
|
|
|
|
|
|
|
BEGIN
|
2023-04-11 23:53:43 +02:00
|
|
|
main("FB2 Reader v0.97c")
|
2023-01-22 15:20:23 +01:00
|
|
|
END FB2READ.
|