root/trunk/Forms/frm_main.pas

463464
1
(* *****************************************************************************
2
  *
3
  * MyHomeLib
4
  *
5
  * Copyright (C) 2008-2010 Aleksey Penkov
6
  *
7
  * Authors Aleksey Penkov   alex.penkov@gmail.com
8
  *         Nick Rymanov     nrymanov@gmail.com
9
  *
10
  ****************************************************************************** *)
1
11
2
{******************************************************************************}
3
{                                                                              }
4
{                                 MyHomeLib                                    }
5
{                                                                              }
6
{                                Version 0.9                                   }
7
{                                20.08.2008                                    }
8
{                    Copyright (c) Aleksey Penkov  alex.penkov@gmail.com       }
9
{                                                                              }
10
{******************************************************************************}
11
12
unit frm_main;
12
unit frm_main;
13
13
14
interface
14
interface
...
...
63
  jpeg,
63
  jpeg,
64
  IdCookieManager,
64
  IdCookieManager,
65
  unit_database,
65
  unit_database,
66
 // oxmldom,
66
  // oxmldom,
67
  DBTables,
67
  DBTables,
68
  Clipbrd,
68
  Clipbrd,
69
  RzCmboBx,
69
  RzCmboBx,
...
...
80
  ActiveX,
80
  ActiveX,
81
  htmlhlp,
81
  htmlhlp,
82
  IdCustomTransparentProxy,
82
  IdCustomTransparentProxy,
83
  IdConnectThroughHttpProxy, Grids, DBGrids;
83
  IdConnectThroughHttpProxy,
84
  Grids,
85
  DBGrids;
84
86
85
type
87
type
86
88
...
...
419
    //
421
    //
420
    //
422
    //
421
    //
423
    //
422
    procedure tvAuthorsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
424
    procedure tvAuthorsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
423
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
425
    procedure tvBooksAGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
424
    procedure tvBooksAGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
426
    procedure tvBooksGGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
425
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
427
    procedure tvBooksSGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
426
    procedure tvBooksGGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
428
    procedure tvBooksFGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
427
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
429
    procedure tvBooksSRGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
428
    procedure tvBooksSGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
430
    procedure tvGenresGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
429
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
430
    procedure tvBooksFGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
431
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
432
    procedure tvBooksSRGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
433
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
434
    procedure tvGenresGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
435
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
436
431
437
    //
432
    //
438
    //
433
    //
...
...
445
    // Код следующих 4-х методов совпадает с точностью до названия объектов
440
    // Код следующих 4-х методов совпадает с точностью до названия объектов
446
    // НО! внутри обрабатываются разные наборы контролов
441
    // НО! внутри обрабатываются разные наборы контролов
447
    //
442
    //
448
    procedure tvAuthorsPaintText(Sender: TBaseVirtualTree;
443
    procedure tvAuthorsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
449
      const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
450
      TextType: TVSTTextType);
451
444
452
    //
445
    //
453
    //
446
    //
454
    //
447
    //
455
    procedure tvBooksTreeBeforeCellPaint(Sender: TBaseVirtualTree;
448
    procedure tvBooksTreeBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
456
      TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
449
    procedure tvBooksTreeAfterCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellRect: TRect);
457
      CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
458
    procedure tvBooksTreeAfterCellPaint(Sender: TBaseVirtualTree;
459
      TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
460
      CellRect: TRect);
461
450
462
    //
451
    //
463
    //
452
    //
464
    //
453
    //
465
    procedure tvBooksAGetNodeDataSize(Sender: TBaseVirtualTree;
454
    procedure tvBooksAGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
466
      var NodeDataSize: Integer);
455
    procedure tvAuthorsGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
467
    procedure tvAuthorsGetNodeDataSize(Sender: TBaseVirtualTree;
456
    procedure tvBooksGGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
468
      var NodeDataSize: Integer);
469
    procedure tvBooksGGetNodeDataSize(Sender: TBaseVirtualTree;
470
      var NodeDataSize: Integer);
471
457
472
    //
458
    //
473
    //
459
    //
...
...
486
    procedure pmiDeselectAllClick(Sender: TObject);
472
    procedure pmiDeselectAllClick(Sender: TObject);
487
    procedure miCopyClBrdClick(Sender: TObject);
473
    procedure miCopyClBrdClick(Sender: TObject);
488
474
489
490
    procedure miDelFavoritesClick(Sender: TObject);
475
    procedure miDelFavoritesClick(Sender: TObject);
491
    procedure miSetRateClick(Sender: TObject);
476
    procedure miSetRateClick(Sender: TObject);
492
    procedure miClearRateClick(Sender: TObject);
477
    procedure miClearRateClick(Sender: TObject);
...
...
529
    //
514
    //
530
    //
515
    //
531
    //
516
    //
532
    procedure tvBooksTreeHeaderClick(Sender: TVTHeader;
517
    procedure tvBooksTreeHeaderClick(Sender: TVTHeader; HitInfo: TVTHeaderHitInfo);
533
  HitInfo: TVTHeaderHitInfo);
518
    procedure tvBooksTreeCompareNodes(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
534
    procedure tvBooksTreeCompareNodes(Sender: TBaseVirtualTree; Node1,
519
    procedure tvBooksTreePaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
535
      Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
536
    procedure tvBooksTreePaintText(Sender: TBaseVirtualTree;
537
      const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
538
      TextType: TVSTTextType);
539
    procedure tbtnShowLocalOnlyClick(Sender: TObject);
520
    procedure tbtnShowLocalOnlyClick(Sender: TObject);
540
    procedure ShowNewCollectionWizard(Sender: TObject);
521
    procedure ShowNewCollectionWizard(Sender: TObject);
541
    procedure HTTPWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
522
    procedure HTTPWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
542
    procedure btnApplyFilterClick(Sender: TObject);
523
    procedure btnApplyFilterClick(Sender: TObject);
543
    procedure btnClearFilterEditsClick(Sender: TObject);
524
    procedure btnClearFilterEditsClick(Sender: TObject);
544
    procedure tvBooksTreeMouseUp(Sender: TObject; Button: TMouseButton;
525
    procedure tvBooksTreeMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
545
      Shift: TShiftState; X, Y: Integer);
526
    procedure tvBooksTreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
546
    procedure tvBooksTreeKeyDown(Sender: TObject; var Key: Word;
527
    procedure edFFullNameKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
547
      Shift: TShiftState);
548
    procedure edFFullNameKeyDown(Sender: TObject; var Key: Word;
549
      Shift: TShiftState);
550
    procedure tbClearEdAuthorClick(Sender: TObject);
528
    procedure tbClearEdAuthorClick(Sender: TObject);
551
    procedure btnClearEdSeriesClick(Sender: TObject);
529
    procedure btnClearEdSeriesClick(Sender: TObject);
552
    procedure tvBooksTreeChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
530
    procedure tvBooksTreeChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
553
    procedure tvBooksTreeInitNode(Sender: TBaseVirtualTree; ParentNode,
531
    procedure tvBooksTreeInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
554
      Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
555
    procedure HeaderPopupItemClick(Sender: TObject);
532
    procedure HeaderPopupItemClick(Sender: TObject);
556
    procedure N27Click(Sender: TObject);
533
    procedure N27Click(Sender: TObject);
557
    procedure CoverPanelResize(Sender: TObject);
534
    procedure CoverPanelResize(Sender: TObject);
...
...
559
    procedure N33Click(Sender: TObject);
536
    procedure N33Click(Sender: TObject);
560
    procedure btnStartDownloadClick(Sender: TObject);
537
    procedure btnStartDownloadClick(Sender: TObject);
561
    procedure btnPauseDownloadClick(Sender: TObject);
538
    procedure btnPauseDownloadClick(Sender: TObject);
562
    procedure tvDownloadListGetText(Sender: TBaseVirtualTree;
539
    procedure tvDownloadListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
563
      Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
564
      var CellText: string);
565
    procedure btnDeleteDownloadClick(Sender: TObject);
540
    procedure btnDeleteDownloadClick(Sender: TObject);
566
    procedure mi_dwnl_LocateAuthorClick(Sender: TObject);
541
    procedure mi_dwnl_LocateAuthorClick(Sender: TObject);
567
    procedure btnClearDownloadClick(Sender: TObject);
542
    procedure btnClearDownloadClick(Sender: TObject);
568
    procedure tvDownloadListSaveNode(Sender: TBaseVirtualTree;
543
    procedure tvDownloadListSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream);
569
      Node: PVirtualNode; Stream: TStream);
544
    procedure tvDownloadListLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream);
570
    procedure tvDownloadListLoadNode(Sender: TBaseVirtualTree;
571
      Node: PVirtualNode; Stream: TStream);
572
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
545
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
573
    procedure N34Click(Sender: TObject);
546
    procedure N34Click(Sender: TObject);
574
    procedure MoveDwnldListNodes(Sender: TObject);
547
    procedure MoveDwnldListNodes(Sender: TObject);
575
    procedure BtnFav_addClick(Sender: TObject);
548
    procedure BtnFav_addClick(Sender: TObject);
576
    procedure tvDownloadListPaintText(Sender: TBaseVirtualTree;
549
    procedure tvDownloadListPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
577
      const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
578
      TextType: TVSTTextType);
579
    procedure BtnSaveClick(Sender: TObject);
550
    procedure BtnSaveClick(Sender: TObject);
580
    procedure edLocateAuthorKeyDown(Sender: TObject; var Key: Word;
551
    procedure edLocateAuthorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
581
      Shift: TShiftState);
582
    procedure btnSavePresetClick(Sender: TObject);
552
    procedure btnSavePresetClick(Sender: TObject);
583
    procedure edFFullNameButtonClick(Sender: TObject);
553
    procedure edFFullNameButtonClick(Sender: TObject);
584
    procedure cbPresetNameChange(Sender: TObject);
554
    procedure cbPresetNameChange(Sender: TObject);
...
...
588
    procedure miAddToSearchClick(Sender: TObject);
558
    procedure miAddToSearchClick(Sender: TObject);
589
    procedure miINPXCollectionExportClick(Sender: TObject);
559
    procedure miINPXCollectionExportClick(Sender: TObject);
590
    procedure pmAuthorPopup(Sender: TObject);
560
    procedure pmAuthorPopup(Sender: TObject);
591
    procedure tvGroupsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
561
    procedure tvGroupsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
592
      Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
562
    procedure tvGroupsGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
593
    procedure tvGroupsGetNodeDataSize(Sender: TBaseVirtualTree;
594
      var NodeDataSize: Integer);
595
    procedure tvGroupsChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
563
    procedure tvGroupsChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
596
    procedure GroupMenuItemClick(Sender: TObject);
564
    procedure GroupMenuItemClick(Sender: TObject);
597
    procedure btnAddGroupClick(Sender: TObject);
565
    procedure btnAddGroupClick(Sender: TObject);
598
    procedure btnDeleteGroupClick(Sender: TObject);
566
    procedure btnDeleteGroupClick(Sender: TObject);
599
    procedure tvGroupsDragOver(Sender: TBaseVirtualTree; Source: TObject;
567
    procedure tvGroupsDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
600
      Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode;
568
    procedure tvGroupsDragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
601
      var Effect: Integer; var Accept: Boolean);
602
    procedure tvGroupsDragDrop(Sender: TBaseVirtualTree; Source: TObject;
603
      DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState;
604
      Pt: TPoint; var Effect: Integer; Mode: TDropMode);
605
    procedure miImportUserDataClick(Sender: TObject);
569
    procedure miImportUserDataClick(Sender: TObject);
606
    procedure miReadedClick(Sender: TObject);
570
    procedure miReadedClick(Sender: TObject);
607
    procedure miExportUserDataClick(Sender: TObject);
571
    procedure miExportUserDataClick(Sender: TObject);
...
...
621
    procedure tvSeriesClick(Sender: TObject);
585
    procedure tvSeriesClick(Sender: TObject);
622
    procedure tvGenresClick(Sender: TObject);
586
    procedure tvGenresClick(Sender: TObject);
623
    procedure tvGroupsClick(Sender: TObject);
587
    procedure tvGroupsClick(Sender: TObject);
624
    procedure tvAuthorsKeyDown(Sender: TObject; var Key: Word;
588
    procedure tvAuthorsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
625
      Shift: TShiftState);
589
    procedure tvSeriesKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
626
    procedure tvSeriesKeyDown(Sender: TObject; var Key: Word;
590
    procedure tvGenresKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
627
      Shift: TShiftState);
591
    procedure tvGroupsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
628
    procedure tvGenresKeyDown(Sender: TObject; var Key: Word;
629
      Shift: TShiftState);
630
    procedure tvGroupsKeyDown(Sender: TObject; var Key: Word;
631
      Shift: TShiftState);
632
    procedure FormResize(Sender: TObject);
592
    procedure FormResize(Sender: TObject);
633
593
634
  protected
594
  protected
635
    procedure OnBookDownloadComplete(var Message: TDownloadCompleteMessage); message WM_MHL_DOWNLOAD_COMPLETE;
595
    procedure OnBookDownloadComplete(var message: TDownloadCompleteMessage); message WM_MHL_DOWNLOAD_COMPLETE;
636
596
637
  private
597
  private type
638
    type
598
    TView = (ByAuthorView, BySeriesView, ByGenreView, SearchView, FavoritesView, DownloadView);
639
      TView = (ByAuthorView, BySeriesView, ByGenreView, SearchView, FavoritesView, DownloadView);
640
599
600
    TSortSetting = record
601
      Column: TColumnIndex;
602
      Direction: TSortDirection;
603
    end;
604
641
  private
605
  private
642
    FDMThread: TDownloadManagerThread;
606
    FDMThread: TDownloadManagerThread;
643
607
644
    FLastActiveBookID: integer;
608
    FLastActiveBookID: Integer;
645
609
646
647
    // поиск аторов, серий
    FIgnoreChange : boolean;
610
    // поиск аторов, серий
    FIgnoreChange : boolean;
611
    FIgnoreChange: Boolean;
648
612
649
    //
613
    //
650
    // Построение деревьев
    //
614
    // Построение деревьев
    //
651
    procedure FillSeriesTree;
615
    procedure FillSeriesTree;
652
    procedure FillBooksTree(
616
    procedure FillBooksTree(const ParentID: Integer; const Tree: TVirtualStringTree; const Master: TDataset; const Detail: TDataset; ShowAuth: Boolean; ShowSer: Boolean);
653
      const ParentID: Integer;
654
      const Tree: TVirtualStringTree;
655
      const Master: TDataset;
656
      const Detail: TDataSet;
657
      ShowAuth: Boolean;
658
      ShowSer: Boolean
659
      );
660
617
661
    procedure FillGroupsList;
618
    procedure FillGroupsList;
662
619
...
...
671
627
672
    function GetViewTree(view: TView): TVirtualStringTree;
628
    function GetViewTree(view: TView): TVirtualStringTree;
673
    procedure GetActiveTree(var Tree: TVirtualStringTree);
629
    procedure GetActiveTree(var Tree: TVirtualStringTree);
674
    procedure Selection(SelState: boolean);
630
    procedure Selection(SelState: Boolean);
675
    procedure LocateAuthor(text: String; Tree: TVirtualStringTree);
631
    procedure LocateAuthor(text: string; Tree: TVirtualStringTree);
676
    procedure InitCollection(ApplyAuthorFilter: Boolean);
632
    procedure InitCollection(ApplyAuthorFilter: Boolean);
677
633
678
    procedure CreateCollectionMenu;
634
    procedure CreateCollectionMenu;
...
...
680
    procedure SetColors;
636
    procedure SetColors;
681
    procedure CreateAlphabet;
637
    procedure CreateAlphabet;
682
638
683
    procedure GetBookRecord(const ID: integer; var R: TBookRecord);
639
    procedure GetBookRecord(const ID: Integer; var R: TBookRecord);
684
640
685
    function IsLibRusecEdit(ID: integer): boolean;
641
    function IsLibRusecEdit(ID: Integer): Boolean;
686
642
687
    procedure WMGetSysCommand(var Message :TMessage); message WM_SYSCOMMAND;
643
    procedure WMGetSysCommand(var message: TMessage); message WM_SYSCOMMAND;
688
644
689
  public
645
  public
690
    FCancelled : boolean;
646
    FCancelled: Boolean;
691
647
692
    procedure FillAuthorTree(Tree: TVirtualStringTree; FullMode: boolean = False);
648
    procedure FillAuthorTree(Tree: TVirtualStringTree; FullMode: Boolean = False);
693
649
694
    procedure FillGenresTree(Tree: TVirtualStringTree; FillFB2: boolean = False);
650
    procedure FillGenresTree(Tree: TVirtualStringTree; FillFB2: Boolean = False);
695
    procedure DisableControls(State: boolean);
651
    procedure DisableControls(State: Boolean);
696
652
697
    function HH(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
653
    function HH(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
698
    procedure LocateBook(text: String; Next : boolean);
654
    procedure LocateBook(text: string; Next: Boolean);
699
655
700
    procedure SelectNextBook(Changed, Frwrd: boolean);
656
    procedure SelectNextBook(Changed, Frwrd: Boolean);
701
657
702
    property LastActiveBookID: integer read FLastActiveBookID;
658
    property LastActiveBookID: Integer read FLastActiveBookID;
703
659
704
    procedure SetFormState;
660
    procedure SetFormState;
661
705
  private
662
  private
706
    FSelectionState: boolean;
663
    FSelectionState: Boolean;
707
    FCollectionRoot: string;
664
    FCollectionRoot: string;
708
665
709
    FAutoCheck: boolean;
666
    FAutoCheck: Boolean;
710
    FFormBusy: boolean;
667
    FFormBusy: Boolean;
711
668
712
    FFileOpMode: (fmFb2Zip, fmFb2);
669
    FFileOpMode: (fmFb2Zip, fmFb2);
713
    FDoNotLocate: Boolean;
670
    FDoNotLocate: Boolean;
...
...
718
    ALetter: TToolButton;
675
    ALetter: TToolButton;
719
    BookTreeStatus: (bsFree, bsBusy);
676
    BookTreeStatus: (bsFree, bsBusy);
720
677
721
    FSortSettings: array [0..5] of record
678
    FSortSettings: array [0 .. 5] of TSortSetting;
722
      Column: TColumnIndex;
723
      Direction: TSortDirection;
724
    end;
725
679
726
    FStarImage: TPngImage;
680
    FStarImage: TPngImage;
727
    FEmptyStarImage: TPngImage;
681
    FEmptyStarImage: TPngImage;
728
682
729
    FLastFoundBook: PVirtualNode;
683
    FLastFoundBook: PVirtualNode;
730
    FFirstFoundBook: PvirtualNode;
684
    FFirstFoundBook: PVirtualNode;
731
    FLastBookRecord: TBookRecord;
685
    FLastBookRecord: TBookRecord;
732
686
733
    //
687
    //
734
    function GetBookNode(const Tree: TVirtualStringTree; bookID: Integer): PVirtualNode;
688
    function GetBookNode(const Tree: TVirtualStringTree; bookID: Integer): PVirtualNode;
735
689
736
    procedure FillBookIdList(const Tree: TVirtualStringTree; var BookIDList: TBookIdList);
690
    procedure FillBookIdList(const Tree: TVirtualStringTree; var BookIDList: TBookIdList);
737
    function GetActiveBookTable(tag: integer): TAbsTable;
691
    function GetActiveBookTable(tag: Integer): TAbsTable;
738
    procedure ClearLabels(Tag: integer; Full: boolean);
692
    procedure ClearLabels(tag: Integer; Full: Boolean);
739
    procedure SetAuthorsShowLocalOnly;
693
    procedure SetAuthorsShowLocalOnly;
740
    procedure SetSeriesShowLocalOnly;
694
    procedure SetSeriesShowLocalOnly;
741
    procedure SetBooksFilter;
695
    procedure SetBooksFilter;
742
    procedure FillAllBooksTree;
696
    procedure FillAllBooksTree;
743
    procedure ChangeLetterButton(S: string);
697
    procedure ChangeLetterButton(S: string);
744
    function CheckLibUpdates(Auto: boolean): Boolean;
698
    function CheckLibUpdates(Auto: Boolean): Boolean;
745
    procedure GetActiveViewComponents(var Tree: TVirtualStringTree; var Panel: TMHLInfoPanel; var Cover: TMHLCoverPanel);
699
    procedure GetActiveViewComponents(var Tree: TVirtualStringTree; var Panel: TMHLInfoPanel; var Cover: TMHLCoverPanel);
746
    procedure SetCoversVisible(State: boolean);
700
    procedure SetCoversVisible(State: Boolean);
747
    procedure RefreshBooksState(Tree: TVirtualStringTree; BookIDList: TBookIdList);
701
    procedure RefreshBooksState(Tree: TVirtualStringTree; BookIDList: TBookIdList);
748
    procedure SetColumns;
702
    procedure SetColumns;
749
    procedure SaveColumns;
703
    procedure SaveColumns;
750
    function GetTreeTag(const Sender: TBaseVirtualTree; const Column: integer): integer;
704
    function GetTreeTag(const Sender: TBaseVirtualTree; const Column: Integer): Integer;
751
    function GetText(Tag: integer; Data: PBookData): string;
705
    function GetText(tag: Integer; Data: PBookData): string;
752
    procedure SetHeaderPopUp;
706
    procedure SetHeaderPopUp;
753
    procedure RestorePositions;
707
    procedure RestorePositions;
754
    procedure DownloadBooks;
708
    procedure DownloadBooks;
755
    function CheckActiveDownloads:boolean;
709
    function CheckActiveDownloads: Boolean;
756
    procedure SetLangBarSize;
710
    procedure SetLangBarSize;
757
    procedure TheFirstRun;
711
    procedure TheFirstRun;
758
712
...
...
764
    procedure SavePositions;
718
    procedure SavePositions;
765
    procedure PrepareFb2EditData(Data: PBookData; var R: TBookRecord);
719
    procedure PrepareFb2EditData(Data: PBookData; var R: TBookRecord);
766
    procedure SaveFb2DataAfterEdit(R: TBookRecord);
720
    procedure SaveFb2DataAfterEdit(R: TBookRecord);
767
    function ShowNCWizard: boolean;
721
    function ShowNCWizard: Boolean;
768
    procedure LoadLastCollection;
722
    procedure LoadLastCollection;
769
    function ExtractBookToStream(CR: string; var Table: TAbsTable; var FS: TMemoryStream):boolean;
723
    function ExtractBookToStream(CR: string; var Table: TAbsTable; var FS: TMemoryStream): Boolean;
770
    property ActiveView: TView read GetActiveView;
724
    property ActiveView: TView read GetActiveView;
771
  end;
725
  end;
772
726
...
...
779
  IsFB2: Boolean;
733
  IsFB2: Boolean;
780
  IsNonFB2: Boolean;
734
  IsNonFB2: Boolean;
781
735
736
const
737
  CHECK_FILE = 'TheFirstRun.check';
782
738
783
const CHECK_FILE = 'TheFirstRun.check';
784
785
implementation
739
implementation
786
740
787
uses
741
uses
...
...
825
779
826
resourcestring
780
resourcestring
827
  rstrFileNotFoundMsg = 'Файл %s не найден!'#13'Проверьте настройки коллекции!';
781
  rstrFileNotFoundMsg = 'Файл %s не найден!'#13'Проверьте настройки коллекции!';
828
829
{$R *.dfm}
782
{$R *.dfm}
830
//
783
  //
831
// Helpers
784
  // Helpers
832
//
785
  //
833
786
834
const
787
const
835
  TreeIcons : array [0 .. 1] of integer = (10,11);
788
  TreeIcons: array [0 .. 1] of Integer = (10, 11);
836
  TreeHints : array [0 .. 1] of string =(
789
  TreeHints: array [0 .. 1] of string = ('Переключится в режим "Таблица"', 'Переключится в режим "Дерево"');
837
                                    'Переключится в режим "Таблица"',
838
                                    'Переключится в режим "Дерево"'
839
                                    );
840
790
841
791
function TfrmMain.CheckActiveDownloads: Boolean;
842
function TfrmMain.CheckActiveDownloads:boolean;
843
var
792
var
844
  Data : PDownloadData;
793
  Data: PDownloadData;
845
  Node : PVirtualNode;
794
  Node: PVirtualNode;
846
begin
795
begin
847
  Result := False;
796
  Result := False;
848
  Node := tvDownloadList.GetFirst;
797
  Node := tvDownloadList.GetFirst;
...
...
858
  end;
807
  end;
859
end;
808
end;
860
809
861
810
procedure TfrmMain.WMGetSysCommand(var message: TMessage);
862
procedure TfrmMain.WMGetSysCommand(var Message : TMessage) ;
863
begin
811
begin
864
  if Message.Msg = WM_Destroy then
812
  if message.Msg = WM_Destroy then
865
  begin
813
  begin
866
    ShowMessage('отключаемся');
814
    ShowMessage('отключаемся');
867
    inherited;
815
    inherited;
868
  end;
816
  end;
869
817
870
  if (Message.wParam = SC_MINIMIZE) and Settings.MinimizeToTray then
818
  if (message.wParam = SC_MINIMIZE) and Settings.MinimizeToTray then
871
  begin
819
  begin
872
    TrayIcon.Visible := True;
820
    TrayIcon.Visible := True;
873
    Hide;
821
    Hide;
874
  end
822
  end
875
  else inherited;
823
  else
824
    inherited;
876
end;
825
end;
877
826
878
procedure TfrmMain.RestorePositions;
827
procedure TfrmMain.RestorePositions;
879
var
828
var
880
  APage: integer;
829
  APage: Integer;
881
begin
830
begin
882
  APage := Settings.ActivePage;
831
  APage := Settings.ActivePage;
883
832
884
  pgControl.ActivePageIndex := PAGE_AUTHORS;
833
  pgControl.ActivePageIndex := PAGE_AUTHORS;
885
  edLocateAuthor.Text := Settings.LastAuthor;
834
  edLocateAuthor.text := Settings.LastAuthor;
886
  SelectBookById(tvBooksA,Settings.LastBookInAuthors);
835
  SelectBookById(tvBooksA, Settings.LastBookInAuthors);
887
836
888
  pgControl.ActivePageIndex := PAGE_SERIES;
837
  pgControl.ActivePageIndex := PAGE_SERIES;
889
  edLocateSeries.Text := Settings.LastSeries;
838
  edLocateSeries.text := Settings.LastSeries;
890
  SelectBookById(tvBooksS,Settings.LastBookInSeries);
839
  SelectBookById(tvBooksS, Settings.LastBookInSeries);
891
840
841
  SelectBookById(tvBooksF, Settings.LastBookInFavorites);
892
842
893
  SelectBookById(tvBooksF,Settings.LastBookInFavorites);
894
895
896
  FIgnoreChange := True;
843
  FIgnoreChange := True;
897
  edLocateAuthor.Text := '';
844
  edLocateAuthor.text := '';
898
  edLocateSeries.Text := '';
845
  edLocateSeries.text := '';
899
846
900
  FIgnoreChange := False;
847
  FIgnoreChange := False;
901
848
...
...
903
850
904
end;
851
end;
905
852
906
907
procedure TfrmMain.SetColumns;
853
procedure TfrmMain.SetColumns;
908
var
854
var
909
  Columns : TColumns;
855
  Columns: TColumns;
910
856
911
begin
857
begin
912
  Columns := TColumns.Create(Settings.SystemFileName[sfColumnsStore]);
858
  Columns := TColumns.Create(Settings.SystemFileName[sfColumnsStore]);
913
  try
859
  try
914
860
915
    if Settings.TreeModes[PAGE_AUTHORS] = tmTree then
861
    if Settings.TreeModes[PAGE_AUTHORS] = tmTree then
916
      Columns.Load(SECTION_A_TREE,tmTree)
862
      Columns.Load(SECTION_A_TREE, tmTree)
917
    else
863
    else
918
      Columns.Load(SECTION_A_FLAT,tmFlat);
864
      Columns.Load(SECTION_A_FLAT, tmFlat);
919
    Columns.SetColumns(tvBooksA.Header.Columns);
865
    Columns.SetColumns(tvBooksA.Header.Columns);
920
866
921
922
    if Settings.TreeModes[PAGE_SERIES] = tmTree then
867
    if Settings.TreeModes[PAGE_SERIES] = tmTree then
923
      Columns.Load(SECTION_S_TREE,tmTree)
868
      Columns.Load(SECTION_S_TREE, tmTree)
924
    else
869
    else
925
      Columns.Load(SECTION_S_FLAT,tmFlat);
870
      Columns.Load(SECTION_S_FLAT, tmFlat);
926
    Columns.SetColumns(tvBooksS.Header.Columns);
871
    Columns.SetColumns(tvBooksS.Header.Columns);
927
872
928
929
    if Settings.TreeModes[PAGE_GENRES] = tmTree then
873
    if Settings.TreeModes[PAGE_GENRES] = tmTree then
930
      Columns.Load(SECTION_G_TREE,tmTree)
874
      Columns.Load(SECTION_G_TREE, tmTree)
931
    else
875
    else
932
      Columns.Load(SECTION_G_FLAT,tmFlat);
876
      Columns.Load(SECTION_G_FLAT, tmFlat);
933
    Columns.SetColumns(tvBooksG.Header.Columns);
877
    Columns.SetColumns(tvBooksG.Header.Columns);
934
878
935
936
    if Settings.TreeModes[PAGE_FAVORITES] = tmTree then
879
    if Settings.TreeModes[PAGE_FAVORITES] = tmTree then
937
      Columns.Load(SECTION_F_TREE,tmTree)
880
      Columns.Load(SECTION_F_TREE, tmTree)
938
    else
881
    else
939
      Columns.Load(SECTION_F_FLAT,tmFlat);
882
      Columns.Load(SECTION_F_FLAT, tmFlat);
940
    Columns.SetColumns(tvBooksF.Header.Columns);
883
    Columns.SetColumns(tvBooksF.Header.Columns);
941
884
942
943
    if Settings.TreeModes[PAGE_SEARCH] = tmTree then
885
    if Settings.TreeModes[PAGE_SEARCH] = tmTree then
944
      Columns.Load(SECTION_SR_TREE,tmTree)
886
      Columns.Load(SECTION_SR_TREE, tmTree)
945
    else
887
    else
946
      Columns.Load(SECTION_SR_FLAT,tmFlat);
888
      Columns.Load(SECTION_SR_FLAT, tmFlat);
947
    Columns.SetColumns(tvBooksSR.Header.Columns);
889
    Columns.SetColumns(tvBooksSR.Header.Columns);
948
890
949
950
    if Settings.TreeModes[PAGE_FILTER] = tmTree then
891
    if Settings.TreeModes[PAGE_FILTER] = tmTree then
951
      Columns.Load(SECTION_FL_TREE,tmTree)
892
      Columns.Load(SECTION_FL_TREE, tmTree)
952
    else
893
    else
953
      Columns.Load(SECTION_FL_FLAT,tmFlat);
894
      Columns.Load(SECTION_FL_FLAT, tmFlat);
954
895
955
    //-------------------------------------------------------------------------
896
    // -------------------------------------------------------------------------
956
    tvBooksA.Header.MainColumn := 1;
897
    tvBooksA.Header.MainColumn := 1;
957
    tvBooksS.Header.MainColumn := 1;
898
    tvBooksS.Header.MainColumn := 1;
958
    tvBooksG.Header.MainColumn := 1;
899
    tvBooksG.Header.MainColumn := 1;
...
...
985
      Columns.Save(SECTION_S_FLAT);
926
      Columns.Save(SECTION_S_FLAT);
986
927
987
    Columns.GetColumns(tvBooksG.Header.Columns);
928
    Columns.GetColumns(tvBooksG.Header.Columns);
988
    if Settings.TreeModes[PAGE_Genres] = tmTree then
929
    if Settings.TreeModes[PAGE_GENRES] = tmTree then
989
      Columns.Save(SECTION_G_TREE)
930
      Columns.Save(SECTION_G_TREE)
990
    else
931
    else
991
      Columns.Save(SECTION_G_FLAT);
932
      Columns.Save(SECTION_G_FLAT);
...
...
1014
955
1015
procedure TfrmMain.ChangeLetterButton(S: string);
956
procedure TfrmMain.ChangeLetterButton(S: string);
1016
var
957
var
1017
  i: integer;
958
  i: Integer;
1018
begin
959
begin
1019
  for I := 0 to RusBar.ControlCount - 1 do
960
  for i := 0 to RusBar.ControlCount - 1 do
1020
    if RusBar.Controls[i] is TToolButton then
961
    if RusBar.Controls[i] is TToolButton then
1021
      if (RusBar.Controls[i] as TToolButton).Caption = S then
962
      if (RusBar.Controls[i] as TToolButton).Caption = S then
1022
      begin
963
      begin
1023
        tbtnStarClick(RusBar.Controls[i] as TToolButton);
964
        tbtnStarClick(RusBar.Controls[i] as TToolButton);
1024
        Exit;
965
        Exit;
1025
      end;
966
      end;
1026
  for I := 0 to EngBar.ControlCount - 1 do
967
  for i := 0 to EngBar.ControlCount - 1 do
1027
    if EngBar.Controls[i] is TToolButton then
968
    if EngBar.Controls[i] is TToolButton then
1028
      if (EngBar.Controls[i] as TToolButton).Caption = S then
969
      if (EngBar.Controls[i] as TToolButton).Caption = S then
1029
      begin
970
      begin
...
...
1057
    AControl.Font.Color := FontColor;
998
    AControl.Font.Color := FontColor;
1058
  end;
999
  end;
1059
1000
1060
1061
begin
1001
begin
1062
  BGColor := Settings.BGColor;
1002
  BGColor := Settings.BGColor;
1063
  TreeFontSize := Settings.TreeFontSize;
1003
  TreeFontSize := Settings.TreeFontSize;
...
...
1078
  cpCoverSR.FontSize := Settings.ShortFontSize;
1018
  cpCoverSR.FontSize := Settings.ShortFontSize;
1079
  cpCoverSR.AnnotationColor := BGColor;
1019
  cpCoverSR.AnnotationColor := BGColor;
1080
1020
1081
1082
  SetTreeViewColor(tvAuthors);
1021
  SetTreeViewColor(tvAuthors);
1083
  SetTreeViewColor(tvBooksA);
1022
  SetTreeViewColor(tvBooksA);
1084
  SetTreeViewColor(tvBooksS);
1023
  SetTreeViewColor(tvBooksS);
...
...
1110
end;
1049
end;
1111
1050
1112
procedure TfrmMain.ReadINIData;
1051
procedure TfrmMain.ReadINIData;
1113
const CHECK_FILE = 'TheFirstRun.check';
1052
const
1114
     ROOT = 'HKEY_CURRENT_USER';
1053
  CHECK_FILE = 'TheFirstRun.check';
1115
     Key  = '\Software\Microsoft\Windows\CurrentVersion\Internet Settings';
1054
  ROOT = 'HKEY_CURRENT_USER';
1055
  Key = '\Software\Microsoft\Windows\CurrentVersion\Internet Settings';
1116
var
1056
var
1117
 regini : TRzRegIniFile;
1057
  regini: TRzRegIniFile;
1118
 IETempStr, IEProxy, IEPort : String;
1058
  IETempStr, IEProxy, IEPort: string;
1119
 i, colonpos : integer;
1059
  i, colonpos: Integer;
1120
1060
1121
begin
1061
begin
1122
1062
...
...
1131
  RusBar.Visible := Settings.ShowRusBar;
1071
  RusBar.Visible := Settings.ShowRusBar;
1132
  EngBar.Visible := Settings.ShowEngBar;
1072
  EngBar.Visible := Settings.ShowEngBar;
1133
1073
1134
  tbtnShowDeleted.Down := Settings.DoNotShowDeleted ;
1074
  tbtnShowDeleted.Down := Settings.DoNotShowDeleted;
1135
  tbtnShowLocalOnly.Down := Settings.ShowLocalOnly ;
1075
  tbtnShowLocalOnly.Down := Settings.ShowLocalOnly;
1136
1076
1137
  cbDeleted.Checked := Settings.DoNotShowDeleted;
1077
  cbDeleted.Checked := Settings.DoNotShowDeleted;
1138
1078
1139
  CreateScriptMenu;
1079
  CreateScriptMenu;
1140
  if Settings.DefaultScript <> 0 then
1080
  if Settings.DefaultScript <> 0 then
1141
  begin
1081
  begin
1142
    tbSendToDevice.Tag := 900 + Settings.DefaultScript;
1082
    tbSendToDevice.tag := 900 + Settings.DefaultScript;
1143
    pmiSendToDevice.Tag := 900 + Settings.DefaultScript;
1083
    pmiSendToDevice.tag := 900 + Settings.DefaultScript;
1144
    miDevice.Tag := 900 + Settings.DefaultScript;
1084
    miDevice.tag := 900 + Settings.DefaultScript;
1145
  end
1085
  end
1146
  else
1086
  else
1147
  begin
1087
  begin
1148
    tbSendToDevice.Tag := 0;
1088
    tbSendToDevice.tag := 0;
1149
    pmiSendToDevice.Tag := 0;
1089
    pmiSendToDevice.tag := 0;
1150
    miDevice.Tag := 0;
1090
    miDevice.tag := 0;
1151
  end;
1091
  end;
1152
1092
1153
  cpCoverA.TmpFolder := Settings.TempPath;
1093
  cpCoverA.TmpFolder := Settings.TempPath;
...
...
1173
1113
1174
  cpCoverA.Width := Settings.CoverWidth;
1114
  cpCoverA.Width := Settings.CoverWidth;
1175
1115
1176
1116
  // Check IE Proxy settings   (by Goblin)
1177
   // Check IE Proxy settings   (by Goblin)
1178
  if Settings.UseIESettings then
1117
  if Settings.UseIESettings then
1179
  try
1118
    try
1180
    regini := TRzRegIniFile.Create(self);
1119
      regini := TRzRegIniFile.Create(self);
1181
    regini.PathType := ptRegistry;
1120
      regini.PathType := ptRegistry;
1182
    regini.Path := ROOT;
1121
      regini.Path := ROOT;
1183
    if regini.ReadInteger(Key, 'ProxyEnable', 0) = 1 then
1122
      if regini.ReadInteger(Key, 'ProxyEnable', 0) = 1 then
1184
    begin
1123
      begin
1185
      IETempStr := regini.ReadString(Key, 'ProxyServer', '');
1124
        IETempStr := regini.ReadString(Key, 'ProxyServer', '');
1186
      if IETempStr <> '' then
1125
        if IETempStr <> '' then
1187
        for i := 1 to Length(IETempStr) do
1126
          for i := 1 to Length(IETempStr) do
1188
          if IETempStr[i] = ':' then colonpos := i;
1127
            if IETempStr[i] = ':' then
1189
      IEProxy := ANSILeftStr(IETempStr, colonpos-1);
1128
              colonpos := i;
1190
      IEPort := ANSIRightStr(IETempStr, Length(IETempStr)-colonpos);
1129
        IEProxy := ANSILeftStr(IETempStr, colonpos - 1);
1130
        IEPort := ANSIRightStr(IETempStr, Length(IETempStr) - colonpos);
1191
1131
1192
      Settings.IEProxyServer := IEProxy;
1132
        Settings.IEProxyServer := IEProxy;
1193
      Settings.IEProxyPort := StrToInt(IEPort);
1133
        Settings.IEProxyPort := StrToInt(IEPort);
1134
      end;
1135
    except
1136
      // что-то пошло не так ...
1194
    end;
1137
    end;
1195
  except
1196
    //  что-то пошло не так ...
1197
  end;
1198
  // End check IE Proxy settings
1138
  // End check IE Proxy settings
1199
end;
1139
end;
1200
1140
1201
procedure TfrmMain.btnApplyFilterClick(Sender: TObject);
1141
procedure TfrmMain.btnApplyFilterClick(Sender: TObject);
1202
var
1142
var
1203
  FilterString: String;
1143
  FilterString: string;
1204
  SeriesFilter: String;
1144
  SeriesFilter: string;
1205
  OldFilter: String;
1145
  OldFilter: string;
1206
  Filtered: boolean;
1146
  Filtered: Boolean;
1207
  Time: TTime;
1147
  Time: TTime;
1208
const
1148
const
1209
  SQLStartStr = 'SELECT distinct b.*'  ;
1149
  SQLStartStr = 'SELECT distinct b.*';
1210
begin
1150
begin
1211
  Screen.Cursor := crSQLWAit;
1151
  Screen.Cursor := crSQLWAit;
1212
  spStatus.Caption := 'Подготовка фильтра ...'; spStatus.Repaint;
1152
  spStatus.Caption := 'Подготовка фильтра ...';
1153
  spStatus.Repaint;
1213
  tvBooksSR.Clear;
1154
  tvBooksSR.Clear;
1214
  lblTotalBooksFL.Caption := '(0)';
1155
  lblTotalBooksFL.Caption := '(0)';
1215
  FilterString := '';
1156
  FilterString := '';
1216
  ClearLabels(tvBooksSR.Tag, True);
1157
  ClearLabels(tvBooksSR.tag, True);
1217
  dmCollection.sqlBooks.SQL.Clear;
1158
  dmCollection.sqlBooks.SQL.Clear;
1218
  try
1159
  try
1219
    try
1160
    try
1220
      OldFilter := dmCollection.tblBooks.Filter;
1161
      OldFilter := dmCollection.tblBooks.Filter;
1221
      Filtered :=  dmCollection.tblBooks.Filtered;
1162
      Filtered := dmCollection.tblBooks.Filtered;
1222
1163
1223
      //------------------------ серия -----------------------------------------
1164
      // ------------------------ серия -----------------------------------------
1224
      FilterString := '';
1165
      FilterString := '';
1225
      AddToFilter('`S_Title`', PrepareQuery(edFSeries.Text, True), True, FilterString);
1166
      AddToFilter('`S_Title`', PrepareQuery(edFSeries.text, True), True, FilterString);
1226
1167
1227
      if FilterString <> '' then
1168
      if FilterString <> '' then
1228
           FilterString := SQLStartStr + #13#10 +
1169
        FilterString := SQLStartStr + #13#10 + 'FROM Series s ' + #13#10 + 'JOIN books b on b.SerID = s.S_Id ' + #13#10 + 'WHERE ' + FilterString + '';
1229
                           'FROM Series s ' + #13#10 +
1230
                           'JOIN books b on b.SerID = s.S_Id ' + #13#10 +
1231
                           'WHERE ' + FilterString + '';
1232
1170
1233
      if FilterString <> '' then
1171
      if FilterString <> '' then
1234
           dmCollection.sqlBooks.SQL.Add(FilterString);
1172
        dmCollection.sqlBooks.SQL.Add(FilterString);
1235
1173
1236
      //------------------------ аннотация -----------------------------------------
1174
      // ------------------------ аннотация -----------------------------------------
1237
      FilterString := '';
1175
      FilterString := '';
1238
      AddToFilter('`E_Annotation`', PrepareQuery(edFAnnotation.Text, True), True, FilterString);
1176
      AddToFilter('`E_Annotation`', PrepareQuery(edFAnnotation.text, True), True, FilterString);
1239
1177
1240
      if FilterString <> '' then
1178
      if FilterString <> '' then
1241
           FilterString := SQLStartStr + #13#10 +
1179
        FilterString := SQLStartStr + #13#10 + 'FROM Extra e ' + #13#10 + 'JOIN books b on b.id = e.E_BookID ' + #13#10 + 'WHERE ' + FilterString + '';
1242
                           'FROM Extra e ' + #13#10 +
1243
                           'JOIN books b on b.id = e.E_BookID ' + #13#10 +
1244
                           'WHERE ' + FilterString + '';
1245
1180
1246
      if (dmCollection.sqlBooks.SQL.Count = 0) and (FilterString <> '') then
1181
      if (dmCollection.sqlBooks.SQL.Count = 0) and (FilterString <> '') then
1247
        dmCollection.sqlBooks.SQL.Add(FilterString)
1182
        dmCollection.sqlBooks.SQL.Add(FilterString)
1248
      else
1183
      else if FilterString <> '' then
1249
        if FilterString <> '' then
1184
      begin
1250
        begin
1185
        dmCollection.sqlBooks.SQL.Add('INTERSECT');
1251
          dmCollection.sqlBooks.SQL.Add('INTERSECT');
1186
        dmCollection.sqlBooks.SQL.Add(FilterString);
1252
          dmCollection.sqlBooks.SQL.Add(FilterString);
1187
      end;
1253
        end;
1188
      // -------------------------- жанр ----------------------------------------
1254
      //-------------------------- жанр ----------------------------------------
1255
      FilterString := '';
1189
      FilterString := '';
1256
      if (edFGenre.Hint <> '') then
1190
      if (edFGenre.Hint <> '') then
1257
           FilterString := SQLStartStr + #13#10 +
1191
        FilterString := SQLStartStr + #13#10 + 'FROM Genre_List g ' + #13#10 + 'JOIN books b on b.id = g.gl_bookid ' + #13#10 + 'WHERE (' + edFGenre.Hint + ')';
1258
                           'FROM Genre_List g ' + #13#10 +
1259
                           'JOIN books b on b.id = g.gl_bookid ' + #13#10 +
1260
                           'WHERE (' + edFGenre.Hint + ')';
1261
1192
1262
1263
      if (dmCollection.sqlBooks.SQL.Count = 0) and (FilterString <> '') then
1193
      if (dmCollection.sqlBooks.SQL.Count = 0) and (FilterString <> '') then
1264
        dmCollection.sqlBooks.SQL.Add(FilterString)
1194
        dmCollection.sqlBooks.SQL.Add(FilterString)
1265
      else
1195
      else if FilterString <> '' then
1266
        if FilterString <> '' then
1196
      begin
1267
        begin
1197
        dmCollection.sqlBooks.SQL.Add('INTERSECT');
1268
          dmCollection.sqlBooks.SQL.Add('INTERSECT');
1198
        dmCollection.sqlBooks.SQL.Add(FilterString);
1269
          dmCollection.sqlBooks.SQL.Add(FilterString);
1199
      end;
1270
        end;
1271
      FilterString := '';
1200
      FilterString := '';
1272
      //-------------------  все остальное   -----------------------------------
1201
      // -------------------  все остальное   -----------------------------------
1273
      AddToFilter('`FullName`', PrepareQuery(edFFullName.Text, True), True, FilterString);
1202
      AddToFilter('`FullName`', PrepareQuery(edFFullName.text, True), True, FilterString);
1274
      AddToFilter('`Title`', PrepareQuery(edFTitle.Text, True), True, FilterString);
1203
      AddToFilter('`Title`', PrepareQuery(edFTitle.text, True), True, FilterString);
1275
      AddToFilter('`FileName`', PrepareQuery(edFFile.Text, False),False, FilterString);
1204
      AddToFilter('`FileName`', PrepareQuery(edFFile.text, False), False, FilterString);
1276
      AddToFilter('`Folder`', PrepareQuery(edFFolder.Text, False), False, FilterString);
1205
      AddToFilter('`Folder`', PrepareQuery(edFFolder.text, False), False, FilterString);
1277
      AddToFilter('`ext`', PrepareQuery(edFExt.Text, False), False, FilterString);
1206
      AddToFilter('`ext`', PrepareQuery(edFExt.text, False), False, FilterString);
1278
      AddToFilter('`Lang`', PrepareQuery(AnsiUpperCase(cbLang.Text), True, False), True, FilterString);
1207
      AddToFilter('`Lang`', PrepareQuery(AnsiUpperCase(cbLang.text), True, False), True, FilterString);
1279
      AddToFilter('`KeyWords`', PrepareQuery(edFKeyWords.Text, True), True, FilterString);
1208
      AddToFilter('`KeyWords`', PrepareQuery(edFKeyWords.text, True), True, FilterString);
1280
//
1209
      //
1281
      if cbDate.ItemIndex = -1 then
1210
      if cbDate.ItemIndex = -1 then
1282
        AddToFilter('`Date`',PrepareQuery(cbDate.Text,False),False, FilterString)
1211
        AddToFilter('`Date`', PrepareQuery(cbDate.text, False), False, FilterString)
1283
      else
1212
      else
1284
        case cbDate.ItemIndex of
1213
        case cbDate.ItemIndex of
1285
          0:AddToFilter('`Date`',Format('> "%s"',[DateToStr(IncDay(Now,- 1))]),False, FilterString);
1214
          0: AddToFilter('`Date`', Format('> "%s"', [DateToStr(IncDay(Now, -1))]), False, FilterString);
1286
          1:AddToFilter('`Date`',Format('> "%s"',[DateToStr(IncDay(Now,- 3))]),False, FilterString);
1215
          1: AddToFilter('`Date`', Format('> "%s"', [DateToStr(IncDay(Now, -3))]), False, FilterString);
1287
          2:AddToFilter('`Date`',Format('> "%s"',[DateToStr(IncDay(Now,- 7))]),False, FilterString);
1216
          2: AddToFilter('`Date`', Format('> "%s"', [DateToStr(IncDay(Now, -7))]), False, FilterString);
1288
          3:AddToFilter('`Date`',Format('> "%s"',[DateToStr(IncDay(Now,- 14))]),False, FilterString);
1217
          3: AddToFilter('`Date`', Format('> "%s"', [DateToStr(IncDay(Now, -14))]), False, FilterString);
1289
          4:AddToFilter('`Date`',Format('> "%s"',[DateToStr(IncDay(Now,- 30))]),False, FilterString);
1218
          4: AddToFilter('`Date`', Format('> "%s"', [DateToStr(IncDay(Now, -30))]), False, FilterString);
1290
          5:AddToFilter('`Date`',Format('> "%s"',[DateToStr(IncDay(Now,- 90))]),False, FilterString);
1219
          5: AddToFilter('`Date`', Format('> "%s"', [DateToStr(IncDay(Now, -90))]), False, FilterString);
1291
        end;
1220
        end;
1292
1221
1293
      case cbDownloaded.ItemIndex of
1222
      case cbDownloaded.ItemIndex of
1294
        1:if (FilterString = '') then
1223
        1:
1224
          if (FilterString = '') then
1295
            FilterString := '(`Local` = True)'
1225
            FilterString := '(`Local` = True)'
1296
          else
1226
          else
1297
            FilterString := FilterString + ' AND (`Local` = True)';
1227
            FilterString := FilterString + ' AND (`Local` = True)';
1298
        2:if (FilterString = '') then
1228
        2:
1229
          if (FilterString = '') then
1299
            FilterString := '(`Local` = False)'
1230
            FilterString := '(`Local` = False)'
1300
          else
1231
          else
1301
            FilterString := FilterString + ' AND (`Local` = False)';
1232
            FilterString := FilterString + ' AND (`Local` = False)';
...
...
1303
1234
1304
      if True then
1235
      if True then
1305
1236
1237
        if cbDeleted.Checked then
1238
          if (FilterString = '') then
1239
            FilterString := '(`Deleted` = False)'
1240
          else
1241
            FilterString := FilterString + ' AND (`Deleted`= False)';
1306
1242
1307
      if cbDeleted.Checked then
1308
        if (FilterString = '') then
1309
          FilterString := '(`Deleted` = False)'
1310
        else
1311
          FilterString := FilterString + ' AND (`Deleted`= False)';
1312
1313
      // Ставим фильтр
      spStatus.Caption := 'Применяем фильтр ...'; spStatus.Repaint;
1243
      // Ставим фильтр
      spStatus.Caption := 'Применяем фильтр ...'; spStatus.Repaint;
1244
      spStatus.Caption := 'Применяем фильтр ...';
1245
      spStatus.Repaint;
1314
1246
1315
      if (dmCollection.sqlBooks.SQL.Count > 0) and (FilterString <> '') then
1247
      if (dmCollection.sqlBooks.SQL.Count > 0) and (FilterString <> '') then
1316
        dmCollection.sqlBooks.SQL.Add('AND' + FilterString)
1248
        dmCollection.sqlBooks.SQL.Add('AND' + FilterString)
1317
      else
1249
      else if FilterString <> '' then
1318
      if FilterString <> '' then
1250
        dmCollection.sqlBooks.SQL.Add('SELECT * FROM Books WHERE ' + FilterString);
1319
           dmCollection.sqlBooks.SQL.Add('SELECT * FROM Books WHERE ' + FilterString);
1320
1251
1321
      if (dmCollection.sqlBooks.SQL.Count)=0 then
1252
      if (dmCollection.sqlBooks.SQL.Count) = 0 then
1322
            raise Exception.Create('Проверьте параметры фильтра');
1253
        raise Exception.Create('Проверьте параметры фильтра');
1323
1254
{$IFDEF DEBUG}
1324
      {$IFDEF DEBUG}
1325
      dmCollection.sqlBooks.SQL.SaveToFile(Settings.AppPath + 'Last.sql');
1255
      dmCollection.sqlBooks.SQL.SaveToFile(Settings.AppPath + 'Last.sql');
1326
      {$ENDIF}
1256
{$ENDIF}
1327
1328
      Time := Now;
1257
      Time := Now;
1329
      dmCollection.sqlBooks.Active := False;
1258
      dmCollection.sqlBooks.Active := False;
1330
      dmCollection.sqlBooks.ExecSQL;
1259
      dmCollection.sqlBooks.ExecSQL;
1331
      dmCollection.sqlBooks.Active := True;
1260
      dmCollection.sqlBooks.Active := True;
1332
      spExecTime.Caption := FloatToStrF(MilliSecondsBetween(Now, Time)/1000, FFFixed, 3, 2) + ' сек.';
1261
      spExecTime.Caption := FloatToStrF(MilliSecondsBetween(Now, Time) / 1000, FFFixed, 3, 2) + ' сек.';
1333
1262
1334
      FillBooksTree(0, tvBooksSR, nil, dmCollection.sqlBooks, True, True);
1263
      FillBooksTree(0, tvBooksSR, nil, dmCollection.sqlBooks, True, True);
1335
    except
1264
    except
...
...
1350
1278
1351
procedure TfrmMain.btnClearFilterEditsClick(Sender: TObject);
1279
procedure TfrmMain.btnClearFilterEditsClick(Sender: TObject);
1352
begin
1280
begin
1353
  edFFullName.Text  :='';
1281
  edFFullName.text := '';
1354
  edFSeries.Text    :='';
1282
  edFSeries.text := '';
1355
  edFTitle.Text     := '';
1283
  edFTitle.text := '';
1356
  edFGenre.Text     := '';
1284
  edFGenre.text := '';
1357
  edFGenre.Hint     := '';
1285
  edFGenre.Hint := '';
1358
  edFFile.Text      := '';
1286
  edFFile.text := '';
1359
  edFFolder.Text    := '';
1287
  edFFolder.text := '';
1360
  edFExt.Text       := '';
1288
  edFExt.text := '';
1361
  edFAnnotation.Text:= '';
1289
  edFAnnotation.text := '';
1362
1290
1363
  cbDate.Text       := '';
1291
  cbDate.text := '';
1364
  cbDate.ItemIndex  := -1;
1292
  cbDate.ItemIndex := -1;
1365
1293
1366
  cbPresetName.Text := '';
1294
  cbPresetName.text := '';
1367
  cbDeleted.Checked := False;
1295
  cbDeleted.Checked := False;
1368
  cbLang.Text       := '';
1296
  cbLang.text := '';
1369
  edFKeyWords.Text  := '';
1297
  edFKeyWords.text := '';
1370
  cbDownloaded.ItemIndex := 0;
1298
  cbDownloaded.ItemIndex := 0;
1371
  tvBooksSR.Clear;
1299
  tvBooksSR.Clear;
1372
  ClearLabels(PAGE_SEARCH, True);
1300
  ClearLabels(PAGE_SEARCH, True);
...
...
1374
1302
1375
procedure TfrmMain.LoadSearchPreset(FN: string);
1303
procedure TfrmMain.LoadSearchPreset(FN: string);
1376
var
1304
var
1377
  SL : TStringList;
1305
  SL: TStringList;
1378
  HL : TStringList;
1306
  HL: TStringList;
1379
begin
1307
begin
1380
  SL := TStringList.Create;
1308
  SL := TStringList.Create;
1381
  HL := TStringList.Create;
1309
  HL := TStringList.Create;
...
...
1384
    HL.QuoteChar := '~';
1312
    HL.QuoteChar := '~';
1385
1313
1386
    SL.LoadFromFile(Settings.PresetPath + FN + '.mhlf');
1314
    SL.LoadFromFile(Settings.PresetPath + FN + '.mhlf');
1387
    HL.DelimitedText := SL.Text;
1315
    HL.DelimitedText := SL.text;
1388
1316
1389
    edFFullName.Text := HL[0];
1317
    edFFullName.text := HL[0];
1390
    edFTitle.Text := HL[1];
1318
    edFTitle.text := HL[1];
1391
    edFSeries.Text := HL[2];
1319
    edFSeries.text := HL[2];
1392
    edFGenre.Text  := HL[3];
1320
    edFGenre.text := HL[3];
1393
    edFGenre.Hint  := HL[4];
1321
    edFGenre.Hint := HL[4];
1394
    edFAnnotation.Text := HL[5];
1322
    edFAnnotation.text := HL[5];
1395
    edFFile.Text := HL[6];
1323
    edFFile.text := HL[6];
1396
    edFFolder.Text := HL[7];
1324
    edFFolder.text := HL[7];
1397
    edFExt.Text := HL[8];
1325
    edFExt.text := HL[8];
1398
    cbDate.Text := HL[9];
1326
    cbDate.text := HL[9];
1399
    cbDownloaded.Text := HL[10];
1327
    cbDownloaded.text := HL[10];
1400
    cbDeleted.Checked := StrToBool(HL[11]);
1328
    cbDeleted.Checked := StrToBool(HL[11]);
1401
    cbLang.Text := HL[12];
1329
    cbLang.text := HL[12];
1402
    edFKeyWords.Text := HL[13];
1330
    edFKeyWords.text := HL[13];
1403
  finally
1331
  finally
1404
    HL.Free;
1332
    HL.Free;
1405
    SL.Free;
1333
    SL.Free;
...
...
1411
  //
1339
  //
1412
  // ВНИМАНИЕ!!! Порядок и количество элементов массива views должно совпадать с порядком и количеством закладок
  //
1340
  // ВНИМАНИЕ!!! Порядок и количество элементов массива views должно совпадать с порядком и количеством закладок
  //
1413
  views: array[0..5] of TView = (
1341
  views: array [0 .. 5] of TView = (ByAuthorView, BySeriesView, ByGenreView, SearchView, FavoritesView, DownloadView);
1414
    ByAuthorView,
1415
    BySeriesView,
1416
    ByGenreView,
1417
    SearchView,
1418
    FavoritesView,
1419
    DownloadView
1420
    );
1421
1342
1422
begin
1343
begin
1423
  Result := views[pgControl.ActivePageIndex];
1344
  Result := views[pgControl.ActivePageIndex];
1424
end;
1345
end;
1425
1346
1426
procedure TfrmMain.DisableControls(State: boolean);
1347
procedure TfrmMain.DisableControls(State: Boolean);
1427
begin
1348
begin
1428
  frmMain.Enabled := State;
1349
  frmMain.Enabled := State;
1429
end;
1350
end;
...
...
1439
  ClearLabels(PAGE_ALL, True);
1360
  ClearLabels(PAGE_ALL, True);
1440
  dmCollection.SetTableState(False);
1361
  dmCollection.SetTableState(False);
1441
  tvGenres.Clear;
1362
  tvGenres.Clear;
1442
  tvbooksG.Clear;
1363
  tvBooksG.Clear;
1443
  dmCollection.DBCollection.Connected := False;
1364
  dmCollection.DBCollection.Connected := False;
1444
1365
1445
  edLocateAuthor.Text := '';
1366
  edLocateAuthor.text := '';
1446
  edLocateSeries.Text := '';
1367
  edLocateSeries.text := '';
1447
1368
1448
  if DMUser.tblBases.IsEmpty then
1369
  if DMUser.tblBases.IsEmpty then
1449
  begin
1370
  begin
...
...
1457
    tvBooksF.Clear;
1378
    tvBooksF.Clear;
1458
    Screen.Cursor := crDefault;
1379
    Screen.Cursor := crDefault;
1459
1380
1460
    if not ShowNCWizard then Application.Terminate;
1381
    if not ShowNCWizard then
1382
      Application.Terminate;
1461
1383
1462
    DeleteFile(Settings.WorkPath + CHECK_FILE);
1384
    DeleteFile(Settings.WorkPath + CHECK_FILE);
1463
    Exit;
1385
    Exit;
...
...
1465
1387
1466
  dmCollection.DBCollection.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
1388
  dmCollection.DBCollection.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
1467
  dmCollection.DBCollection.Connected := True;
1389
  dmCollection.DBCollection.Connected := True;
1468
  frmMain.Caption := 'MyHomeLib - ' + DMUser.ActiveCollection.Name;
1390
  frmMain.Caption := 'MyHomeLib - ' + DMUser.ActiveCollection.name;
1469
1391
1470
  { TODO -oNickR -cRefactoring : проверить использование }
1392
  { TODO -oNickR -cRefactoring : проверить использование }
1471
  FCollectionRoot := IncludeTrailingPathDelimiter(DMUser.ActiveCollection.RootFolder);
1393
  FCollectionRoot := IncludeTrailingPathDelimiter(DMUser.ActiveCollection.RootFolder);
...
...
1478
  IsFB2 := isFB2Collection(CollectionType);
1400
  IsFB2 := isFB2Collection(CollectionType);
1479
  IsNonFB2 := isNonFB2Collection(CollectionType);
1401
  IsNonFB2 := isNonFB2Collection(CollectionType);
1480
1402
1481
  //----------------------------------------------------------------------------
1403
  // ----------------------------------------------------------------------------
1482
  // высталяем видимость пунктов меню в завичимости от типа коллекции
1404
  // высталяем видимость пунктов меню в завичимости от типа коллекции
1483
  //----------------------------------------------------------------------------
1405
  // ----------------------------------------------------------------------------
1484
1406
1485
  //------    Главное меню   ---------------------------------------------------
1407
  // ------    Главное меню   ---------------------------------------------------
1486
1408
1487
  // Книга
1409
  // Книга
1488
1410
...
...
1497
  miEditGenres.Visible := IsPrivate;
1419
  miEditGenres.Visible := IsPrivate;
1498
  miEditSeries.Visible := IsPrivate;
1420
  miEditSeries.Visible := IsPrivate;
1499
  miBookEdit.Visible := IsPrivate;
1421
  miBookEdit.Visible := IsPrivate;
1500
  miConverToFBD.Visible := IsPrivate  and not IsFB2;
1422
  miConverToFBD.Visible := IsPrivate and not IsFB2;
1501
  miDeleteBook.Visible := IsPrivate; // DMUser.ActiveCollection.AllowDelete;
1423
  miDeleteBook.Visible := IsPrivate; // DMUser.ActiveCollection.AllowDelete;
1502
  miDeleteFiles.Visible := isOnline and (ActiveView <> FavoritesView);
1424
  miDeleteFiles.Visible := IsOnline and (ActiveView <> FavoritesView);
1503
1425
1504
  miDownloadBooks.Visible := IsOnline;
1426
  miDownloadBooks.Visible := IsOnline;
1505
1427
...
...
1507
1429
1508
  // Инструменты
1430
  // Инструменты
1509
  miSyncOnline.Visible := IsOnline or IsNonFb2;
1431
  miSyncOnline.Visible := IsOnline or IsNonFB2;
1510
1432
1511
  //-------- Контекстное меню --------------------------------------------------
1433
  // -------- Контекстное меню --------------------------------------------------
1512
1434
1513
//  pmiBookInfo.Visible := IsFB2;
1435
  // pmiBookInfo.Visible := IsFB2;
1514
  pmiDownloadBooks.Visible := IsOnline;
1436
  pmiDownloadBooks.Visible := IsOnline;
1515
1437
1516
  //--------- Панели онструментов ----------------------------------------------
1438
  // --------- Панели онструментов ----------------------------------------------
1517
  tbtnShowLocalOnly.Visible := IsOnline;
1439
  tbtnShowLocalOnly.Visible := IsOnline;
1518
  tbtnDownloadList_Add.Visible := IsOnline;
1440
  tbtnDownloadList_Add.Visible := IsOnline;
1519
  tbtnShowDeleted.Visible := not IsPrivate;
1441
  tbtnShowDeleted.Visible := not IsPrivate;
...
...
1529
1451
1530
  edFAnnotation.Enabled := IsPrivate;
1452
  edFAnnotation.Enabled := IsPrivate;
1531
1453
1532
  //--------- Вкладки, прочее  -------------------------------------------------
1454
  // --------- Вкладки, прочее  -------------------------------------------------
1533
1455
1534
  TabSheet7.TabVisible := IsOnline;
1456
  TabSheet7.TabVisible := IsOnline;
1535
1457
1536
  //----------------------------------------------------------------------------
1458
  // ----------------------------------------------------------------------------
1537
1459
1538
  CreateCollectionMenu;
1460
  CreateCollectionMenu;
1539
  dmCollection.SetTableState(True);
1461
  dmCollection.SetTableState(True);
...
...
1549
      dmCollection.tblAuthors.Filtered := True;
1471
      dmCollection.tblAuthors.Filtered := True;
1550
      ALetter.Down := True;
1472
      ALetter.Down := True;
1551
      FLastLetterA := ALetter;
1473
      FLastLetterA := ALetter;
1552
      edLocateAuthor.Text := 'А';
1474
      edLocateAuthor.text := 'А';
1553
    end
1475
    end
1554
    else
1476
    else
1555
    begin
1477
    begin
1556
      dmCollection.tblAuthors.Filtered := False;
1478
      dmCollection.tblAuthors.Filtered := False;
1557
      tbtnStar.Down := True;
1479
      tbtnStar.Down := True;
1558
      FLastLetterA := tbtnStar;
1480
      FLastLetterA := tbtnStar;
1559
      edLocateAuthor.Text := '';
1481
      edLocateAuthor.text := '';
1560
    end;
1482
    end;
1561
1483
1562
//  SetCoversVisible((not IsNonFB2 and Settings.ShowInfoPanel)
1484
  // SetCoversVisible((not IsNonFB2 and Settings.ShowInfoPanel)
1563
//                   or (Settings.AllowMixed and Settings.ShowInfoPanel));
1485
  // or (Settings.AllowMixed and Settings.ShowInfoPanel));
1564
1486
1565
  if IsNonFB2 and not IsPrivate then SetCoversVisible(false)
1487
  if IsNonFB2 and not IsPrivate then
1566
    else SetCoversVisible(Settings.ShowInfoPanel);
1488
    SetCoversVisible(False)
1489
  else
1490
    SetCoversVisible(Settings.ShowInfoPanel);
1567
1491
1568
  SetAuthorsShowLocalOnly;
1492
  SetAuthorsShowLocalOnly;
1569
  SetSeriesShowLocalOnly;
1493
  SetSeriesShowLocalOnly;
...
...
1588
1512
1589
end;
1513
end;
1590
1514
1591
procedure TfrmMain.GetBookRecord(const ID: integer; var R: TBookRecord);
1515
procedure TfrmMain.GetBookRecord(const ID: Integer; var R: TBookRecord);
1592
begin
1516
begin
1593
  dmCollection.tblBooks.Locate('ID', ID, []);
1517
  dmCollection.tblBooks.Locate('ID', ID, []);
1594
1518
...
...
1597
1521
1598
procedure TfrmMain.CreateAlphabet;
1522
procedure TfrmMain.CreateAlphabet;
1599
const
1523
const
1600
  E : string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
1524
  E: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
1601
  R : string = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ';
1525
  R: string = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЭЮЯ';
1602
var
1526
var
1603
  i: integer;
1527
  i: Integer;
1604
  B: TToolButton;
1528
  B: TToolButton;
1605
begin
1529
begin
1606
  for I := 1 to Length(E) do
1530
  for i := 1 to Length(E) do
1607
  begin
1531
  begin
1608
    B := TToolButton.Create(EngBar);
1532
    B := TToolButton.Create(EngBar);
1609
    B.Caption := E[i];
1533
    B.Caption := E[i];
...
...
1615
    EngBar.InsertControl(B);
1539
    EngBar.InsertControl(B);
1616
  end;
1540
  end;
1617
1541
1618
  for I := 1 to Length(R) do
1542
  for i := 1 to Length(R) do
1619
  begin
1543
  begin
1620
    B := TToolButton.Create(RusBar);
1544
    B := TToolButton.Create(RusBar);
1621
    B.Caption := R[i];
1545
    B.Caption := R[i];
...
...
1633
procedure TfrmMain.CreateCollectionMenu;
1557
procedure TfrmMain.CreateCollectionMenu;
1634
var
1558
var
1635
  ItemL, ItemC, ItemP: TMenuItem;
1559
  ItemL, ItemC, ItemP: TMenuItem;
1636
  i, j, k: integer;
1560
  i, j, k: Integer;
1637
  CollectionType: COLLECTION_TYPE;
1561
  CollectionType: COLLECTION_TYPE;
1638
  Active: integer;
1562
  Active: Integer;
1639
1563
1640
  function GetCollectionTypeImageIndex: Integer;
1564
  function GetCollectionTypeImageIndex: Integer;
1641
  begin
1565
  begin
...
...
1644
      CT_PRIVATE_NONFB: Result := 8;
1568
      CT_PRIVATE_NONFB: Result := 8;
1645
      CT_LIBRUSEC_LOCAL_FB: Result := 14;
1569
      CT_LIBRUSEC_LOCAL_FB: Result := 14;
1646
      CT_LIBRUSEC_ONLINE_FB: Result := 4;
1570
      CT_LIBRUSEC_ONLINE_FB: Result := 4;
1647
      CT_GENESIS_LOCAL_NONFB: Result := 8;    { TODO -oNickR -cUsability : нарисовать иконку }
1571
      CT_GENESIS_LOCAL_NONFB: Result := 8; { TODO -oNickR -cUsability : нарисовать иконку }
1648
      CT_GENESIS_ONLINE_NONFB: Result := 8;   { TODO -oNickR -cUsability : нарисовать иконку }
1572
      CT_GENESIS_ONLINE_NONFB: Result := 8; { TODO -oNickR -cUsability : нарисовать иконку }
1649
      CT_LIBRUSEC_USR: Result := 8;
1573
      CT_LIBRUSEC_USR: Result := 8;
1650
    else
1574
    else
1651
//      Assert(False);
1575
      // Assert(False);
1652
      Result := 8;                             { TODO -oNickR -cUsability : нарисовать иконку }
1576
      Result := 8; { TODO -oNickR -cUsability : нарисовать иконку }
1653
    end;
1577
    end;
1654
  end;
1578
  end;
1655
1579
...
...
1660
  miCopyToCollection.Clear;
1584
  miCopyToCollection.Clear;
1661
  pmCollection.Items.Clear;
1585
  pmCollection.Items.Clear;
1662
  DMUser.tblBases.First;
1586
  DMUser.tblBases.First;
1663
  i := 0; j := 0; k := 0;
1587
  i := 0;
1588
  j := 0;
1589
  k := 0;
1664
  while not DMUser.tblBases.Eof do
1590
  while not DMUser.tblBases.Eof do
1665
  begin
1591
  begin
1666
    //----------------------------
1592
    // ----------------------------
1667
    ItemL := TMenuItem.Create(miCollSelect);
1593
    ItemL := TMenuItem.Create(miCollSelect);
1668
    ItemL.Caption := DMUser.ActiveCollection.Name;
1594
    ItemL.Caption := DMUser.ActiveCollection.name;
1669
    ItemL.Tag := DMUser.ActiveCollection.ID;
1595
    ItemL.tag := DMUser.ActiveCollection.ID;
1670
    ItemL.OnClick := miActiveCollectionClick;
1596
    ItemL.OnClick := miActiveCollectionClick;
1671
    ItemL.ImageIndex := GetCollectionTypeImageIndex;
1597
    ItemL.ImageIndex := GetCollectionTypeImageIndex;
1672
1598
1673
    if ItemL.Tag <> Active then
1599
    if ItemL.tag <> Active then
1674
    begin
1600
    begin
1675
      miCollSelect.Insert(i, ItemL);
1601
      miCollSelect.Insert(i, ItemL);
1676
      inc(i);
1602
      inc(i);
1677
    end;
1603
    end;
1678
1604
1679
    //----------------------------
1605
    // ----------------------------
1680
    ItemP := TMenuItem.Create(pmCollection);
1606
    ItemP := TMenuItem.Create(pmCollection);
1681
    ItemP.Caption := DMUser.ActiveCollection.Name;
1607
    ItemP.Caption := DMUser.ActiveCollection.name;
1682
    ItemP.Tag := DMUser.ActiveCollection.ID;
1608
    ItemP.tag := DMUser.ActiveCollection.ID;
1683
    ItemP.OnClick := miActiveCollectionClick;
1609
    ItemP.OnClick := miActiveCollectionClick;
1684
    ItemP.ImageIndex := GetCollectionTypeImageIndex;
1610
    ItemP.ImageIndex := GetCollectionTypeImageIndex;
1685
1611
1686
    if ItemP.Tag <> Active then
1612
    if ItemP.tag <> Active then
1687
    begin
1613
    begin
1688
      pmCollection.Items.Insert(k, ItemP);
1614
      pmCollection.Items.Insert(k, ItemP);
1689
      Inc(k);
1615
      inc(k);
1690
    end;
1616
    end;
1691
1617
1692
    //----------------------------------
1618
    // ----------------------------------
1693
    ItemC := TMenuItem.Create(miCopyToCollection);
1619
    ItemC := TMenuItem.Create(miCopyToCollection);
1694
    ItemC.Caption := DMUser.ActiveCollection.Name;
1620
    ItemC.Caption := DMUser.ActiveCollection.name;
1695
    ItemC.Tag := DMUser.ActiveCollection.ID;
1621
    ItemC.tag := DMUser.ActiveCollection.ID;
1696
    ItemC.OnClick := CopyToCollectionClick;
1622
    ItemC.OnClick := CopyToCollectionClick;
1697
    ItemC.ImageIndex := GetCollectionTypeImageIndex;
1623
    ItemC.ImageIndex := GetCollectionTypeImageIndex;
1698
1624
1699
    if (ItemC.Tag <> Active) and
1625
    if (ItemC.tag <> Active) and isPrivateCollection(DMUser.ActiveCollection.CollectionType) and (isFB2Collection(DMUser.ActiveCollection.CollectionType) and IsFB2) then
1700
      isPrivateCollection(DMUser.ActiveCollection.CollectionType) and
1701
      (isFB2Collection(DMUser.ActiveCollection.CollectionType) and IsFB2 )
1702
    then
1703
    begin
1626
    begin
1704
      miCopyToCollection.Insert(j, ItemC);
1627
      miCopyToCollection.Insert(j, ItemC);
1705
      Inc(j);
1628
      inc(j);
1706
    end;
1629
    end;
1707
1630
1708
    //----------------------------------------------------------------------
1631
    // ----------------------------------------------------------------------
1709
    DMUser.tblBases.Next;
1632
    DMUser.tblBases.Next;
1710
  end;
1633
  end;
1711
1634
...
...
1717
1640
1718
procedure TfrmMain.CreateGroupsMenu;
1641
procedure TfrmMain.CreateGroupsMenu;
1719
var
1642
var
1720
  Item, ItemP : TMenuItem;
1643
  Item, ItemP: TMenuItem;
1721
  i: integer;
1644
  i: Integer;
1722
begin
1645
begin
1723
  pmGroups.Items.Clear;
1646
  pmGroups.Items.Clear;
1724
  pmiGroups.Clear;
1647
  pmiGroups.Clear;
...
...
1731
    // меню для кнопки
1654
    // меню для кнопки
1732
    Item := TMenuItem.Create(pmGroups);
1655
    Item := TMenuItem.Create(pmGroups);
1733
    Item.Caption := DMUser.tblGroupListName.Value;
1656
    Item.Caption := DMUser.tblGroupListName.Value;
1734
    Item.Tag := DMUser.tblGroupListID.Value;
1657
    Item.tag := DMUser.tblGroupListID.Value;
1735
    Item.OnClick := GroupMenuItemClick;
1658
    Item.OnClick := GroupMenuItemClick;
1736
    pmGroups.Items.Insert(i, Item);
1659
    pmGroups.Items.Insert(i, Item);
1737
1660
1738
    // подменю для контекстного
    ItemP := TMenuItem.Create(pmMain);
1661
    // подменю для контекстного
    ItemP := TMenuItem.Create(pmMain);
1739
    ItemP.Caption := DMUser.tblGroupListName.Value;
1662
    ItemP.Caption := DMUser.tblGroupListName.Value;
1740
    ItemP.Tag := DMUser.tblGroupListID.Value;
1663
    ItemP.tag := DMUser.tblGroupListID.Value;
1741
    ItemP.OnClick := GroupMenuItemClick;
1664
    ItemP.OnClick := GroupMenuItemClick;
1742
    pmiGroups.Insert(i, ItemP);
1665
    pmiGroups.Insert(i, ItemP);
1743
    inc(i);
1666
    inc(i);
...
...
1748
1671
1749
procedure TfrmMain.CreateScriptMenu;
1672
procedure TfrmMain.CreateScriptMenu;
1750
const
1673
const
1751
    ExpTypes : array [0..5] of string = ('  fb2','  fb2.zip','  LRF','  txt', ' epub', '  pdf');
1674
  ExpTypes: array [0 .. 5] of string = ('  fb2', '  fb2.zip', '  LRF', '  txt', ' epub', '  pdf');
1752
    Icons: array [0..5] of integer = (18,19,20,21,24,25);
1675
  Icons: array [0 .. 5] of Integer = (18, 19, 20, 21, 24, 25);
1753
var
1676
var
1754
  Item, ItemP, ItemM: TMenuItem;
1677
  Item, ItemP, ItemM: TMenuItem;
1755
  F:integer;
1678
  F: Integer;
1756
  i: Integer;
1679
  i: Integer;
1757
begin
1680
begin
1758
  pmScripts.Items.Clear;
1681
  pmScripts.Items.Clear;
1759
  pmiScripts.Clear;
1682
  pmiScripts.Clear;
1760
  mmiScripts.Clear;
1683
  mmiScripts.Clear;
1761
1684
1762
1763
  if isFB2Collection(DMUser.ActiveCollection.CollectionType) then
1685
  if isFB2Collection(DMUser.ActiveCollection.CollectionType) then
1764
  begin
1686
  begin
1765
    for I := 0 to 5 do
1687
    for i := 0 to 5 do
1766
    begin
1688
    begin
1767
      Item := TMenuItem.Create(pmScripts);
1689
      Item := TMenuItem.Create(pmScripts);
1768
      Item.Caption := ExpTypes[i];
1690
      Item.Caption := ExpTypes[i];
1769
      Item.Tag := 850 + i;
1691
      Item.tag := 850 + i;
1770
      Item.OnClick := tbSendToDeviceClick;
1692
      Item.OnClick := tbSendToDeviceClick;
1771
      Item.ImageIndex := i;
1693
      Item.ImageIndex := i;
1772
      pmScripts.Items.Insert(i, Item);
1694
      pmScripts.Items.Insert(i, Item);
...
...
1776
    begin
1698
    begin
1777
      Item := TMenuItem.Create(pmScripts);
1699
      Item := TMenuItem.Create(pmScripts);
1778
      Item.Caption := '-';
1700
      Item.Caption := '-';
1779
      Item.Tag := 0;
1701
      Item.tag := 0;
1780
      pmScripts.Items.Insert(6, Item);
1702
      pmScripts.Items.Insert(6, Item);
1781
    end;
1703
    end;
1782
1704
1783
    tbSendToDevice.ImageIndex := Icons[ord(Settings.ExportMode)];
1705
    tbSendToDevice.ImageIndex := Icons[ord(Settings.ExportMode)];
1784
//    pmScripts.Items[i].Caption := '>> ' + ExpTypes[i] + ' <<';
1706
    // pmScripts.Items[i].Caption := '>> ' + ExpTypes[i] + ' <<';
1785
    F := 7;
1707
    F := 7;
1786
  end
1708
  end
1787
  else
1709
  else
...
...
1790
    tbSendToDevice.ImageIndex := 1;
1712
    tbSendToDevice.ImageIndex := 1;
1791
  end;
1713
  end;
1792
1714
1793
  { TODO 1 -oNickR -cRefactoring :заменить этот код на создание TFileRun}
1715
  { TODO 1 -oNickR -cRefactoring :заменить этот код на создание TFileRun }
1794
  for i := 0 to Settings.Scripts.Count - 1 do
1716
  for i := 0 to Settings.Scripts.Count - 1 do
1795
  begin
1717
  begin
1796
    //----  dropdown ----------------
1718
    // ----  dropdown ----------------
1797
    Item := TMenuItem.Create(pmScripts);
1719
    Item := TMenuItem.Create(pmScripts);
1798
    Item.Caption := Settings.Scripts[i].Title;
1720
    Item.Caption := Settings.Scripts[i].Title;
1799
    Item.Tag := 901 + i;
1721
    Item.tag := 901 + i;
1800
    Item.OnClick := tbSendToDeviceClick;
1722
    Item.OnClick := tbSendToDeviceClick;
1801
    Item.ImageIndex := 6;
1723
    Item.ImageIndex := 6;
1802
    pmScripts.Items.Insert(i + F, Item);
1724
    pmScripts.Items.Insert(i + F, Item);
1803
1725
1804
    //------ context -----------------
1726
    // ------ context -----------------
1805
    ItemP := TMenuItem.Create(pmMain);
1727
    ItemP := TMenuItem.Create(pmMain);
1806
    ItemP.Caption := Settings.Scripts[i].Title;
1728
    ItemP.Caption := Settings.Scripts[i].Title;
1807
    ItemP.Tag := 901 + i;
1729
    ItemP.tag := 901 + i;
1808
    ItemP.OnClick := tbSendToDeviceClick;
1730
    ItemP.OnClick := tbSendToDeviceClick;
1809
    pmiScripts.Insert(i, ItemP);
1731
    pmiScripts.Insert(i, ItemP);
1810
1732
1811
    //------ main -----------------
1733
    // ------ main -----------------
1812
    ItemM := TMenuItem.Create(MainMenu);
1734
    ItemM := TMenuItem.Create(MainMenu);
1813
    ItemM.Caption := Settings.Scripts[i].Title;
1735
    ItemM.Caption := Settings.Scripts[i].Title;
1814
    ItemM.Tag := 901 + i;
1736
    ItemM.tag := 901 + i;
1815
    ItemM.OnClick := tbSendToDeviceClick;
1737
    ItemM.OnClick := tbSendToDeviceClick;
1816
    mmiScripts.Insert(i, ItemM);
1738
    mmiScripts.Insert(i, ItemM);
1817
  end;
1739
  end;
...
...
1828
  end
1750
  end
1829
end;
1751
end;
1830
1752
1831
function TfrmMain.ShowNCWizard:boolean;
1753
function TfrmMain.ShowNCWizard: Boolean;
1832
var
1754
var
1833
  frmNCWizard: TfrmNCWizard;
1755
  frmNCWizard: TfrmNCWizard;
1834
begin
1756
begin
...
...
1858
  frmMain.WindowState := TWindowState(Settings.WindowState);
1780
  frmMain.WindowState := TWindowState(Settings.WindowState);
1859
  if frmMain.WindowState = wsNormal then
1781
  if frmMain.WindowState = wsNormal then
1860
  begin
1782
  begin
1861
    frmMain.Top    := Settings.FormTop;
1783
    frmMain.Top := Settings.FormTop;
1862
    frmMain.Left   := Settings.FormLeft;
1784
    frmMain.Left := Settings.FormLeft;
1863
    frmMain.Width  := Settings.FormWidth;
1785
    frmMain.Width := Settings.FormWidth;
1864
    frmMain.Height := Settings.FormHeight;
1786
    frmMain.Height := Settings.FormHeight;
1865
  end;
1787
  end;
1866
1788
1867
  // костыль
1789
  // костыль
1868
  frmMain.Visible := True;
1790
  frmMain.Visible := True;
1869
  if frmMain.WindowState = wsMinimized then
1791
  if frmMain.WindowState = wsMinimized then
1870
     frmMain.WindowState := wsNormal;
1792
    frmMain.WindowState := wsNormal;
1871
  // конец костыля
1793
  // конец костыля
1872
1794
1873
1874
end;
1795
end;
1875
1796
1876
procedure TfrmMain.btnSwitchTreeModeClick(Sender: TObject);
1797
procedure TfrmMain.btnSwitchTreeModeClick(Sender: TObject);
1877
var
1798
var
1878
  Page: integer;
1799
  Page: Integer;
1879
begin
1800
begin
1880
  SaveColumns;
1801
  SaveColumns;
1881
1802
...
...
1888
1809
1889
  btnSwitchTreeMode.ImageIndex := TreeIcons[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
1810
  btnSwitchTreeMode.ImageIndex := TreeIcons[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
1890
  btnSwitchTreeMode.Hint := TreeHints[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
1811
  btnSwitchTreeMode.Hint := TreeHints[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
1891
  
1812
1892
  SetColumns;
1813
  SetColumns;
1893
1814
1894
  case Page of
1815
  case Page of
1895
    0: FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA,    False, True); // авторы
1816
    1: FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
    2: FillBooksTree(0, tvBooksG, dmCollection.tblGenre_List, dmCollection.tblBooksG, True, True); // жанры
    3: FillBooksTree(0, tvBooksSR, nil, dmCollection.sqlBooks, True, True);
1896
    1: FillBooksTree(0, tvBooksS,                   nil, dmCollection.tblBooksS,    False, False); // серии
    2: FillBooksTree(0, tvBooksG,  dmCollection.tblGenre_List, dmCollection.tblBooksG,    True,  True); // жанры
    0: FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
1817
    4: FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
1897
    4: FillBooksTree(0, tvBooksF,                   nil, DMUser.tblGrouppedBooks, True,  True); // избранное
1818
    5: btnApplyFilterClick(self);
1898
    5: btnApplyFilterClick(Self);
1899
  end;
1819
  end;
1900
1820
1901
  SetHeaderPopUp;
1821
  SetHeaderPopUp;
1902
end;
1822
end;
1903
1823
1904
1824
procedure TfrmMain.ClearLabels(tag: Integer; Full: Boolean);
1905
procedure TfrmMain.ClearLabels(Tag: integer; Full: boolean);
1906
begin
1825
begin
1907
  case Tag of
1826
  case tag of
1908
    PAGE_AUTHORS:
1827
    PAGE_AUTHORS:
1909
    begin
1828
      begin
1910
      ipnlAuthors.Clear;
1829
        ipnlAuthors.Clear;
1911
      cpCoverA.Clear;
1830
        cpCoverA.Clear;
1912
      if Full then lblAuthor.Caption := '';
1831
        if Full then
1913
    end;
1832
          lblAuthor.Caption := '';
1833
      end;
1914
1834
1915
    PAGE_SERIES:
1835
    PAGE_SERIES:
1916
    begin
1836
      begin
1917
      ipnlSeries.Clear;
1837
        ipnlSeries.Clear;
1918
      cpCoverS.Clear;
1838
        cpCoverS.Clear;
1919
      lblSeries.Caption := '';
1839
        lblSeries.Caption := '';
1920
    end;
1840
      end;
1921
1841
1922
    PAGE_GENRES:
1842
    PAGE_GENRES:
1923
    begin
1843
      begin
1924
      ipnlGenres.Clear;
1844
        ipnlGenres.Clear;
1925
      cpCoverG.Clear;
1845
        cpCoverG.Clear;
1926
    end;
1846
      end;
1927
1847
1928
    PAGE_FAVORITES:
1848
    PAGE_FAVORITES:
1929
    begin
1849
      begin
1930
      ipnlFAVORITES.Clear;
1850
        ipnlFavorites.Clear;
1931
      cpCoverF.Clear;
1851
        cpCoverF.Clear;
1932
    end;
1852
      end;
1933
1853
1934
    PAGE_SEARCH:
1854
    PAGE_SEARCH:
1935
    begin
1855
      begin
1936
      ipnlSearch.Clear;
1856
        ipnlSearch.Clear;
1937
      cpCoverSR.Clear;
1857
        cpCoverSR.Clear;
1938
      lblTotalBooksFL.Caption := '()';
1858
        lblTotalBooksFL.Caption := '()';
1939
    end;
1859
      end;
1940
1860
1941
    PAGE_ALL:
1861
    PAGE_ALL:
1942
    begin
1862
      begin
1943
      ClearLabels(PAGE_AUTHORS, True);
1863
        ClearLabels(PAGE_AUTHORS, True);
1944
      ClearLabels(PAGE_SERIES, True);
1864
        ClearLabels(PAGE_SERIES, True);
1945
      ClearLabels(PAGE_GENRES, True);
1865
        ClearLabels(PAGE_GENRES, True);
1946
      ClearLabels(PAGE_FAVORITES, True);
1866
        ClearLabels(PAGE_FAVORITES, True);
1947
      ClearLabels(PAGE_FILTER, True);
1867
        ClearLabels(PAGE_FILTER, True);
1948
      ClearLabels(PAGE_SEARCH, True);
1868
        ClearLabels(PAGE_SEARCH, True);
1949
    end;
1869
      end;
1950
  end;
1870
  end;
1951
end;
1871
end;
1952
1872
1953
procedure  TfrmMain.SetAuthorsShowLocalOnly;
1873
procedure TfrmMain.SetAuthorsShowLocalOnly;
1954
begin
1874
begin
1955
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
1875
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
1956
    begin
1876
  begin
1957
      if Settings.ShowLocalOnly then
1877
    if Settings.ShowLocalOnly then
1958
        dmCollection.tblAuthors.ParamByName('All').AsInteger := 1
1878
      dmCollection.tblAuthors.ParamByName('All').AsInteger := 1
1959
      else
1879
    else
1960
        dmCollection.tblAuthors.ParamByName('All').AsInteger := 0;
1961
      dmCollection.tblAuthors.Close;
1962
      Screen.Cursor := crHourGlass;
1963
      dmCollection.tblAuthors.Open;
1964
      Screen.Cursor := crDefault;
1965
    end
1966
  else
1967
    begin
1968
      dmCollection.tblAuthors.ParamByName('All').AsInteger := 0;
1880
      dmCollection.tblAuthors.ParamByName('All').AsInteger := 0;
1969
      dmCollection.tblAuthors.Close;
1881
    dmCollection.tblAuthors.Close;
1970
      Screen.Cursor := crHourGlass;
1882
    Screen.Cursor := crHourGlass;
1971
      dmCollection.tblAuthors.Open;
1883
    dmCollection.tblAuthors.Open;
1972
      Screen.Cursor := crDefault;
1884
    Screen.Cursor := crDefault;
1973
    end;
1885
  end
1886
  else
1887
  begin
1888
    dmCollection.tblAuthors.ParamByName('All').AsInteger := 0;
1889
    dmCollection.tblAuthors.Close;
1890
    Screen.Cursor := crHourGlass;
1891
    dmCollection.tblAuthors.Open;
1892
    Screen.Cursor := crDefault;
1893
  end;
1974
end;
1894
end;
1975
1895
1976
procedure  TfrmMain.SetSeriesShowLocalOnly;
1896
procedure TfrmMain.SetSeriesShowLocalOnly;
1977
begin
1897
begin
1978
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
1898
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
1979
    begin
1899
  begin
1980
      if Settings.ShowLocalOnly then
1900
    if Settings.ShowLocalOnly then
1981
        dmCollection.tblSeries.ParamByName('All').AsInteger := 1
1901
      dmCollection.tblSeries.ParamByName('All').AsInteger := 1
1982
      else
1902
    else
1983
        dmCollection.tblSeries.ParamByName('All').AsInteger := 0;
1984
      dmCollection.tblSeries.Close;
1985
      Screen.Cursor := crHourGlass;
1986
      dmCollection.tblSeries.Open;
1987
      Screen.Cursor := crDefault;
1988
    end
1989
  else
1990
    begin
1991
      dmCollection.tblSeries.ParamByName('All').AsInteger := 0;
1903
      dmCollection.tblSeries.ParamByName('All').AsInteger := 0;
1992
      dmCollection.tblSeries.Close;
1904
    dmCollection.tblSeries.Close;
1993
      Screen.Cursor := crHourGlass;
1905
    Screen.Cursor := crHourGlass;
1994
      dmCollection.tblSeries.Open;
1906
    dmCollection.tblSeries.Open;
1995
      Screen.Cursor := crDefault;
1907
    Screen.Cursor := crDefault;
1996
    end;
1908
  end
1909
  else
1910
  begin
1911
    dmCollection.tblSeries.ParamByName('All').AsInteger := 0;
1912
    dmCollection.tblSeries.Close;
1913
    Screen.Cursor := crHourGlass;
1914
    dmCollection.tblSeries.Open;
1915
    Screen.Cursor := crDefault;
1916
  end;
1997
end;
1917
end;
1998
1918
1999
procedure  TfrmMain.SetBooksFilter;
1919
procedure TfrmMain.SetBooksFilter;
2000
const
1920
const
2001
   flLocal = '`Local` = True';
1921
  flLocal = '`Local` = True';
2002
   flNotShowDeleted = '`Deleted` <> True';
1922
  flNotShowDeleted = '`Deleted` <> True';
2003
1923
1924
  procedure SwitchFilter(Filter: string);
1925
  var
1926
    State: Boolean;
1927
  begin
1928
    State := (Filter <> '');
2004
1929
2005
      procedure SwitchFilter(Filter: string);
1930
    dmCollection.tblBooksA.Filter := Filter;
2006
      var
1931
    dmCollection.tblBooksG.Filter := Filter;
2007
        State : boolean;
1932
    dmCollection.tblBooksS.Filter := Filter;
2008
      begin
1933
    DMUser.tblGrouppedBooks.Filter := Filter;
2009
        State := (Filter <> '');
2010
1934
2011
        dmCollection.tblBooksA.Filter := Filter;
1935
    dmCollection.tblBooksA.Filtered := State;
2012
        dmCollection.tblBooksG.Filter := Filter;
1936
    dmCollection.tblBooksG.Filtered := State;
2013
        dmCollection.tblBooksS.Filter := Filter;
1937
    dmCollection.tblBooksS.Filtered := State;
2014
        DMUser.tblGrouppedBooks.Filter := Filter;
1938
    DMUser.tblGrouppedBooks.Filtered := State;
1939
  end;
2015
1940
2016
        dmCollection.tblBooksA.Filtered := State;
2017
        dmCollection.tblBooksG.Filtered := State;
2018
        dmCollection.tblBooksS.Filtered := State;
2019
        DMUser.tblGrouppedBooks.Filtered := State;
2020
      end;
2021
2022
begin
1941
begin
2023
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
1942
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
2024
  begin
1943
  begin
...
...
2031
    else if not Settings.DoNotShowDeleted and Settings.ShowLocalOnly then
1951
    else if not Settings.DoNotShowDeleted and Settings.ShowLocalOnly then
2032
      SwitchFilter(flLocal)
1952
      SwitchFilter(flLocal)
2033
    else if not Settings.DoNotShowDeleted and not Settings.ShowLocalOnly then
1953
    else if not Settings.DoNotShowDeleted and not Settings.ShowLocalOnly then
2034
      SwitchFilter('') ;
1954
      SwitchFilter('');
2035
  end
1955
  end
1956
  else if Settings.DoNotShowDeleted then
1957
    SwitchFilter(flNotShowDeleted)
2036
  else
1958
  else
2037
    if Settings.DoNotShowDeleted then
1959
    SwitchFilter('');
2038
      SwitchFilter(flNotShowDeleted)
2039
    else
2040
      SwitchFilter('');
2041
end;
1960
end;
2042
1961
2043
procedure TfrmMain.FilesListFile(Sender: TObject; const F: TSearchRec);
1962
procedure TfrmMain.FilesListFile(Sender: TObject; const F: TSearchRec);
2044
var
1963
var
2045
  S: string;
1964
  S: string;
2046
begin
1965
begin
2047
  if ExtractFileExt(F.Name) = '.mhlf' then
1966
  if ExtractFileExt(F.name) = '.mhlf' then
2048
  begin
1967
  begin
2049
    S := ExtractFileName(F.Name);
1968
    S := ExtractFileName(F.name);
2050
    Delete(S, Length(S) - 4 , 5);
1969
    Delete(S, Length(S) - 4, 5);
2051
    cbPresetName.Items.Add(S);
1970
    cbPresetName.Items.Add(S);
2052
  end;
1971
  end;
2053
end;
1972
end;
2054
1973
2055
procedure  TfrmMain.FillAllBooksTree;
1974
procedure TfrmMain.FillAllBooksTree;
2056
begin
1975
begin
2057
  FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA,    False, True); // авторы
1976
  FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
2058
  FillBooksTree(0, tvBooksS,                   nil, dmCollection.tblBooksS,    False, False); // серии
  FillBooksTree(0, tvBooksG,  dmCollection.tblGenre_List, dmCollection.tblBooksG,    True,  True); // жанры
  FillBooksTree(0, tvBooksF,                   nil, DMUser.tblGrouppedBooks, True,  True); // избранное
1977
  FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
  FillBooksTree(0, tvBooksG, dmCollection.tblGenre_List, dmCollection.tblBooksG, True, True); // жанры
  FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
2059
1978
2060
//  if DMCollection.sqlBooks.Active then
1979
  // if DMCollection.sqlBooks.Active then
2061
//    FillBooksTree(0, tvBooksSR, nil, dmCollection.sqlBooks, True, True);
1980
  // FillBooksTree(0, tvBooksSR, nil, dmCollection.sqlBooks, True, True);
2062
1981
2063
end;
1982
end;
2064
1983
2065
function TfrmMain.CheckLibUpdates(Auto: boolean): Boolean;
1984
function TfrmMain.CheckLibUpdates(Auto: Boolean): Boolean;
2066
var
1985
var
2067
  Active: Integer;
1986
  Active: Integer;
2068
  i: integer;
1987
  i: Integer;
2069
begin
1988
begin
2070
1989
2071
  if not Auto then ShowPopup('Проверка обновлений ...');
1990
  if not Auto then
1991
    ShowPopup('Проверка обновлений ...');
2072
1992
2073
  Result := False;
1993
  Result := False;
2074
1994
...
...
2080
2000
2081
  DMUser.FindFirstCollection;
2001
  DMUser.FindFirstCollection;
2082
  repeat
2002
  repeat
2083
    for I := 0 to Settings.Updates.Count - 1 do
2003
    for i := 0 to Settings.Updates.Count - 1 do
2084
      if Settings.Updates.Items[i].CheckCodes(DMUser.ActiveCollection.Name,
2004
      if Settings.Updates.Items[i].CheckCodes(DMUser.ActiveCollection.name, DMUser.ActiveCollection.CollectionType, DMUser.ActiveCollection.ID) then
2085
                                              DMUser.ActiveCollection.CollectionType,
2086
                                              DMUser.ActiveCollection.ID)
2087
      then
2088
        if Settings.Updates.Items[i].CheckVersion(Settings.UpdatePath, DMUser.ActiveCollection.Version) then
2005
        if Settings.Updates.Items[i].CheckVersion(Settings.UpdatePath, DMUser.ActiveCollection.Version) then
2089
        begin
2006
        begin
2090
          Result := True;
2007
          Result := True;
...
...
2096
  if not Auto then
2013
  if not Auto then
2097
  begin
2014
  begin
2098
    HidePopup;
2015
    HidePopup;
2099
    if not Result then ShowMessage('Нет доступных обновлений');
2016
    if not Result then
2017
      ShowMessage('Нет доступных обновлений');
2100
  end;
2018
  end;
2101
end;
2019
end;
2102
2020
2103
procedure TfrmMain.SetLangBarSize;
2021
procedure TfrmMain.SetLangBarSize;
2104
begin
2022
begin
2105
    // исправляем косяк с алфавитными панелями
  rpLang.Visible := rusBar.Visible or engBar.Visible;
2023
  // исправляем косяк с алфавитными панелями
  rpLang.Visible := RusBar.Visible or EngBar.Visible;
2106
  if (rusBar.Visible and not engBar.Visible) or
2024
  if (RusBar.Visible and not EngBar.Visible) or (not RusBar.Visible and EngBar.Visible) then
2107
     (not rusBar.Visible and engBar.Visible)
2025
    rpLang.Height := RusBar.Height + 5
2108
  then
2109
    rpLang.Height := rusBar.Height + 5
2110
  else
2026
  else
2111
    rpLang.Height := 2 * rusBar.Height + 10;
2027
    rpLang.Height := 2 * RusBar.Height + 10;
2112
end;
2028
end;
2113
2029
2114
procedure TfrmMain.TheFirstRun;
2030
procedure TfrmMain.TheFirstRun;
2115
begin
2031
begin
2116
  if  DMUser.tblBases.IsEmpty then
2032
  if DMUser.tblBases.IsEmpty then
2117
    DeleteFile(Settings.WorkPath + CHECK_FILE)
2033
    DeleteFile(Settings.WorkPath + CHECK_FILE)
2118
  else
2034
  else if FileExists(Settings.WorkPath + CHECK_FILE) and (Application.MessageBox('Вы успешно обновили программу. Для нормальной работы необходимо' + #13 + 'обновить струткуру таблиц БД. Сделать это прямо сейчас?', 'MyHomeLib - первый запуск', mb_YesNo) = mrYes) then
2119
  if FileExists(Settings.WorkPath + CHECK_FILE) and
2120
     (Application.MessageBox('Вы успешно обновили программу. Для нормальной работы необходимо' + #13 +
2121
                'обновить струткуру таблиц БД. Сделать это прямо сейчас?',
2122
                'MyHomeLib - первый запуск',mb_YesNo) = mrYes) then
2123
  begin
2035
  begin
2124
    RenameFile(Settings.SystemFileName[sfLibRusEcinpx],Settings.SystemFileName[sfLibRusEcUpdate]);
2036
    RenameFile(Settings.SystemFileName[sfLibRusEcinpx], Settings.SystemFileName[sfLibRusEcUpdate]);
2125
    DeleteFile(Settings.WorkPath + CHECK_FILE);
2037
    DeleteFile(Settings.WorkPath + CHECK_FILE);
2126
    if unit_utils.LibrusecUpdate then
2038
    if unit_Utils.LibrusecUpdate then
2127
      InitCollection(True);
2039
      InitCollection(True);
2128
  end;
2040
  end;
2129
end;
2041
end;
...
...
2154
begin
2066
begin
2155
  CanClose := True;
2067
  CanClose := True;
2156
  if CheckActiveDownloads then
2068
  if CheckActiveDownloads then
2157
    if MessageDlg('В списке есть незавершенные закачки!' + #13 +
2069
    if MessageDlg('В списке есть незавершенные закачки!' + #13 + 'Вы все еще хотите выйти из программы?', mtWarning, mbYesNo, 0) = mrYes then
2158
                  'Вы все еще хотите выйти из программы?', mtWarning, mbYesNo, 0) = mrYes then
2070
    begin
2159
      begin
2071
      if Assigned(FDMThread) then
2160
        if Assigned(FDMThread) then FDMThread.TerminateNow;
2072
        FDMThread.TerminateNow;
2161
      end
2073
    end
2162
    else
2074
    else
2163
      CanClose := False;
2075
      CanClose := False;
2164
end;
2076
end;
2165
2077
2166
procedure TfrmMain.StartLibUpdate;
2078
procedure TfrmMain.StartLibUpdate;
2167
begin
2079
begin
2168
  if unit_utils.LibrusecUpdate then
2080
  if unit_Utils.LibrusecUpdate then
2169
    InitCollection(True);
2081
    InitCollection(True);
2170
end;
2082
end;
2171
2083
...
...
2176
    DMUser.ActivateCollection(Settings.ActiveCollection);
2088
    DMUser.ActivateCollection(Settings.ActiveCollection);
2177
    if not FileExists(DMUser.ActiveCollection.DBFileName) then
2089
    if not FileExists(DMUser.ActiveCollection.DBFileName) then
2178
    begin
2090
    begin
2179
      MessageDlg('Файл коллекции "' + DMUser.ActiveCollection.DBFileName + '" не найден.' + #13 +
2091
      MessageDlg('Файл коллекции "' + DMUser.ActiveCollection.DBFileName + '" не найден.' + #13 + 'Невозможно запустить программу.', mtError, [mbOk], 0);
2180
                 'Невозможно запустить программу.', mtError, [mbOK], 0);
2181
      Application.Terminate;
2092
      Application.Terminate;
2182
    end;
2093
    end;
2183
    frmSplash.lblState.Caption := main_loading_collection;
2094
    frmSplash.lblState.Caption := main_loading_collection;
...
...
2200
2111
2201
  tvDownloadList.NodeDataSize := SizeOf(TDownloadData);
2112
  tvDownloadList.NodeDataSize := SizeOf(TDownloadData);
2202
2113
2203
//-----------------------------
2114
  // -----------------------------
2204
2115
2205
  FSelectionState := False;
2116
  FSelectionState := False;
2206
  FAutoCheck := False;
2117
  FAutoCheck := False;
2207
  FFormBusy := False;
2118
  FFormBusy := False;
2208
2119
2209
  FFileOpMode := fmFb2Zip;
2120
  FFileOpMode := fmFb2Zip;
2210
  
2121
2211
  FLastLetterA := tbtnStar;
2122
  FLastLetterA := tbtnStar;
2212
  FLastLetterS := tbtnStar;
2123
  FLastLetterS := tbtnStar;
2213
2124
...
...
2221
  SetColumns;
2132
  SetColumns;
2222
  SetHeaderPopUp;
2133
  SetHeaderPopUp;
2223
2134
2224
  //------------------------ чистка папки дата если нужно ----------------------
2135
  // ------------------------ чистка папки дата если нужно ----------------------
2225
  if (ParamCount > 0) and (ParamStr(1) = '/clear') then
2136
  if (ParamCount > 0) and (ParamStr(1) = '/clear') then
2226
    ClearDir(Settings.DataDir);
2137
    ClearDir(Settings.DataDir);
2227
2138
...
...
2231
  if not FileExists(DMUser.DBUser.DatabaseFileName) then
2142
  if not FileExists(DMUser.DBUser.DatabaseFileName) then
2232
    TMHLLibrary.CreateSystemTables(DMUser.DBUser.DatabaseFileName);
2143
    TMHLLibrary.CreateSystemTables(DMUser.DBUser.DatabaseFileName);
2233
2144
2234
2235
  DMUser.DBUser.Connected := True;
2145
  DMUser.DBUser.Connected := True;
2236
  DMUser.SetUserTableState(True);
2146
  DMUser.SetUserTableState(True);
2237
2147
2238
 //------------------------------------------------------------------------------
2148
  // ------------------------------------------------------------------------------
2239
 //  Проверка обновлений
 //------------------------------------------------------------------------------
2149
  // Проверка обновлений
  // ------------------------------------------------------------------------------
2240
2150
2241
  frmSplash.lblState.Caption := main_check_updates;
2151
  frmSplash.lblState.Caption := main_check_updates;
2242
  if Settings.CheckUpdate then
2152
  if Settings.CheckUpdate then
...
...
2251
  if Settings.CheckExternalLibUpdate then
2161
  if Settings.CheckExternalLibUpdate then
2252
    if CheckLibUpdates(True) then
2162
    if CheckLibUpdates(True) then
2253
      if Settings.AutoRunUpdate then
2163
      if Settings.AutoRunUpdate then
2254
          StartLibUpdate
2164
        StartLibUpdate
2255
      else
2165
      else if MessageDlg('Доступно обновление для коллекций "lib.rus.ec".' + #13 + ' Начать обновление ?', mtWarning, [mbYes, mbNo], 0) = mrYes then
2256
        if MessageDlg('Доступно обновление для коллекций "lib.rus.ec".' + #13 + ' Начать обновление ?', mtWarning, [mbYes, mbNo], 0) = mrYes then
2166
        StartLibUpdate;
2257
           StartLibUpdate;
2258
2167
2259
//------------------------------------------------------------------------------
2168
  // ------------------------------------------------------------------------------
2260
2169
2261
  FillGroupsList;
2170
  FillGroupsList;
2262
  CreateGroupsMenu;
2171
  CreateGroupsMenu;
...
...
2265
  dmCollection.SetActiveTable(pgControl.ActivePageIndex);
2174
  dmCollection.SetActiveTable(pgControl.ActivePageIndex);
2266
  TheFirstRun;
2175
  TheFirstRun;
2267
2176
2268
//------------------------------------------------------------------------------
2177
  // ------------------------------------------------------------------------------
2269
2178
2270
  SetLangBarSize;
2179
  SetLangBarSize;
2271
  frmSplash.lblState.Caption := 'Старт ...';
2180
  frmSplash.lblState.Caption := 'Старт ...';
...
...
2287
  // загрузка списка закачек
  if FileExists(Settings.SystemFileName[sfDownloadsStore]) then
2196
  // загрузка списка закачек
  if FileExists(Settings.SystemFileName[sfDownloadsStore]) then
2288
  begin
2197
  begin
2289
    tvDownloadList.LoadFromfile(Settings.SystemFileName[sfDownloadsStore]);
2198
    tvDownloadList.LoadFromFile(Settings.SystemFileName[sfDownloadsStore]);
2290
    lblDownloadCount.Caption := Format('(%d)',[tvDownloadList.ChildCount[Nil]]);
2199
    lblDownloadCount.Caption := Format('(%d)', [tvDownloadList.ChildCount[nil]]);
2291
  end;
2200
  end;
2292
2201
2293
  if Settings.AutoStartDwnld then
2202
  if Settings.AutoStartDwnld then
...
...
2323
2232
2324
  Settings.CoverWidth := cpCoverA.Width;
2233
  Settings.CoverWidth := cpCoverA.Width;
2325
2234
2326
  Settings.WindowState := Ord(Self.WindowState);
2235
  Settings.WindowState := ord(self.WindowState);
2327
  if WindowState = wsNormal then
2236
  if WindowState = wsNormal then
2328
  begin
2237
  begin
2329
    Settings.FormWidth := Width;
2238
    Settings.FormWidth := Width;
...
...
2339
  FreeAndNil(FStarImage);
2248
  FreeAndNil(FStarImage);
2340
  FreeAndNil(FEmptyStarImage);
2249
  FreeAndNil(FEmptyStarImage);
2341
2250
2342
2343
  tvDownloadList.SaveToFile(Settings.SystemFileName[sfDownloadsStore]);
2251
  tvDownloadList.SaveToFile(Settings.SystemFileName[sfDownloadsStore]);
2344
2252
2345
  if DirectoryExists(Settings.TempDir) then ClearDir(Settings.TempDir);
2253
  if DirectoryExists(Settings.TempDir) then
2254
    ClearDir(Settings.TempDir);
2346
2255
2347
  SaveMainFormSettings;
2256
  SaveMainFormSettings;
2348
2257
2349
2350
  Settings.SaveSettings;
2258
  Settings.SaveSettings;
2351
  FreeSettings;
2259
  FreeSettings;
2352
2260
...
...
2360
//
2268
//
2361
// Список книг
2269
// Список книг
2362
//
2270
//
2363
function TfrmMain.GetText(Tag: integer; Data: PBookData):string;
2271
function TfrmMain.GetText(tag: Integer; Data: PBookData): string;
2364
begin
2272
begin
2365
    case Tag  of
2273
  case tag of
2366
      COL_AUTHOR : Result := Data.FullName;
2274
    COL_AUTHOR:
2367
      COL_TITLE  : Result := Data.Title;
2275
      Result := Data.FullName;
2368
      COL_SERIES : Result := Data.Series;
2276
    COL_TITLE:
2369
      COL_NO     : if Data.No <> 0 then
2277
      Result := Data.Title;
2370
                      Result := IntToStr(Data.No);
2278
    COL_SERIES:
2371
      COL_SIZE   : Result := IntToStr(Data.Size);
2279
      Result := Data.Series;
2372
      COL_DATE   : Result := DateToStr(Data.Date);
2280
    COL_NO:
2373
      COL_GENRE  : Result := Data.Genre;
2281
      if Data.No <> 0 then
2374
      COL_TYPE   : Result := Data.FileType;
2282
        Result := IntToStr(Data.No);
2375
      COL_LANG   : Result := Data.Lang;
2283
    COL_SIZE:
2376
//      COL_LIBRATE   : Result := IntToStr(Data.LibRate);
2284
      Result := GetFormattedSize(Data.Size);
2377
      COL_COLLECTION: Result := Data.ColName;
2285
    COL_DATE:
2378
    end;
2286
      Result := DateToStr(Data.Date);
2287
    COL_GENRE:
2288
      Result := Data.Genre;
2289
    COL_TYPE:
2290
      Result := Data.FileType;
2291
    COL_LANG:
2292
      Result := Data.Lang;
2293
    // COL_LIBRATE   : Result := IntToStr(Data.LibRate);
2294
    COL_COLLECTION:
2295
      Result := Data.ColName;
2296
  end;
2379
end;
2297
end;
2380
2298
2381
procedure TfrmMain.tvAuthorsGetText(Sender: TBaseVirtualTree;
2299
procedure TfrmMain.tvAuthorsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2382
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
2383
  var CellText: String);
2384
var
2300
var
2385
  Data: PAuthorData;
2301
  Data: PAuthorData;
2386
begin
2302
begin
2387
  Data := Sender.GetNodeData(Node);
2303
  Data := Sender.GetNodeData(Node);
2388
  Assert(Assigned(Data));
2304
  Assert(Assigned(Data));
2389
2305
2390
  CellText := Data.Text;
2306
  CellText := Data.text;
2391
end;
2307
end;
2392
2308
2393
procedure TfrmMain.tvAuthorsKeyDown(Sender: TObject; var Key: Word;
2309
procedure TfrmMain.tvAuthorsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
2394
  Shift: TShiftState);
2395
begin
2310
begin
2396
  if Key = VK_RETURN then
2311
  if Key = VK_RETURN then
2397
  begin
2312
  begin
...
...
2400
  end;
2315
  end;
2401
end;
2316
end;
2402
2317
2403
procedure TfrmMain.tvBooksAGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2318
procedure TfrmMain.tvBooksAGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2404
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
2405
var
2319
var
2406
  Data: PBookData;
2320
  Data: PBookData;
2407
begin
2321
begin
...
...
2413
  if Settings.TreeModes[PAGE_AUTHORS] = tmTree then
2327
  if Settings.TreeModes[PAGE_AUTHORS] = tmTree then
2414
  begin
2328
  begin
2415
    if Node.ChildCount > 0 then
2329
    if Node.ChildCount > 0 then
2416
      case GetTreeTag(Sender, Column)  of
2330
      case GetTreeTag(Sender, Column) of
2417
        COL_TITLE: CellText := Data.Series;
2331
        COL_TITLE:
2332
          CellText := Data.Series;
2418
      end
2333
      end
2419
    else
2334
    else
2420
      CellText := GetText(GetTreeTag(Sender, Column), Data);
2335
      CellText := GetText(GetTreeTag(Sender, Column), Data);
...
...
2423
    CellText := GetText(GetTreeTag(Sender, Column), Data);
2338
    CellText := GetText(GetTreeTag(Sender, Column), Data);
2424
end;
2339
end;
2425
2340
2426
procedure TfrmMain.tvBooksTreeInitNode(Sender: TBaseVirtualTree; ParentNode,
2341
procedure TfrmMain.tvBooksTreeInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
2427
  Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
2428
begin
2342
begin
2429
  Node.CheckType := ctTriStateCheckBox;
2343
  Node.CheckType := ctTriStateCheckBox;
2430
  Sender.CheckState[Node] := csUncheckedNormal;
2344
  Sender.CheckState[Node] := csUncheckedNormal;
2431
end;
2345
end;
2432
2346
2433
procedure TfrmMain.tvBooksTreeHeaderClick(Sender: TVTHeader;
2347
procedure TfrmMain.tvBooksTreeHeaderClick(Sender: TVTHeader; HitInfo: TVTHeaderHitInfo);
2434
  HitInfo: TVTHeaderHitInfo);
2435
var
2348
var
2436
  Tree:TVirtualStringTree;
2349
  Tree: TVirtualStringTree;
2437
begin
2350
begin
2438
  if (HitInfo.Button = mbLeft) then
2351
  if (HitInfo.Button = mbLeft) then
2439
  begin
2352
  begin
2440
    GetActiveTree(Tree);
2353
    GetActiveTree(Tree);
2441
    if (Settings.TreeModes[Tree.Tag] = tmTree) or (HitInfo.Column < 0) then Exit;
2354
    if (Settings.TreeModes[Tree.tag] = tmTree) or (HitInfo.Column < 0) then
2355
      Exit;
2442
    // Меняем индекс сортирующей колонки на индекс колонки,
2356
    // Меняем индекс сортирующей колонки на индекс колонки,
2443
    // которая была нажата.
2357
    // которая была нажата.
2444
    Tree.Header.SortColumn := HitInfo.Column;
2358
    Tree.Header.SortColumn := HitInfo.Column;
...
...
2449
      Tree.Header.SortDirection := sdDescending;
2363
      Tree.Header.SortDirection := sdDescending;
2450
      Tree.SortTree(HitInfo.Column, Tree.Header.SortDirection);
2364
      Tree.SortTree(HitInfo.Column, Tree.Header.SortDirection);
2451
    end
2365
    end
2452
    else begin
2366
    else
2367
    begin
2453
      Tree.Header.SortDirection := sdAscending;
2368
      Tree.Header.SortDirection := sdAscending;
2454
      Tree.SortTree(HitInfo.Column, Tree.Header.SortDirection);
2369
      Tree.SortTree(HitInfo.Column, Tree.Header.SortDirection);
2455
    end;
2370
    end;
2456
2371
2457
    // запоминаем параметры для активного дерева
2372
    // запоминаем параметры для активного дерева
2458
    FSortSettings[Tree.Tag].Column := HitInfo.Column;
2373
    FSortSettings[Tree.tag].Column := HitInfo.Column;
2459
    FSortSettings[Tree.Tag].Direction := Tree.Header.SortDirection;
2374
    FSortSettings[Tree.tag].Direction := Tree.Header.SortDirection;
2460
  end;
2375
  end;
2461
end;
2376
end;
2462
2377
2463
procedure TfrmMain.tvBooksGGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2378
procedure TfrmMain.tvBooksGGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2464
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
2465
var
2379
var
2466
  Data: PBookData;
2380
  Data: PBookData;
2467
  Tag: integer;
2381
  tag: Integer;
2468
begin
2382
begin
2469
  Data := Sender.GetNodeData(Node);
2383
  Data := Sender.GetNodeData(Node);
2470
  CellText := ' ';
2384
  CellText := ' ';
2471
  Tag := GetTreeTag(Sender, Column);
2385
  tag := GetTreeTag(Sender, Column);
2472
  if Settings.TreeModes[PAGE_GENRES] = tmTree then
2386
  if Settings.TreeModes[PAGE_GENRES] = tmTree then
2473
  case Data.nodeType of
2387
    case Data.nodeType of
2474
    ntAuthorInfo: if Tag = COL_TITLE then
2388
      ntAuthorInfo:
2475
                     CellText := Data.FullName;
2389
        if tag = COL_TITLE then
2476
    ntSeriesInfo: if Tag = COL_TITLE then
2390
          CellText := Data.FullName;
2477
                     CellText := 'Серия: ' + Data.Series;
2391
      ntSeriesInfo:
2478
    ntBookInfo:
2392
        if tag = COL_TITLE then
2479
      case Tag of
2393
          CellText := 'Серия: ' + Data.Series;
2480
        COL_TITLE : CellText := Data.Title;
2394
      ntBookInfo:
2481
        COL_NO    : if Data.No <> 0 then
2395
        case tag of
2482
                        CellText := IntToStr(Data.No);
2396
          COL_TITLE:
2483
        COL_SIZE  : CellText := IntToStr(Data.Size);
2397
            CellText := Data.Title;
2484
        COL_GENRE : CellText := Data.Genre;
2398
          COL_NO:
2485
      end;
2399
            if Data.No <> 0 then
2486
  end
2400
              CellText := IntToStr(Data.No);
2401
          COL_SIZE:
2402
            CellText := GetFormattedSize(Data.Size);
2403
          COL_GENRE:
2404
            CellText := Data.Genre;
2405
        end;
2406
    end
2487
  else
2407
  else
2488
    CellText := GetText(GetTreeTag(Sender, Column), Data);
2408
    CellText := GetText(GetTreeTag(Sender, Column), Data);
2489
end;
2409
end;
2490
2410
2491
procedure TfrmMain.tvBooksSGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2411
procedure TfrmMain.tvBooksSGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2492
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
2493
var
2412
var
2494
  Data: PBookData;
2413
  Data: PBookData;
2495
begin
2414
begin
...
...
2500
  CellText := GetText(GetTreeTag(Sender, Column), Data);
2419
  CellText := GetText(GetTreeTag(Sender, Column), Data);
2501
end;
2420
end;
2502
2421
2503
procedure TfrmMain.tvBooksFGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2422
procedure TfrmMain.tvBooksFGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2504
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
2505
var
2423
var
2506
  Data: PBookData;
2424
  Data: PBookData;
2507
  Page: integer;
2425
  Page: Integer;
2508
2426
2509
begin
2427
begin
2510
  Page := Sender.Tag;
2428
  Page := Sender.tag;
2511
  Data := Sender.GetNodeData(Node);
2429
  Data := Sender.GetNodeData(Node);
2512
  Assert(Assigned(Data));
2430
  Assert(Assigned(Data));
2513
2431
2514
  CellText := ' ';
2432
  CellText := ' ';
2515
  if Settings.TreeModes[Page] = tmTree then
2433
  if Settings.TreeModes[Page] = tmTree then
2516
  case Data.nodeType of
2434
    case Data.nodeType of
2517
    ntAuthorInfo:
2435
      ntAuthorInfo:
2518
      begin
2436
        begin
2519
        case GetTreeTag(Sender, Column)  of
2437
          case GetTreeTag(Sender, Column) of
2520
          COL_TITLE : CellText := Data.FullName;
2438
            COL_TITLE:
2521
          COL_COLLECTION : CellText := Data.ColName;
2439
              CellText := Data.FullName;
2440
            COL_COLLECTION:
2441
              CellText := Data.ColName;
2442
          end;
2522
        end;
2443
        end;
2523
      end;
2524
2444
2525
    ntSeriesInfo:
2445
      ntSeriesInfo:
2526
      begin
2446
        begin
2527
        if GetTreeTag(Sender, Column)  = COL_TITLE then
2447
          if GetTreeTag(Sender, Column) = COL_TITLE then
2528
          CellText := 'Серия: ' + Data.Series;
2448
            CellText := 'Серия: ' + Data.Series;
2529
      end;
2449
        end;
2530
2450
2531
    ntBookInfo: if GetTreeTag(Sender, Column)  <> COL_COLLECTION
2451
      ntBookInfo:
2532
     then CellText := GetText(GetTreeTag(Sender, Column), Data);
2452
        if GetTreeTag(Sender, Column) <> COL_COLLECTION then
2453
          CellText := GetText(GetTreeTag(Sender, Column), Data);
2533
2454
2534
  end
2455
    end
2535
  else
2456
  else
2536
    CellText := GetText(GetTreeTag(Sender, Column), Data);
2457
    CellText := GetText(GetTreeTag(Sender, Column), Data);
2537
end;
2458
end;
2538
2459
2539
procedure TfrmMain.tvBooksSRGetText(Sender: TBaseVirtualTree;
2460
procedure TfrmMain.tvBooksSRGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2540
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
2541
  var CellText: String);
2542
var
2461
var
2543
  Data: PBookData;
2462
  Data: PBookData;
2544
begin
2463
begin
...
...
2547
2466
2548
  CellText := ' ';
2467
  CellText := ' ';
2549
  case Column of
2468
  case Column of
2550
    0: CellText := Data.FullName;
2469
    0:
2551
    1: CellText := Data.Title;
2470
      CellText := Data.FullName;
2552
    2: CellText := Data.Series;
2471
    1:
2553
    3: if Data.No <> 0 then
2472
      CellText := Data.Title;
2473
    2:
2474
      CellText := Data.Series;
2475
    3:
2476
      if Data.No <> 0 then
2554
        CellText := IntToStr(Data.No);
2477
        CellText := IntToStr(Data.No);
2555
    4: CellText := IntToStr(Data.Size);
2478
    4:
2556
    6: CellText := Data.Genre;
2479
      CellText := GetFormattedSize(Data.Size);
2557
    7: CellText := DateToStr(Data.Date);
2480
    6:
2481
      CellText := Data.Genre;
2482
    7:
2483
      CellText := DateToStr(Data.Date);
2558
  end;
2484
  end;
2559
end;
2485
end;
2560
2486
2561
procedure TfrmMain.tvGenresGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2487
procedure TfrmMain.tvGenresGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2562
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
2563
var
2488
var
2564
  Data: PGenreData;
2489
  Data: PGenreData;
2565
begin
2490
begin
2566
  Data := Sender.GetNodeData(Node);
2491
  Data := Sender.GetNodeData(Node);
2567
  Assert(Assigned(Data));
2492
  Assert(Assigned(Data));
2568
2493
2569
  CellText := Data.Text;
2494
  CellText := Data.text;
2570
end;
2495
end;
2571
2496
2572
procedure TfrmMain.tvGenresKeyDown(Sender: TObject; var Key: Word;
2497
procedure TfrmMain.tvGenresKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
2573
  Shift: TShiftState);
2574
begin
2498
begin
2575
  if Key = VK_RETURN then
2499
  if Key = VK_RETURN then
2576
  begin
2500
  begin
...
...
2585
2509
2586
begin
2510
begin
2587
  Data := tvGroups.GetNodeData(Node);
2511
  Data := tvGroups.GetNodeData(Node);
2588
  if Data = Nil then Exit;
2512
  if Data = nil then
2513
    Exit;
2589
2514
2590
  DMUser.ActivateGroup(Data.ID);
2515
  DMUser.ActivateGroup(Data.ID);
2591
2516
2592
  lblGroups.Caption := DMUser.tblGroupListName.Value;
2517
  lblGroups.Caption := DMUser.tblGroupListName.Value;
2593
2518
2594
  FillBooksTree(0,tvBooksF,Nil,DMUser.tblGrouppedBooks,true, true);
2519
  FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
2595
2520
2596
end;
2521
end;
2597
2522
...
...
2601
begin
2526
begin
2602
  BNode := tvBooksF.GetFirst;
2527
  BNode := tvBooksF.GetFirst;
2603
  if (BNode <> nil) and (BNode.FirstChild <> nil) then
2528
  if (BNode <> nil) and (BNode.FirstChild <> nil) then
2604
     BNode := tvBooksF.GetFirstChild(BNode);
2529
    BNode := tvBooksF.GetFirstChild(BNode);
2605
  if BNode <> nil then tvBooksF.Selected[BNode] := True;
2530
  if BNode <> nil then
2531
    tvBooksF.Selected[BNode] := True;
2606
end;
2532
end;
2607
2533
2608
procedure TfrmMain.tvGroupsDragDrop(Sender: TBaseVirtualTree; Source: TObject;
2534
procedure TfrmMain.tvGroupsDragDrop(Sender: TBaseVirtualTree; Source: TObject; DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
2609
  DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState;
2610
  Pt: TPoint; var Effect: Integer; Mode: TDropMode);
2611
2535
2612
var
2536
var
2613
  Nodes: TNodeArray;
2537
  Nodes: TNodeArray;
2614
  i: Integer;
2538
  i: Integer;
2615
  Node, LastNode : PvirtualNode;
2539
  Node, LastNode: PVirtualNode;
2616
  Data: PGenreData;
2540
  Data: PGenreData;
2617
  BookData: PBookData;
2541
  BookData: PBookData;
2618
2542
2619
          procedure SelectChildNodes(ParentNode: PVirtualNode);
2543
  procedure SelectChildNodes(ParentNode: PVirtualNode);
2620
          var
2544
  var
2621
            Node: PVirtualNode;
2545
    Node: PVirtualNode;
2622
          begin
2546
  begin
2623
            if ParentNode.ChildCount = 0 then Exit;
2547
    if ParentNode.ChildCount = 0 then
2624
            Node := ParentNode.FirstChild;
2548
      Exit;
2625
            while Node <> Nil do
2549
    Node := ParentNode.FirstChild;
2626
            begin
2550
    while Node <> nil do
2627
              SelectChildNodes(Node);
2551
    begin
2628
              tvBooksF.Selected[Node] := True;
2552
      SelectChildNodes(Node);
2629
              Node := tvBooksF.GetNextSibling(Node);
2553
      tvBooksF.Selected[Node] := True;
2630
            end;
2554
      Node := tvBooksF.GetNextSibling(Node);
2631
          end;
2555
    end;
2556
  end;
2632
2557
2633
begin
2558
begin
2634
  Nodes := nil;
2559
  Nodes := nil;
...
...
2637
2562
2638
  // сканируем выделенные ноды.
2563
  // сканируем выделенные ноды.
2639
  // если есть потомки, выделяем их тоже
2564
  // если есть потомки, выделяем их тоже
2640
  for i := 0 to High(Nodes) do
2565
  for i := 0 to high(Nodes) do
2641
    SelectChildNodes(Nodes[i]);
2566
    SelectChildNodes(Nodes[i]);
2642
2567
2643
  // составляем новый список выделенных
  Nodes := tvBooksF.GetSortedSelection(False);
2568
  // составляем новый список выделенных
  Nodes := tvBooksF.GetSortedSelection(False);
2644
2569
2645
  // переносим данные
2570
  // переносим данные
2646
  for i := 0 to High(Nodes) do
2571
  for i := 0 to high(Nodes) do
2647
  begin
2572
  begin
2648
    BookData := tvBooksF.GetNodeData(Nodes[i]);
2573
    BookData := tvBooksF.GetNodeData(Nodes[i]);
2649
    if (BookData.nodeType = ntBookInfo) and
2574
    if (BookData.nodeType = ntBookInfo) and (DMUser.tblGrouppedBooks.Locate('ID', BookData.ID, [])) then
2650
       (DMUser.tblGrouppedBooks.Locate('ID',BookData.ID,[])) then
2651
    begin
2575
    begin
2652
      DMUser.tblGrouppedBooks.Edit;
2576
      DMUser.tblGrouppedBooks.Edit;
2653
      DMUser.tblGrouppedBooksGroupID.Value := Data.ID;
2577
      DMUser.tblGrouppedBooksGroupID.Value := Data.ID;
2654
      DMUser.tblGrouppedBooks.Post;
2578
      DMUser.tblGrouppedBooks.Post;
2655
    end;
2579
    end;
2656
  end;
2580
  end;
2657
  FillBooksTree(0,tvBooksF,Nil,DMUser.tblGrouppedBooks,true, true);
2581
  FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
2658
end;
2582
end;
2659
2583
2660
procedure TfrmMain.tvGroupsDragOver(Sender: TBaseVirtualTree; Source: TObject;
2584
procedure TfrmMain.tvGroupsDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
2661
  Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode;
2662
  var Effect: Integer; var Accept: Boolean);
2663
var
2585
var
2664
  Data : PGroupData;
2586
  Data: PGroupData;
2665
begin
2587
begin
2666
  Data := tvGroups.GetNodeData(tvGroups.DropTargetNode);
2588
  Data := tvGroups.GetNodeData(tvGroups.DropTargetNode);
2667
  if Data <> nil then
2589
  if Data <> nil then
...
...
2670
      Accept := True;
2592
      Accept := True;
2671
end;
2593
end;
2672
2594
2673
procedure TfrmMain.tvGroupsGetNodeDataSize(Sender: TBaseVirtualTree;
2595
procedure TfrmMain.tvGroupsGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
2674
  var NodeDataSize: Integer);
2675
begin
2596
begin
2676
  NodeDataSize := sizeof(TGroupData);
2597
  NodeDataSize := SizeOf(TGroupData);
2677
end;
2598
end;
2678
2599
2679
procedure TfrmMain.tvGroupsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
2600
procedure TfrmMain.tvGroupsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2680
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
2681
var
2601
var
2682
  Data: PGroupData;
2602
  Data: PGroupData;
2683
begin
2603
begin
2684
  Data := Sender.GetNodeData(Node);
2604
  Data := Sender.GetNodeData(Node);
2685
  Assert(Assigned(Data));
2605
  Assert(Assigned(Data));
2686
  CellText := Data.Text;
2606
  CellText := Data.text;
2687
end;
2607
end;
2688
2608
2689
procedure TfrmMain.tvGroupsKeyDown(Sender: TObject; var Key: Word;
2609
procedure TfrmMain.tvGroupsKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
2690
  Shift: TShiftState);
2691
begin
2610
begin
2692
  if Key = VK_RETURN then
2611
  if Key = VK_RETURN then
2693
  begin
2612
  begin
...
...
2699
procedure TfrmMain.tvAuthorsChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
2618
procedure TfrmMain.tvAuthorsChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
2700
var
2619
var
2701
  Data: PAuthorData;
2620
  Data: PAuthorData;
2702
  ID: integer;
2621
  ID: Integer;
2703
begin
2622
begin
2704
  Data := tvAuthors.GetNodeData(Node);
2623
  Data := tvAuthors.GetNodeData(Node);
2705
  if not Assigned(Data) then
2624
  if not Assigned(Data) then
...
...
2707
  ClearLabels(PAGE_AUTHORS, True);
2626
  ClearLabels(PAGE_AUTHORS, True);
2708
  ID := Data^.ID;
2627
  ID := Data^.ID;
2709
  dmCollection.tblAuthors.Locate('A_ID', ID, []);
2628
  dmCollection.tblAuthors.Locate('A_ID', ID, []);
2710
  lblAuthor.Caption := Data.Text;
2629
  lblAuthor.Caption := Data.text;
2711
  FillBooksTree(ID, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
2630
  FillBooksTree(ID, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
2712
end;
2631
end;
2713
2632
...
...
2717
begin
2636
begin
2718
  BNode := tvBooksA.GetFirst;
2637
  BNode := tvBooksA.GetFirst;
2719
  if (BNode <> nil) and (BNode.FirstChild <> nil) then
2638
  if (BNode <> nil) and (BNode.FirstChild <> nil) then
2720
     BNode := tvBooksA.GetFirstChild(BNode);
2639
    BNode := tvBooksA.GetFirstChild(BNode);
2721
  if BNode <> nil then tvBooksA.Selected[BNode] := True;
2640
  if BNode <> nil then
2641
    tvBooksA.Selected[BNode] := True;
2722
end;
2642
end;
2723
2643
2724
procedure TfrmMain.tvSeriesChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
2644
procedure TfrmMain.tvSeriesChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
2725
var
2645
var
2726
  Data: PAuthorData;
2646
  Data: PAuthorData;
2727
  ID: integer;
2647
  ID: Integer;
2728
begin
2648
begin
2729
  Data := tvSeries.GetNodeData(Node);
2649
  Data := tvSeries.GetNodeData(Node);
2730
  if not Assigned(Data) then
2650
  if not Assigned(Data) then
...
...
2732
  ClearLabels(PAGE_SERIES, True);
2652
  ClearLabels(PAGE_SERIES, True);
2733
  ID := Data^.ID;
2653
  ID := Data^.ID;
2734
  dmCollection.tblSeries.Locate('S_ID', ID, []);
2654
  dmCollection.tblSeries.Locate('S_ID', ID, []);
2735
  lblSeries.Caption := Data.Text;
2655
  lblSeries.Caption := Data.text;
2736
  FillBooksTree(ID, tvBooksS, nil, dmCollection.tblBooksS, False, False); // авторы
2656
  FillBooksTree(ID, tvBooksS, nil, dmCollection.tblBooksS, False, False); // авторы
2737
end;
2657
end;
2738
2658
...
...
2741
  BNode: PVirtualNode;
2661
  BNode: PVirtualNode;
2742
begin
2662
begin
2743
  BNode := tvBooksS.GetFirst;
2663
  BNode := tvBooksS.GetFirst;
2744
  if BNode <> nil then tvBooksS.Selected[BNode] := True;
2664
  if BNode <> nil then
2665
    tvBooksS.Selected[BNode] := True;
2745
end;
2666
end;
2746
2667
2747
procedure TfrmMain.tvSeriesKeyDown(Sender: TObject; var Key: Word;
2668
procedure TfrmMain.tvSeriesKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
2748
  Shift: TShiftState);
2749
begin
2669
begin
2750
  if Key = VK_RETURN then
2670
  if Key = VK_RETURN then
2751
  begin
2671
  begin
...
...
2764
    Exit;
2684
    Exit;
2765
  ClearLabels(PAGE_GENRES, True);
2685
  ClearLabels(PAGE_GENRES, True);
2766
  ID := Data.Code;
2686
  ID := Data.Code;
2767
  if IsFB2Collection(DMUser.ActiveCollection.CollectionType) or
2687
  if isFB2Collection(DMUser.ActiveCollection.CollectionType) or not Settings.ShowSubGenreBooks then
2768
     not Settings.ShowSubGenreBooks
2769
  then
2770
  begin
2688
  begin
2771
    dmCollection.tblGenres.Locate('G_Code', ID, []);
2689
    dmCollection.tblGenres.Locate('G_Code', ID, []);
2772
    FillBooksTree(0, tvBooksG, dmCollection.tblGenre_List, dmCollection.tblBooksG, True, True); // жанры
2690
    FillBooksTree(0, tvBooksG, dmCollection.tblGenre_List, dmCollection.tblBooksG, True, True); // жанры
...
...
2775
  begin
2693
  begin
2776
    dmCollection.tblGenre_List.MasterSource := nil;
2694
    dmCollection.tblGenre_List.MasterSource := nil;
2777
    if Node.ChildCount > 0 then
2695
    if Node.ChildCount > 0 then
2778
        dmCollection.tblGenre_List.Filter := '`GL_Code` Like ' + QuotedStr(ID + '.%')
2696
      dmCollection.tblGenre_List.Filter := '`GL_Code` Like ' + QuotedStr(ID + '.%')
2779
      else
2697
    else
2780
        dmCollection.tblGenre_List.Filter := '`GL_Code` Like ' + QuotedStr(ID + '%');
2698
      dmCollection.tblGenre_List.Filter := '`GL_Code` Like ' + QuotedStr(ID + '%');
2781
    dmCollection.tblGenre_List.Filtered := True;
2699
    dmCollection.tblGenre_List.Filtered := True;
2782
    FillBooksTree(0, tvBooksG, dmCollection.tblGenre_List, dmCollection.tblBooksG, True, True); // жанры
    dmCollection.tblGenre_List.Filtered := False;
2700
    FillBooksTree(0, tvBooksG, dmCollection.tblGenre_List, dmCollection.tblBooksG, True, True); // жанры
    dmCollection.tblGenre_List.Filtered := False;
2783
    dmCollection.tblGenre_List.MasterSource := dmCollection.dsGenres;
2701
    dmCollection.tblGenre_List.MasterSource := dmCollection.dsGenres;
2784
  end;
2702
  end;
2785
  lblGenreTitle.Caption := Data.Text;
2703
  lblGenreTitle.Caption := Data.text;
2786
end;
2704
end;
2787
2705
2788
procedure TfrmMain.tvGenresClick(Sender: TObject);
2706
procedure TfrmMain.tvGenresClick(Sender: TObject);
...
...
2792
begin
2710
begin
2793
  BNode := tvBooksG.GetFirst;
2711
  BNode := tvBooksG.GetFirst;
2794
  if (BNode <> nil) and (BNode.FirstChild <> nil) then
2712
  if (BNode <> nil) and (BNode.FirstChild <> nil) then
2795
     BNode := tvBooksG.GetFirstChild(BNode);
2713
    BNode := tvBooksG.GetFirstChild(BNode);
2796
  if BNode <> nil then tvBooksG.Selected[BNode] := True;
2714
  if BNode <> nil then
2715
    tvBooksG.Selected[BNode] := True;
2797
end;
2716
end;
2798
2717
2799
procedure TfrmMain.GetActiveViewComponents(var Tree : TVirtualStringTree;
2718
procedure TfrmMain.GetActiveViewComponents(var Tree: TVirtualStringTree; var Panel: TMHLInfoPanel; var Cover: TMHLCoverPanel);
2800
                        var Panel: TMHLInfoPanel;
2801
                        var Cover: TMHLCoverPanel);
2802
begin
2719
begin
2803
  case ActiveView of
2720
  case ActiveView of
2804
    ByAuthorView:begin
2721
    ByAuthorView:
2805
                   Tree := tvBooksA;
2722
      begin
2806
                   Panel:= ipnlAuthors;
2723
        Tree := tvBooksA;
2807
                   Cover:= cpCoverA;
2724
        Panel := ipnlAuthors;
2808
                 end;
2725
        Cover := cpCoverA;
2809
    BySeriesView: begin
2726
      end;
2810
                   Tree := tvBooksS;
2727
    BySeriesView:
2811
                   Panel:= ipnlSeries;
2728
      begin
2812
                   Cover:= cpCoverS;
2729
        Tree := tvBooksS;
2813
                 end;
2730
        Panel := ipnlSeries;
2814
    ByGenreView: begin
2731
        Cover := cpCoverS;
2815
                   Tree := tvBooksG;
2732
      end;
2816
                   Panel:= ipnlGenres;
2733
    ByGenreView:
2817
                   Cover:= cpCoverG;
2734
      begin
2818
                 end;
2735
        Tree := tvBooksG;
2819
    SearchView: begin
2736
        Panel := ipnlGenres;
2820
                   Tree := tvBooksSR;
2737
        Cover := cpCoverG;
2821
                   Panel:= ipnlSearch;
2738
      end;
2822
                   Cover:= cpCoverSR;
2739
    SearchView:
2823
                 end;
2740
      begin
2824
    FavoritesView: begin
2741
        Tree := tvBooksSR;
2825
                   Tree := tvBooksF;
2742
        Panel := ipnlSearch;
2826
                   Panel:= ipnlFavorites;
2743
        Cover := cpCoverSR;
2827
                   Cover:= cpCoverF;
2744
      end;
2828
                 end;
2745
    FavoritesView:
2746
      begin
2747
        Tree := tvBooksF;
2748
        Panel := ipnlFavorites;
2749
        Cover := cpCoverF;
2750
      end;
2829
  end;
2751
  end;
2830
end;
2752
end;
2831
2753
...
...
2839
  FileName: string;
2761
  FileName: string;
2840
  Ext: string;
2762
  Ext: string;
2841
2763
2842
  CoverOK: boolean;
2764
  CoverOK: Boolean;
2843
2765
2844
  No: integer;
2766
  No: Integer;
2845
begin
2767
begin
2846
  if BookTreeStatus = bsBusy then
2768
  if BookTreeStatus = bsBusy then
2847
    Exit;
2769
    Exit;
2848
2770
2849
  GetActiveViewComponents(Tree,InfoPanel,Cover);
2771
  GetActiveViewComponents(Tree, InfoPanel, Cover);
2850
2772
2851
  Data := Tree.GetNodeData(Tree.GetFirstSelected);
2773
  Data := Tree.GetNodeData(Tree.GetFirstSelected);
2852
  if not Assigned(Data) then
2774
  if not Assigned(Data) then
...
...
2854
2776
2855
  if Data.nodeType <> ntBookInfo then
2777
  if Data.nodeType <> ntBookInfo then
2856
  begin
2778
  begin
2857
    ClearLabels(Tree.Tag, False);
2779
    ClearLabels(Tree.tag, False);
2858
    Exit;
2780
    Exit;
2859
  end;
2781
  end;
2860
2782
2861
  dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
2783
  dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
2862
2784
2863
2864
  InfoPanel.Title := Data.Title;
2785
  InfoPanel.Title := Data.Title;
2865
//  InfoPanel.Author := Data.ID);
2786
  // InfoPanel.Author := Data.ID);
2866
2787
2867
  InfoPanel.Genre := Data.Genre;
2788
  InfoPanel.Genre := Data.Genre;
2868
  InfoPanel.FileName := FileName;
2789
  InfoPanel.FileName := FileName;
2869
2790
2870
  InfoPanel.HideFileInfo := not (isOnlineCollection(DMUser.ActiveCollection.CollectionType) and not Data.Locale);
2791
  InfoPanel.HideFileInfo := not(isOnlineCollection(DMUser.ActiveCollection.CollectionType) and not Data.Locale);
2871
2792
2872
2873
  if ActiveView <> FavoritesView then
2793
  if ActiveView <> FavoritesView then
2874
  begin
2794
  begin
2875
    InfoPanel.Author := dmCollection.FullAuthorsString(Data.ID);
2795
    InfoPanel.Author := dmCollection.FullAuthorsString(Data.ID);
2876
    if (Folder = '') then
2796
    if (Folder = '') then
2877
       InfoPanel.Folder := FCollectionRoot
2797
      InfoPanel.Folder := FCollectionRoot
2878
     else
2798
    else
2879
       InfoPanel.Folder := FCollectionRoot + Folder
2799
      InfoPanel.Folder := FCollectionRoot + Folder
2880
  end
2800
  end
2881
  else
2801
  else
2882
  begin
2802
  begin
...
...
2884
    InfoPanel.Author := Data.FullName;
2804
    InfoPanel.Author := Data.FullName;
2885
  end;
2805
  end;
2886
2806
2887
  CoverOK := Cover.Show(InfoPanel.Folder,InfoPanel.FileName,No);
2807
  CoverOK := Cover.Show(InfoPanel.Folder, InfoPanel.FileName, No);
2888
2808
2889
  if CoverOK and IsPrivate and IsNonFB2 then
2809
  if CoverOK and IsPrivate and IsNonFB2 then
2890
  begin
2810
  begin
2891
    miConverToFBD.Visible := true;
2811
    miConverToFBD.Visible := True;
2892
    miConverToFBD.Tag := 999;
2812
    miConverToFBD.tag := 999;
2893
    miConverToFBD.Caption := 'Редактировать FBD';
2813
    miConverToFBD.Caption := 'Редактировать FBD';
2894
    if frmConvertToFBD <> nil then
2814
    if frmConvertToFBD <> nil then
2895
    begin
2815
    begin
2896
      frmConvertToFBD.EditorMode := true;
2816
      frmConvertToFBD.EditorMode := True;
2897
      frmConvertToFBD.Caption := 'Редактирование FBD';
2817
      frmConvertToFBD.Caption := 'Редактирование FBD';
2898
    end;
2818
    end;
2899
  end
2819
  end
2900
    else
2820
  else if not CoverOK and IsPrivate and IsNonFB2 then
2901
      if not CoverOK and IsPrivate and IsNonFB2 then
2821
  begin
2902
      begin
2822
    miConverToFBD.Visible := True;
2903
        miConverToFBD.Visible := true;
2823
    miConverToFBD.tag := 0;
2904
        miConverToFBD.Tag := 0;
2824
    miConverToFBD.Caption := 'Преобразовать FBD';
2905
        miConverToFBD.Caption := 'Преобразовать FBD';
2825
    if frmConvertToFBD <> nil then
2906
        if frmConvertToFBD <> nil then
2826
    begin
2907
        begin
2827
      frmConvertToFBD.EditorMode := False;
2908
          frmConvertToFBD.EditorMode := false;
2828
      frmConvertToFBD.Caption := 'Преобразование в FBD';
2909
          frmConvertToFBD.Caption := 'Преобразование в FBD';
2829
    end;
2910
        end;
2830
  end;
2911
      end;
2912
  Application.ProcessMessages;
2831
  Application.ProcessMessages;
2913
end;
2832
end;
2914
2833
2915
procedure TfrmMain.tvBooksTreeCompareNodes(Sender: TBaseVirtualTree; Node1,
2834
procedure TfrmMain.tvBooksTreeCompareNodes(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
2916
  Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
2917
var
2835
var
2918
  Data1, Data2: PBookData;
2836
  Data1, Data2: PBookData;
2919
begin
2837
begin
2920
  Data1 := Sender.GetNodeData(Node1);
2838
  Data1 := Sender.GetNodeData(Node1);
2921
  Data2 := Sender.GetNodeData(Node2);
2839
  Data2 := Sender.GetNodeData(Node2);
2922
  case (Sender as TVirtualStringTree).Header.Columns[Column].Tag of
2840
  case (Sender as TVirtualStringTree).Header.Columns[Column].tag of
2923
    COL_AUTHOR : Result := CompareStr(Data1.FullName, Data2.FullName);
2841
    COL_AUTHOR:
2924
    COL_TITLE  : Result := CompareStr(Data1.Title, Data2.Title);
2842
      Result := CompareStr(Data1.FullName, Data2.FullName);
2925
    COL_SERIES : Result := CompareStr(Data1.Series, Data2.Series);
2843
    COL_TITLE:
2926
    COL_NO     : Result := CompareInt(Data1.No, Data2.No);
2844
      Result := CompareStr(Data1.Title, Data2.Title);
2927
    COL_SIZE   : Result := CompareInt(Data1.Size, Data2.Size);
2845
    COL_SERIES:
2928
    COL_RATE   : Result := CompareInt(Data1.Rate, Data2.Rate);
2846
      Result := CompareStr(Data1.Series, Data2.Series);
2929
    COL_GENRE  : Result := CompareStr(Data1.Genre, Data2.Genre);
2847
    COL_NO:
2930
    COL_DATE   : Result := CompareDate(Data1.Date, Data2.Date);
2848
      Result := CompareInt(Data1.No, Data2.No);
2931
    COL_LANG   : Result := CompareSTR(Data1.Lang, Data2.Lang);
2849
    COL_SIZE:
2932
    COL_LibRate: Result := CompareInt(Data1.LibRate, Data2.LibRate);
2850
      Result := CompareInt(Data1.Size, Data2.Size);
2851
    COL_RATE:
2852
      Result := CompareInt(Data1.Rate, Data2.Rate);
2853
    COL_GENRE:
2854
      Result := CompareStr(Data1.Genre, Data2.Genre);
2855
    COL_DATE:
2856
      Result := CompareDate(Data1.Date, Data2.Date);
2857
    COL_LANG:
2858
      Result := CompareStr(Data1.Lang, Data2.Lang);
2859
    COL_LibRate:
2860
      Result := CompareInt(Data1.LibRate, Data2.LibRate);
2933
  end;
2861
  end;
2934
end;
2862
end;
2935
2863
2936
procedure TfrmMain.tvAuthorsPaintText(Sender: TBaseVirtualTree;
2864
procedure TfrmMain.tvAuthorsPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
2937
  const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
2938
  TextType: TVSTTextType);
2939
begin
2865
begin
2940
  if Sender.Selected[Node] then
2866
  if Sender.Selected[Node] then
2941
    TargetCanvas.Font.Color := clWhite;
2867
    TargetCanvas.Font.Color := clWhite;
2942
end;
2868
end;
2943
2869
2944
procedure TfrmMain.tvBooksTreeBeforeCellPaint(Sender: TBaseVirtualTree;
2870
procedure TfrmMain.tvBooksTreeBeforeCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
2945
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
2946
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
2947
var
2871
var
2948
  Data: PBookData;
2872
  Data: PBookData;
2949
  Color: TColor;
2873
  Color: TColor;
...
...
2953
2877
2954
  Color := Settings.BGColor;
2878
  Color := Settings.BGColor;
2955
  case Data.nodeType of
2879
  case Data.nodeType of
2956
    ntAuthorInfo: Color := Settings.AuthorColor;
2880
    ntAuthorInfo:
2957
    ntSeriesInfo: Color := Settings.SeriesColor;
2881
      Color := Settings.AuthorColor;
2958
    ntBookInfo:begin
2882
    ntSeriesInfo:
2959
                 if Data.Series <> '' then
2883
      Color := Settings.SeriesColor;
2960
                   Color := Settings.SeriesBookColor
2884
    ntBookInfo:
2961
                 else
2885
      begin
2962
                   Color := Settings.BookColor;
2886
        if Data.Series <> '' then
2963
               end;
2887
          Color := Settings.SeriesBookColor
2888
        else
2889
          Color := Settings.BookColor;
2890
      end;
2964
  end;
2891
  end;
2965
2892
2966
2967
2968
  TargetCanvas.Brush.Color := Color;
2893
  TargetCanvas.Brush.Color := Color;
2969
  TargetCanvas.FillRect(CellRect);
2894
  TargetCanvas.FillRect(CellRect);
2970
end;
2895
end;
2971
2896
2972
function TfrmMain.GetTreeTag(const Sender: TBaseVirtualTree; const Column: integer):integer;
2897
function TfrmMain.GetTreeTag(const Sender: TBaseVirtualTree; const Column: Integer): Integer;
2973
begin
2898
begin
2974
  if Column < 0 then Result := -1
2899
  if Column < 0 then
2975
    else
2900
    Result := -1
2976
      Result := (Sender as TVirtualStringTree).Header.Columns[Column].Tag;
2901
  else
2902
    Result := (Sender as TVirtualStringTree).Header.Columns[Column].tag;
2977
end;
2903
end;
2978
2904
2979
2905
procedure TfrmMain.tvBooksTreeAfterCellPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; CellRect: TRect);
2980
procedure TfrmMain.tvBooksTreeAfterCellPaint(Sender: TBaseVirtualTree;
2981
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
2982
  CellRect: TRect);
2983
var
2906
var
2984
  Data: PBookData;
2907
  Data: PBookData;
2985
  Tag : integer;
2908
  tag: Integer;
2986
  X : integer;
2909
  X: Integer;
2987
2910
2988
  procedure Stars(Value: integer);
2911
  procedure Stars(Value: Integer);
2989
  var
2912
  var
2990
    i: integer;
2913
    i: Integer;
2991
    x, y: integer;
2914
    X, Y: Integer;
2992
    w, h: integer;
2915
    w, h: Integer;
2993
  begin
2916
  begin
2994
    w := FStarImage.Width;
2917
    w := FStarImage.Width;
2995
    h := FStarImage.Height;
2918
    h := FStarImage.Height;
2996
    x := CellRect.Left (*+ (CellRect.Right - CellRect.Left - 10 {w} * 5) div 2*);
2919
    X := CellRect.Left (* + (CellRect.Right - CellRect.Left - 10 {w} * 5) div 2 *) ;
2997
    y := CellRect.Top + (CellRect.Bottom - CellRect.Top - h) div 2;
2920
    Y := CellRect.Top + (CellRect.Bottom - CellRect.Top - h) div 2;
2998
    for i := 0 to 4 do
2921
    for i := 0 to 4 do
2999
    begin
2922
    begin
3000
      if Value > i then
2923
      if Value > i then
3001
        FStarImage.Draw(TargetCanvas, Rect(x, y, x + w, y + h))
2924
        FStarImage.Draw(TargetCanvas, Rect(X, Y, X + w, Y + h))
3002
      else
2925
      else
3003
        FEmptyStarImage.Draw(TargetCanvas, Rect(x, y, x + w, y + h));
2926
        FEmptyStarImage.Draw(TargetCanvas, Rect(X, Y, X + w, Y + h));
3004
      Inc(x, {w} 10);
2927
      inc(X, { w } 10);
3005
    end;
2928
    end;
3006
  end;
2929
  end;
3007
2930
...
...
3012
  if Data.nodeType <> ntBookInfo then
2935
  if Data.nodeType <> ntBookInfo then
3013
    Exit;
2936
    Exit;
3014
2937
3015
  Tag := GetTreeTag(Sender, Column);
2938
  tag := GetTreeTag(Sender, Column);
3016
2939
3017
  X := (Sender as TvirtualStringTree).Header.Columns.Items[Column].Left;
2940
  X := (Sender as TVirtualStringTree).Header.Columns.Items[Column].Left;
3018
2941
3019
  if (Tag = COL_STATE) then
2942
  if (tag = COL_STATE) then
3020
  begin
2943
  begin
3021
    if isOnlineCollection(DMUser.ActiveCollection.CollectionType)
2944
    if isOnlineCollection(DMUser.ActiveCollection.CollectionType) and (Data.Locale) then
3022
        and (Data.Locale)
3023
    then
3024
      ilFileTypes.Draw(TargetCanvas, X, CellRect.Top + 1, 7);
2945
      ilFileTypes.Draw(TargetCanvas, X, CellRect.Top + 1, 7);
3025
    if Data.Progress = 100 then
2946
    if Data.Progress = 100 then
3026
      ilFileTypes.Draw(TargetCanvas, X + 10, CellRect.Top, 8);
2947
      ilFileTypes.Draw(TargetCanvas, X + 10, CellRect.Top, 8);
...
...
3029
      ilFileTypes.Draw(TargetCanvas, X + 25, CellRect.Top + 1, 9);
2950
      ilFileTypes.Draw(TargetCanvas, X + 25, CellRect.Top + 1, 9);
3030
  end;
2951
  end;
3031
2952
3032
  if (Tag = COL_RATE) then Stars(Data.Rate);
2953
  if (tag = COL_RATE) then
2954
    Stars(Data.Rate);
3033
2955
3034
  if (Tag = COL_LIBRATE) then
2956
  if (tag = COL_LibRate) then
3035
    if Data.LibRate <= 5 then Stars(Data.LibRate)
2957
    if Data.LibRate <= 5 then
3036
      else Stars(0);
2958
      Stars(Data.LibRate)
2959
    else
2960
      Stars(0);
3037
end;
2961
end;
3038
2962
3039
procedure TfrmMain.tvBooksTreeKeyDown(Sender: TObject; var Key: Word;
2963
procedure TfrmMain.tvBooksTreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
3040
  Shift: TShiftState);
3041
var
2964
var
3042
  Node : PVirtualNode;
2965
  Node: PVirtualNode;
3043
  Tree, Left : TVirtualStringTree;
2966
  Tree, Left: TVirtualStringTree;
3044
  Data : PBookData;
2967
  Data: PBookData;
3045
begin
2968
begin
3046
  if Key = vk_Insert then
2969
  if Key = vk_Insert then
3047
  begin
2970
  begin
...
...
3049
    Node := Tree.FocusedNode;
2972
    Node := Tree.FocusedNode;
3050
    if Node <> nil then
2973
    if Node <> nil then
3051
    begin
2974
    begin
3052
      BookTreeStatus := bsBusy ;
2975
      BookTreeStatus := bsBusy;
3053
      Data := Tree.GetNodeData(Node);
2976
      Data := Tree.GetNodeData(Node);
3054
      if Data.nodeType = ntBookInfo then
2977
      if Data.nodeType = ntBookInfo then
3055
        if Tree.CheckState[Node] = csCheckedNormal then
2978
        if Tree.CheckState[Node] = csCheckedNormal then
3056
          Tree.CheckState[Node] := csUnCheckedNormal
2979
          Tree.CheckState[Node] := csUncheckedNormal
3057
        else
2980
        else
3058
          Tree.CheckState[Node] := csCheckedNormal;
2981
          Tree.CheckState[Node] := csCheckedNormal;
3059
2982
3060
      Tree.Selected[Node] := False;
2983
      Tree.Selected[Node] := False;
3061
      Node := Tree.GetNext(Node);
2984
      Node := Tree.GetNext(Node);
3062
      BookTreeStatus := bsFree ;
2985
      BookTreeStatus := bsFree;
3063
      if Node <> nil then Tree.Selected[Node] := True;
2986
      if Node <> nil then
2987
        Tree.Selected[Node] := True;
3064
    end;
2988
    end;
3065
  end;
2989
  end;
3066
  if ((Key = vk_Right) or  (Key = vk_Left))and (ssCtrl in Shift) then
2990
  if ((Key = vk_Right) or (Key = vk_Left)) and (ssCtrl in Shift) then
3067
  begin
2991
  begin
3068
    Tree := (Sender as TVirtualStringTree);
2992
    Tree := (Sender as TVirtualStringTree);
3069
    case ActiveView of
2993
    case ActiveView of
3070
      ByAuthorView: Left := tvAuthors;
2994
      ByAuthorView:
3071
      BySeriesView: Left := tvSeries;
2995
        Left := tvAuthors;
3072
      ByGenreView: Left := tvGenres;
2996
      BySeriesView:
3073
      FavoritesView: Left := tvGroups;
2997
        Left := tvSeries;
3074
      SearchView: Exit;
2998
      ByGenreView:
2999
        Left := tvGenres;
3000
      FavoritesView:
3001
        Left := tvGroups;
3002
      SearchView:
3003
        Exit;
3075
    end;
3004
    end;
3076
3005
3077
    Node := Left.FocusedNode;
3006
    Node := Left.FocusedNode;
3078
    Left.Selected[Node] := False;
3007
    Left.Selected[Node] := False;
3079
3008
3080
    if (Key = vk_Right) then
3009
    if (Key = vk_Right) then
3081
           Node := Left.GetNext(Node)
3010
      Node := Left.GetNext(Node)
3082
     else
3011
    else
3083
           Node := Left.GetPrevious(Node);
3012
      Node := Left.GetPrevious(Node);
3084
3013
3085
    if Node <> Nil then
3014
    if Node <> nil then
3086
    begin
3015
    begin
3087
      Left.Selected[Node] := True;
3016
      Left.Selected[Node] := True;
3088
      Left.FocusedNode := Node;
3017
      Left.FocusedNode := Node;
3089
    end;
3018
    end;
3090
3019
3091
    Node := Tree.GetFirst;
3020
    Node := Tree.GetFirst;
3092
    if Node <> Nil then
3021
    if Node <> nil then
3093
         Tree.Selected[Node] := True;
3022
      Tree.Selected[Node] := True;
3094
  end;
3023
  end;
3095
3024
3096
3097
end;
3025
end;
3098
3026
3099
procedure TfrmMain.tvBooksAGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
3027
procedure TfrmMain.tvBooksAGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
...
...
3111
  NodeDataSize := SizeOf(TBookData);
3039
  NodeDataSize := SizeOf(TBookData);
3112
end;
3040
end;
3113
3041
3114
procedure TfrmMain.tvBooksTreeMouseUp(Sender: TObject; Button: TMouseButton;
3042
procedure TfrmMain.tvBooksTreeMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
3115
  Shift: TShiftState; X, Y: Integer);
3116
var
3043
var
3117
  Node: PVirtualNode;
3044
  Node: PVirtualNode;
3118
  Data: PBookData;
3045
  Data: PBookData;
...
...
3121
begin
3048
begin
3122
  if (Button = mbLeft) and (ssShift in Shift) then
3049
  if (Button = mbLeft) and (ssShift in Shift) then
3123
  begin
3050
  begin
3124
    BookTreeStatus := bsBusy ;
3051
    BookTreeStatus := bsBusy;
3125
    try
3052
    try
3126
      Tree := Sender as TVirtualStringTree;
3053
      Tree := Sender as TVirtualStringTree;
3127
      ClearLabels(Tree.Tag, True);
3054
      ClearLabels(Tree.tag, True);
3128
      Node := Tree.GetFirstSelected;
3055
      Node := Tree.GetFirstSelected;
3129
      Selected := Node;
3056
      Selected := Node;
3130
      while Node <> nil do
3057
      while Node <> nil do
3131
      begin
3058
      begin
3132
        Data := Tree.GetNodeData(Node);
3059
        Data := Tree.GetNodeData(Node);
3133
        if Data.nodeType = ntBookInfo  then
3060
        if Data.nodeType = ntBookInfo then
3134
        begin
3061
        begin
3135
          if Tree.CheckState[Node] = csCheckedNormal then
3062
          if Tree.CheckState[Node] = csCheckedNormal then
3136
             Tree.CheckState[Node] := csUnCheckedNormal
3063
            Tree.CheckState[Node] := csUncheckedNormal
3137
          else
3064
          else
3138
            Tree.CheckState[Node] := csCheckedNormal;
3065
            Tree.CheckState[Node] := csCheckedNormal;
3139
          Tree.Selected[Node] := False;
3066
          Tree.Selected[Node] := False;
3140
        end;
3067
        end;
3141
        Node := Tree.GetNextSelected(Node);
3068
        Node := Tree.GetNextSelected(Node);
3142
      end; //while
3069
      end; // while
3143
    finally
3070
    finally
3144
      BookTreeStatus := bsFree ;
3071
      BookTreeStatus := bsFree;
3145
      Tree.Selected[Selected] := True;
3072
      Tree.Selected[Selected] := True;
3146
    end;
3073
    end;
3147
  end; // if
3074
  end; // if
3148
end;
3075
end;
3149
3076
3150
procedure TfrmMain.tvBooksTreePaintText(Sender: TBaseVirtualTree;
3077
procedure TfrmMain.tvBooksTreePaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
3151
  const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
3152
  TextType: TVSTTextType);
3153
var
3078
var
3154
  Data: PBookData;
3079
  Data: PBookData;
3155
begin
3080
begin
3156
  Data := Sender.GetNodeData(Node);
3081
  Data := Sender.GetNodeData(Node);
3157
  if Data.nodeType <> ntBookInfo then
3082
  if Data.nodeType <> ntBookInfo then
3158
      TargetCanvas.Font.Style := [fsBold]
3083
    TargetCanvas.Font.Style := [fsBold]
3159
    else
3084
  else if not Sender.Selected[Node] then
3160
      if not Sender.Selected[Node] then
3085
  begin
3161
      begin
3086
    if Data.Locale then
3162
        if Data.Locale then TargetCanvas.Font.Color := Settings.LocalColor;
3087
      TargetCanvas.Font.Color := Settings.LocalColor;
3163
        if Data.Deleted then TargetCanvas.Font.Color := Settings.DeletedColor;
3088
    if Data.Deleted then
3164
      end;
3089
      TargetCanvas.Font.Color := Settings.DeletedColor;
3090
  end;
3165
end;
3091
end;
3166
3092
3167
procedure TfrmMain.tvDownloadListGetText(Sender: TBaseVirtualTree;
3093
procedure TfrmMain.tvDownloadListGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
3168
  Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
3169
  var CellText: string);
3170
const
3094
const
3171
  States : array [0..3] of string = ('Ожидание','Закачка','Готово','Ошибка');
3095
  States: array [0 .. 3] of string = ('Ожидание', 'Закачка', 'Готово', 'Ошибка');
3172
var
3096
var
3173
  Data : PDownloadData;
3097
  Data: PDownloadData;
3174
begin
3098
begin
3175
  Data := tvDownloadList.GetNodeData(Node);
3099
  Data := tvDownloadList.GetNodeData(Node);
3176
  case Column of
3100
  case Column of
3177
    0: CellText := Data.Author;
3101
    0:
3178
    1: CellText := Data.Title;
3102
      CellText := Data.Author;
3179
    2: CellText := IntToStr(Data.Size);
3103
    1:
3180
    3: CellText := States[ord(Data.State)];
3104
      CellText := Data.Title;
3105
    2:
3106
      CellText := GetFormattedSize(Data.Size);
3107
    3:
3108
      CellText := States[ord(Data.State)];
3181
  end;
3109
  end;
3182
end;
3110
end;
3183
3111
3184
procedure TfrmMain.tvDownloadListLoadNode(Sender: TBaseVirtualTree;
3112
procedure TfrmMain.tvDownloadListLoadNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream);
3185
  Node: PVirtualNode; Stream: TStream);
3186
var
3113
var
3187
  Data: PDownloadData;
3114
  Data: PDownloadData;
3188
  size: Integer;
3115
  Size: Integer;
3189
  StrBuffer: PChar;
3116
  StrBuffer: PChar;
3190
3117
3191
    function GetString:string;
3118
  function GetString: string;
3192
    begin
3119
  begin
3193
      Stream.Read(Size, SizeOf(Size));
3120
    Stream.read(Size, SizeOf(Size));
3194
      StrBuffer := AllocMem(Size);
3121
    StrBuffer := AllocMem(Size);
3195
      Stream.Read(StrBuffer^, Size);
3122
    Stream.read(StrBuffer^, Size);
3196
      Result := (StrBuffer);
3123
    Result := (StrBuffer);
3197
      FreeMem(StrBuffer);
3124
    FreeMem(StrBuffer);
3198
    end;
3125
  end;
3199
3126
3200
begin
3127
begin
3201
  Data := Sender.GetNodeData(Node);
3128
  Data := Sender.GetNodeData(Node);
3202
  // ID
3129
  // ID
3203
  Stream.Read(Data.ID, SizeOf(Data.ID));
3130
  Stream.read(Data.ID, SizeOf(Data.ID));
3204
3131
3205
  Data.Title := GetString;
3132
  Data.Title := GetString;
3206
  Data.Author := GetString;
3133
  Data.Author := GetString;
3207
3134
3208
  // Size
3135
  // Size
3209
  Stream.Read(Data.Size, SizeOf(Data.Size));
3136
  Stream.read(Data.Size, SizeOf(Data.Size));
3210
3137
3211
  Data.FileName := GetString;
3138
  Data.FileName := GetString;
3212
  Data.URL := GetString;
3139
  Data.URL := GetString;
3213
3140
3214
  // State
3141
  // State
3215
  Stream.Read(Data.State, SizeOf(Data.State));
3142
  Stream.read(Data.State, SizeOf(Data.State));
3216
end;
3143
end;
3217
3144
3218
procedure TfrmMain.tvDownloadListPaintText(Sender: TBaseVirtualTree;
3145
procedure TfrmMain.tvDownloadListPaintText(Sender: TBaseVirtualTree; const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType);
3219
  const TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
3220
  TextType: TVSTTextType);
3221
var
3146
var
3222
  Data : PDownloadData;
3147
  Data: PDownloadData;
3223
begin
3148
begin
3224
  Data := Sender.GetNodeData(Node);
3149
  Data := Sender.GetNodeData(Node);
3225
  if (Data <> nil) and not Sender.Selected[Node] then
3150
  if (Data <> nil) and not Sender.Selected[Node] then
3226
    case Data.State of
3151
    case Data.State of
3227
      dsRun  : TargetCanvas.Font.Color := clGreen;
3152
      dsRun:
3228
      dsError: TargetCanvas.Font.Color := clRed;
3153
        TargetCanvas.Font.Color := clGreen;
3154
      dsError:
3155
        TargetCanvas.Font.Color := clRed;
3229
    end;
3156
    end;
3230
end;
3157
end;
3231
3158
3232
procedure TfrmMain.tvDownloadListSaveNode(Sender: TBaseVirtualTree;
3159
procedure TfrmMain.tvDownloadListSaveNode(Sender: TBaseVirtualTree; Node: PVirtualNode; Stream: TStream);
3233
  Node: PVirtualNode; Stream: TStream);
3234
var
3160
var
3235
  Data: PDownloadData;
3161
  Data: PDownloadData;
3236
  size: Integer;
3162
  Size: Integer;
3237
3163
3238
  procedure WriteString(const S: string);
3164
  procedure WriteString(const S: string);
3239
  begin
3165
  begin
3240
    Size := ByteLength(S) + 1;
3166
    Size := ByteLength(S) + 1;
3241
    Stream.Write(Size, SizeOf(Size));
3167
    Stream.write(Size, SizeOf(Size));
3242
    Stream.Write(PChar(S)^, Size);
3168
    Stream.write(PChar(S)^, Size);
3243
  end;
3169
  end;
3244
3170
3245
begin
3171
begin
3246
  Data := Sender.GetNodeData(Node);
3172
  Data := Sender.GetNodeData(Node);
3247
3173
3248
  if Data = Nil then Exit;
3174
  if Data = nil then
3175
    Exit;
3249
3176
3250
  //  ID
3177
  // ID
3251
  Stream.Write(Data.ID, SizeOf(Data.ID));
3178
  Stream.write(Data.ID, SizeOf(Data.ID));
3252
3179
3253
  WriteString(Data.Title);
3180
  WriteString(Data.Title);
3254
  WriteString(Data.Author);
3181
  WriteString(Data.Author);
3255
3182
3256
  // Size
3183
  // Size
3257
  Stream.Write(Data.Size, SizeOf(Data.Size));
3184
  Stream.write(Data.Size, SizeOf(Data.Size));
3258
3185
3259
  WriteString(Data.FileName);
3186
  WriteString(Data.FileName);
3260
  WriteString(Data.URL);
3187
  WriteString(Data.URL);
3261
3188
3262
  // State
3189
  // State
3263
  Stream.Write(Data.State, SizeOf(Data.State));
3190
  Stream.write(Data.State, SizeOf(Data.State));
3264
end;
3191
end;
3265
3192
3266
//
3193
//
...
...
3288
    while not DMUser.tblGrouppedBooks.Eof do
3215
    while not DMUser.tblGrouppedBooks.Eof do
3289
    begin
3216
    begin
3290
      if DMUser.tblExtra.RecordCount <> 0 then
3217
      if DMUser.tblExtra.RecordCount <> 0 then
3291
       DMUser.tblExtra.Delete;
3218
        DMUser.tblExtra.Delete;
3292
      DMUser.tblGrouppedBooks.Delete;
3219
      DMUser.tblGrouppedBooks.Delete;
3293
    end;
3220
    end;
3294
    FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
3221
    FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
...
...
3299
3226
3300
procedure TfrmMain.MoveDwnldListNodes(Sender: TObject);
3227
procedure TfrmMain.MoveDwnldListNodes(Sender: TObject);
3301
var
3228
var
3302
  i: integer;
3229
  i: Integer;
3303
  List: TSelectionList;
3230
  List: TSelectionList;
3304
begin
3231
begin
3305
  GetSeelections(tvDownloadList,List);
3232
  GetSeelections(tvDownloadList, List);
3306
  for I := 0 to tvDownloadList.SelectedCount - 1 do
3233
  for i := 0 to tvDownloadList.SelectedCount - 1 do
3307
    case (Sender as TrzToolButton).Tag of
3234
    case (Sender as TRzToolButton).tag of
3308
      20: tvDownloadList.MoveTo(List[tvDownloadList.SelectedCount - i - 1],tvDownloadList.GetFirst,amInsertBefore,False);
3235
      20:
3309
      21: tvDownloadList.MoveTo(List[i],tvDownloadList.GetPrevious(List[i]),amInsertBefore,False);
3236
        tvDownloadList.MoveTo(List[tvDownloadList.SelectedCount - i - 1], tvDownloadList.GetFirst, amInsertBefore, False);
3310
      22: tvDownloadList.MoveTo(List[tvDownloadList.SelectedCount - i - 1],tvDownloadList.GetNext(List[tvDownloadList.SelectedCount - i - 1]),amInsertAfter,False);
3237
      21:
3311
      23: tvDownloadList.MoveTo(List[i],tvDownloadList.GetLast,amInsertAfter,False);
3238
        tvDownloadList.MoveTo(List[i], tvDownloadList.GetPrevious(List[i]), amInsertBefore, False);
3239
      22:
3240
        tvDownloadList.MoveTo(List[tvDownloadList.SelectedCount - i - 1], tvDownloadList.GetNext(List[tvDownloadList.SelectedCount - i - 1]), amInsertAfter, False);
3241
      23:
3242
        tvDownloadList.MoveTo(List[i], tvDownloadList.GetLast, amInsertAfter, False);
3312
    end;
3243
    end;
3313
end;
3244
end;
3314
3245
3315
procedure TfrmMain.CopyToCollectionClick(Sender: TObject);
3246
procedure TfrmMain.CopyToCollectionClick(Sender: TObject);
3316
var
3247
var
3317
  R: TbookRecord;
3248
  R: TBookRecord;
3318
  ID: integer;
3249
  ID: Integer;
3319
  Tree: TVirtualStringTree;
3250
  Tree: TVirtualStringTree;
3320
  Data: PBookData;
3251
  Data: PBookData;
3321
  Node: PVirtualNode;
3252
  Node: PVirtualNode;
...
...
3330
  end;
3261
  end;
3331
3262
3332
  GetActiveTree(Tree);
3263
  GetActiveTree(Tree);
3333
  ID := (Sender as TMenuItem).Tag;
3264
  ID := (Sender as TMenuItem).tag;
3334
  if not DMUser.ActivateCollection(ID) then
3265
  if not DMUser.ActivateCollection(ID) then
3335
    Exit;
3266
    Exit;
3336
  ALibrary := TMHLLibrary.Create(nil);
3267
  ALibrary := TMHLLibrary.Create(nil);
...
...
3359
3290
3360
procedure TfrmMain.CoverPanelResize(Sender: TObject);
3291
procedure TfrmMain.CoverPanelResize(Sender: TObject);
3361
var
3292
var
3362
  NewSize: integer;
3293
  NewSize: Integer;
3363
begin
3294
begin
3364
  NewSize := (Sender as TWinControl).Width;
3295
  NewSize := (Sender as TWinControl).Width;
3365
  if NewSize < 150 then NewSize := 150;
3296
  if NewSize < 150 then
3366
  
3297
    NewSize := 150;
3298
3367
  cpCoverA.Width := NewSize;
3299
  cpCoverA.Width := NewSize;
3368
  cpCoverS.Width := NewSize;
3300
  cpCoverS.Width := NewSize;
3369
  cpCoverG.Width := NewSize;
3301
  cpCoverG.Width := NewSize;
...
...
3371
  cpCoverSR.Width := NewSize;
3303
  cpCoverSR.Width := NewSize;
3372
end;
3304
end;
3373
3305
3374
procedure TfrmMain.FillBookIdList(const Tree: TVirtualStringTree; var BookIDList: TBookIdList );
3306
procedure TfrmMain.FillBookIdList(const Tree: TVirtualStringTree; var BookIDList: TBookIdList);
3375
var
3307
var
3376
  i: integer;
3308
  i: Integer;
3377
  Data: PBookData;
3309
  Data: PBookData;
3378
  Node: PVirtualNode;
3310
  Node: PVirtualNode;
3379
begin
3311
begin
...
...
3385
    Assert(Assigned(Data));
3317
    Assert(Assigned(Data));
3386
    if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
3318
    if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
3387
    begin
3319
    begin
3388
      SetLength(BookIdList, i + 1);
3320
      SetLength(BookIDList, i + 1);
3389
      BookIdList[i].ID := Data.ID;
3321
      BookIDList[i].ID := Data.ID;
3390
      Inc(i);
3322
      inc(i);
3391
      Tree.CheckState[Node] := csUnCheckedNormal;
3323
      Tree.CheckState[Node] := csUncheckedNormal;
3392
    end;
3324
    end;
3393
    Node := Tree.GetNext(Node);
3325
    Node := Tree.GetNext(Node);
3394
  end;
3326
  end;
...
...
3399
  AFolder: string;
3331
  AFolder: string;
3400
  SaveDeviceDir: string;
3332
  SaveDeviceDir: string;
3401
  SaveFolderTemplate: string;
3333
  SaveFolderTemplate: string;
3402
  TMPParams: String;
3334
  TMPParams: string;
3403
  ScriptID: Integer;
3335
  ScriptID: Integer;
3404
  BookIDList: TBookIdList;
3336
  BookIDList: TBookIdList;
3405
  Files : string;
3337
  Files: string;
3406
  p:integer;
3338
  p: Integer;
3407
  S: string;
3339
  S: string;
3408
  Tree: TVirtualStringTree;
3340
  Tree: TVirtualStringTree;
3409
  ExportMode: TExportMode;
3341
  ExportMode: TExportMode;
3410
begin
3342
begin
3411
  FCancelled := false;
3343
  FCancelled := False;
3412
  GetActiveTree(Tree);
3344
  GetActiveTree(Tree);
3413
  FillBookIdList(Tree, BookIDList);
3345
  FillBookIdList(Tree, BookIDList);
3414
3346
...
...
3420
3352
3421
  SaveDeviceDir := Settings.DeviceDir;
3353
  SaveDeviceDir := Settings.DeviceDir;
3422
  SaveFolderTemplate := Settings.FolderTemplate;
3354
  SaveFolderTemplate := Settings.FolderTemplate;
3423
  //  dlgFolder.Directory := Settings.DeviceDir;
3355
  // dlgFolder.Directory := Settings.DeviceDir;
3424
  ScriptID := (Sender as TComponent).Tag;
3356
  ScriptID := (Sender as TComponent).tag;
3425
3357
3426
3427
  if isFB2Collection(DMUser.ActiveCollection.CollectionType) then
3358
  if isFB2Collection(DMUser.ActiveCollection.CollectionType) then
3428
  case ScriptID of
3359
    case ScriptID of
3429
    850: ExportMode := emFb2;
3360
      850:
3430
    851: ExportMode := emFb2Zip;
3361
        ExportMode := emFb2;
3431
    852: ExportMode := emLrf;
3362
      851:
3432
    853: ExportMode := emTxt;
3363
        ExportMode := emFb2Zip;
3433
    854: ExportMode := emEpub;
3364
      852:
3434
    855: ExportMode := emPDF;
3365
        ExportMode := emLrf;
3435
    else ExportMode := Settings.ExportMode;
3366
      853:
3436
  end
3367
        ExportMode := emTxt;
3368
      854:
3369
        ExportMode := emEpub;
3370
      855:
3371
        ExportMode := emPDF;
3372
    else
3373
      ExportMode := Settings.ExportMode;
3374
    end
3437
  else
3375
  else
3438
    ExportMode := emFb2;
3376
    ExportMode := emFb2;
3439
3377
3440
  Dec(ScriptID, 901);
3378
    Dec(ScriptID, 901);
3441
3379
3442
  if (ScriptID < 1 ) and (Settings.PromptDevicePath) then
3380
    if (ScriptID < 1) and (Settings.PromptDevicePath) then
3443
    //if not dlgFolder.Execute then
3381
      // if not dlgFolder.Execute then
3444
    if not GetFolderName(Handle, 'Укажите путь', AFolder) then
3382
      if not GetFolderName(Handle, 'Укажите путь', AFolder) then
3445
      Exit
3383
        Exit
3446
    else
3384
      else
3447
      { TODO -oNickR -cRefactoring : это временное изменение в настройках и оно не должно сохраняться при закрытии программы
                             Это изменение нужно только для работы функций ZipToDevice/FileToDevice и решается
3385
        { TODO -oNickR -cRefactoring : это временное изменение в настройках и оно не должно сохраняться при закрытии программы
          Это изменение нужно только для работы функций ZipToDevice/FileToDevice и решается
3448
                             параметрами этих функций
3386
          параметрами этих функций
3449
      }
3387
          }
3450
      Settings.DeviceDir := AFolder;
3388
        Settings.DeviceDir := AFolder;
3451
3389
3452
  if ScriptID >= 0 then
3390
    if ScriptID >= 0 then
3453
  begin
3454
    TMPParams := Settings.Scripts[ScriptID].Params;
3455
    if Pos('%NFT%', Settings.Scripts[ScriptID].Params) <> 0 then
3456
    begin
3391
    begin
3457
      Settings.FolderTemplate := '';
3392
      TMPParams := Settings.Scripts[ScriptID].Params;
3458
      StrReplace('%NFT%', '', TMPParams);
3393
      if Pos('%NFT%', Settings.Scripts[ScriptID].Params) <> 0 then
3459
    end;
3394
      begin
3395
        Settings.FolderTemplate := '';
3396
        StrReplace('%NFT%', '', TMPParams);
3397
      end;
3460
3398
3461
    if Pos('%TMP%', Settings.Scripts[ScriptID].Params) <> 0 then
3399
      if Pos('%TMP%', Settings.Scripts[ScriptID].Params) <> 0 then
3462
      StrReplace('%TMP%',Settings.TempPath, TMPParams);
3400
        StrReplace('%TMP%', Settings.TempPath, TMPParams);
3463
3401
3464
    if Pos('%DEST%', Settings.Scripts[ScriptID].Params) <> 0 then
3402
      if Pos('%DEST%', Settings.Scripts[ScriptID].Params) <> 0 then
3465
      StrReplace('%DEST%',Settings.DeviceDir, TMPParams);
3403
        StrReplace('%DEST%', Settings.DeviceDir, TMPParams);
3466
3404
3467
    if Pos('%FOLDER ', Settings.Scripts[ScriptID].Params) <> 0 then
3405
      if Pos('%FOLDER ', Settings.Scripts[ScriptID].Params) <> 0 then
3468
    begin
3406
      begin
3469
      StrReplace('%FOLDER ','', TMPParams);
3407
        StrReplace('%FOLDER ', '', TMPParams);
3470
      p := pos('%',TMPParams);
3408
        p := Pos('%', TMPParams);
3471
      S := copy(TMPParams,1,p-1);
3409
        S := copy(TMPParams, 1, p - 1);
3472
      Settings.DeviceDir := S;
3410
        Settings.DeviceDir := S;
3473
      Delete(TMPParams,1,p);
3411
        Delete(TMPParams, 1, p);
3474
    end;
3412
      end;
3475
3413
3476
    if (Settings.Scripts[ScriptID].Path = '%COPY%') and
3414
      if (Settings.Scripts[ScriptID].Path = '%COPY%') and (trim(TMPParams) <> '') then
3477
       (trim(TMPParams) <> '') then Settings.DeviceDir := trim(TMPParams);
3415
        Settings.DeviceDir := trim(TMPParams);
3478
3416
3479
    Settings.Scripts[ScriptID].TmpParams := TMPParams;
3417
      Settings.Scripts[ScriptID].TMPParams := TMPParams;
3480
  end;
3418
    end;
3481
3419
3482
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
3420
    if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
3483
  begin
3421
    begin
3484
    unit_ExportToDevice.DownloadBooks(dmCollection.ActiveTable, BookIdList);
3422
      unit_ExportToDevice.DownloadBooks(dmCollection.ActiveTable, BookIDList);
3485
    RefreshBooksState(Tree, BookIDList);
3423
      RefreshBooksState(Tree, BookIDList);
3486
    if FCancelled then Exit;
3424
      if FCancelled then
3425
        Exit;
3487
3426
3488
  end;
3427
    end;
3489
3428
3490
  if ActiveView <> FavoritesView then
3429
    if ActiveView <> FavoritesView then
3491
       unit_ExportToDevice.ExportToDevice(dmCollection.ActiveTable, BookIdList, ExportMode, Files)
3430
      unit_ExportToDevice.ExportToDevice(dmCollection.ActiveTable, BookIDList, ExportMode, Files)
3492
  else
3431
    else
3493
       unit_ExportToDevice.ExportToDevice(dmUser.tblGrouppedBooks, BookIdList, ExportMode, Files);
3432
      unit_ExportToDevice.ExportToDevice(DMUser.tblGrouppedBooks, BookIDList, ExportMode, Files);
3494
3433
3495
  if (ScriptID >= 0 ) and (Settings.Scripts[ScriptID].Path <> '%COPY%') then
3434
    if (ScriptID >= 0) and (Settings.Scripts[ScriptID].Path <> '%COPY%') then
3496
  begin
3497
    if Pos('%FILENAME%', Settings.Scripts[ScriptID].Params) <> 0 then
3498
    begin
3435
    begin
3499
      StrReplace('%FILENAME%', Files, TMPParams);
3436
      if Pos('%FILENAME%', Settings.Scripts[ScriptID].Params) <> 0 then
3500
      Settings.Scripts[ScriptID].TmpParams := TMPParams;
3437
      begin
3438
        StrReplace('%FILENAME%', Files, TMPParams);
3439
        Settings.Scripts[ScriptID].TMPParams := TMPParams;
3440
      end;
3441
      Settings.Scripts[ScriptID].Run;
3501
    end;
3442
    end;
3502
    Settings.Scripts[ScriptID].Run;
3503
  end;
3504
3443
3505
  Settings.DeviceDir := SaveDeviceDir;
3444
    Settings.DeviceDir := SaveDeviceDir;
3506
  Settings.FolderTemplate := SaveFolderTemplate;
3445
    Settings.FolderTemplate := SaveFolderTemplate;
3507
3446
3508
end;
3447
  end;
3509
3448
3449
  procedure TfrmMain.HTTPWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
3450
  begin
3451
    spStatus.Caption := 'Готово';
3452
    spProgress.Percent := 100;
3453
  end;
3510
3454
3511
procedure TfrmMain.HTTPWorkEnd(ASender: TObject; AWorkMode: TWorkMode);
3455
  procedure TfrmMain.DownloadBooks;
3512
begin
3456
  var
3513
  spStatus.Caption := 'Готово';
3457
    BookIDList: TBookIdList;
3514
  spProgress.Percent := 100;
3458
    Tree: TVirtualStringTree;
3515
end;
3459
  begin
3460
    GetActiveTree(Tree);
3516
3461
3517
procedure TfrmMain.DownloadBooks;
3462
    FillBookIdList(Tree, BookIDList);
3518
var
3463
    unit_ExportToDevice.DownloadBooks(dmCollection.ActiveTable, BookIDList);
3519
  BookIDList: TBookIdList;
3520
  Tree: TVirtualStringTree;
3521
begin
3522
  GetActiveTree(Tree);
3523
3464
3524
  FillBookIdList(Tree, BookIDList);
3465
    RefreshBooksState(Tree, BookIDList);
3525
  unit_ExportToDevice.DownloadBooks(dmCollection.ActiveTable, BookIdList );
3466
  end;
3526
3467
3527
  RefreshBooksState(Tree, BookIDList);
3468
  procedure TfrmMain.tbtbnReadClick(Sender: TObject);
3528
end;
3469
  var
3470
    WorkFile: string;
3471
    Tree: TVirtualStringTree;
3472
    Cover: TMHLCoverPanel;
3473
    Panel: TMHLInfoPanel;
3474
    No: Integer;
3475
    Data: PBookData;
3529
3476
3530
procedure TfrmMain.tbtbnReadClick(Sender: TObject);
3477
    FS: TMemoryStream;
3531
var
3478
    Zip: TZipForge;
3532
  WorkFile: String;
3479
    ID, i: Integer;
3533
  Tree: TVirtualStringTree;
3534
  Cover: TMHLCoverPanel;
3535
  Panel: TMHLInfoPanel;
3536
  No: integer;
3537
  Data: PBookData;
3538
3480
3539
  fs: TMemoryStream;
3481
    FileName, Folder, Ext: string;
3540
  Zip: TZipForge;
3541
  Id,I: integer;
3542
3482
3543
  FileName,Folder,Ext: string;
3544
3545
begin
3546
  GetActiveViewComponents(Tree,Panel,Cover);
3547
  Data := Tree.GetNodeData(Tree.GetFirstSelected);
3548
  if (not Assigned(Data)) then
3549
    Exit;
3550
3551
  if Data.nodeType <> ntBookInfo then
3552
  begin
3483
  begin
3553
    ClearLabels(Tree.Tag, True);
3484
    GetActiveViewComponents(Tree, Panel, Cover);
3554
    Exit;
3485
    Data := Tree.GetNodeData(Tree.GetFirstSelected);
3555
  end;
3486
    if (not Assigned(Data)) then
3487
      Exit;
3556
3488
3557
  Screen.Cursor := crHourGlass;
3489
    if Data.nodeType <> ntBookInfo then
3558
  try
3559
    if ExtractFileExt(Panel.Folder) = ZIP_EXTENSION then
3560
    begin
3490
    begin
3561
      //
3491
      ClearLabels(Tree.tag, True);
3562
      if ActiveView = FavoritesView then
3492
      Exit;
3493
    end;
3494
3495
    Screen.Cursor := crHourGlass;
3496
    try
3497
      if ExtractFileExt(Panel.Folder) = ZIP_EXTENSION then
3563
      begin
3498
      begin
3564
        I := DMUser.tblGrouppedBooksDatabaseID.Value;
3499
        //
3565
        DMUser.tblBases.Locate('ID',I,[]);
3500
        if ActiveView = FavoritesView then
3566
        if isOnlineCollection(DMUser.tblBasesCode.Value) then
3567
        begin
3501
        begin
3568
          DownloadBooks;
3502
          i := DMUser.tblGrouppedBooksDatabaseID.Value;
3569
          if not FileExists(Panel.Folder) then
3503
          DMUser.tblBases.Locate('ID', i, []);
3570
            Exit;
3504
          if isOnlineCollection(DMUser.tblBasesCode.Value) then
3571
        end;
3505
          begin
3572
        Id := DMUser.tblGrouppedBooksOuterId.Value;
3506
            DownloadBooks;
3573
      end   // if ActiveView
3507
            if not FileExists(Panel.Folder) then
3574
      else
3508
              Exit;
3575
      begin
3509
          end;
3576
        if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
3510
          ID := DMUser.tblGrouppedBooksOuterId.Value;
3511
        end // if ActiveView
3512
        else
3577
        begin
3513
        begin
3578
          DownloadBooks;
3514
          if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
3579
          if not FileExists(Panel.Folder) then
3515
          begin
3516
            DownloadBooks;
3517
            if not FileExists(Panel.Folder) then
3580
              Exit; // если файла нет, значит закачка не удалась, и юзер об  этом уже знает
3518
              Exit; // если файла нет, значит закачка не удалась, и юзер об  этом уже знает
3581
3519
3582
        end;
3520
          end;
3583
        Id := Data.ID;
3521
          ID := Data.ID;
3584
      end;  // if .. else
3522
        end; // if .. else
3585
3523
3586
      if not FileExists(Panel.Folder) then
3524
        if not FileExists(Panel.Folder) then
3587
          raise EInvalidOp.Create('Архив ' + Panel.Folder + ' не найден!');
3525
          raise EInvalidOp.Create('Архив ' + Panel.Folder + ' не найден!');
3588
3526
3589
      dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
3527
        dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
3590
3528
3591
      if ActiveView <> FavoritesView then
3529
        if ActiveView <> FavoritesView then
3592
        WorkFile := Settings.ReadPath + Format('%s - %s.%d%s',
3530
          WorkFile := Settings.ReadPath + Format('%s - %s.%d%s', [CheckSymbols(dmCollection.FullName(Data.ID)), CheckSymbols(Panel.Title), ID, Ext])
3593
                                              [CheckSymbols(dmCollection.FullName(Data.ID)),
3531
        else
3594
                                               CheckSymbols(Panel.Title),Id,Ext])
3532
          WorkFile := Settings.ReadPath + Format('%s - %s.%d%s', [CheckSymbols(DMUser.tblGrouppedBooksFullName.Value), CheckSymbols(Panel.Title), ID, Ext]);
3595
      else
3596
         WorkFile := Settings.ReadPath + Format('%s - %s.%d%s',
3597
                                              [CheckSymbols(DMUser.tblGrouppedBooksFullName.Value),
3598
                                               CheckSymbols(Panel.Title),Id,Ext]);
3599
3533
3600
      if not FileExists(WorkFile) then
3534
        if not FileExists(WorkFile) then
3535
        begin
3536
          Zip := TZipForge.Create(nil);
3537
          FS := TMemoryStream.Create;
3538
          try
3539
            Zip.FileName := Panel.Folder;
3540
            Zip.BaseDir := Settings.ReadPath;
3541
            Zip.OpenArchive;
3542
            Zip.ExtractToStream(GetFileNameZip(Zip, No), FS);
3543
            FS.SaveToFile(WorkFile);
3544
          finally
3545
            FS.Free;
3546
            Zip.Free;
3547
          end;
3548
        end; // if Exists
3549
      end
3550
      else if ExtractFileExt(Panel.FileName) = ZIP_EXTENSION then
3601
      begin
3551
      begin
3602
        Zip := TZipForge.Create(nil);
3603
        FS := TMemoryStream.Create;
3604
        try
3605
          Zip.FileName := Panel.Folder;
3606
          Zip.BaseDir := Settings.ReadPath;
3607
          Zip.OpenArchive;
3608
          Zip.ExtractToStream(GetFileNameZip(Zip,No),FS);
3609
          fs.SaveToFile(WorkFile);
3610
        finally
3611
          FS.Free;
3612
          Zip.Free;
3613
        end;
3614
      end; // if Exists
3615
    end
3616
    else
3617
      if ExtractFileExt(Panel.FileName) = ZIP_EXTENSION then
3618
      begin
3619
        dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
3552
        dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
3620
3553
3621
        WorkFile := Settings.ReadPath + Format('%s - %s.%d%s',
3554
        WorkFile := Settings.ReadPath + Format('%s - %s.%d%s', [CheckSymbols(Panel.Author), CheckSymbols(Panel.Title), ID, Ext]);
3622
                                              [CheckSymbols(Panel.Author),
3623
                                               CheckSymbols(Panel.Title),Id,Ext]);
3624
3555
3625
        if not FileExists(WorkFile) then
3556
        if not FileExists(WorkFile) then
3626
        begin
3557
        begin
...
...
3631
            Zip.FileName := Panel.Folder + Panel.FileName;
3562
            Zip.FileName := Panel.Folder + Panel.FileName;
3632
            Zip.BaseDir := Settings.ReadPath;
3563
            Zip.BaseDir := Settings.ReadPath;
3633
            Zip.OpenArchive;
3564
            Zip.OpenArchive;
3634
            WorkFile := GetFileNameZip(Zip,No);
3565
            WorkFile := GetFileNameZip(Zip, No);
3635
            Zip.ExtractToStream(WorkFile,FS);
3566
            Zip.ExtractToStream(WorkFile, FS);
3636
            WorkFile := Settings.ReadPath + WorkFile;
3567
            WorkFile := Settings.ReadPath + WorkFile;
3637
            fs.SaveToFile(WorkFile);
3568
            FS.SaveToFile(WorkFile);
3638
          finally
3569
          finally
3639
            FS.Free;
3570
            FS.Free;
3640
            Zip.Free;
3571
            Zip.Free;
...
...
3645
      else
3576
      else
3646
        WorkFile := Panel.Folder + Panel.FileName;
3577
        WorkFile := Panel.Folder + Panel.FileName;
3647
3578
3648
    if Settings.OverwriteFB2Info and (Ext = FB2_EXTENSION) then WriteFb2InfoToFile(WorkFile);
3579
      if Settings.OverwriteFB2Info and (Ext = FB2_EXTENSION) then
3580
        WriteFb2InfoToFile(WorkFile);
3649
3581
3650
    Settings.Readers.RunReader(WorkFile);
3582
      Settings.Readers.RunReader(WorkFile);
3651
    Tree.RepaintNode(Tree.GetFirstSelected);
3583
      Tree.RepaintNode(Tree.GetFirstSelected);
3652
  finally
3584
    finally
3653
    Screen.Cursor := crDefault;
3585
      Screen.Cursor := crDefault;
3586
    end;
3654
  end;
3587
  end;
3655
end;
3656
3588
3657
procedure TfrmMain.tbtnEngClick(Sender: TObject);
3589
  procedure TfrmMain.tbtnEngClick(Sender: TObject);
3658
begin
3590
  begin
3659
  Settings.ShowEngBar := not Settings.ShowEngBar;
3591
    Settings.ShowEngBar := not Settings.ShowEngBar;
3660
  EngBar.Visible := Settings.ShowEngBar;
3592
    EngBar.Visible := Settings.ShowEngBar;
3661
3593
3662
  SetLangBarSize;
3594
    SetLangBarSize;
3663
end;
3595
  end;
3664
3596
3665
procedure TfrmMain.tbtnRusClick(Sender: TObject);
3597
  procedure TfrmMain.tbtnRusClick(Sender: TObject);
3666
begin
3598
  begin
3667
  Settings.ShowRusBar := not Settings.ShowRusBar;
3599
    Settings.ShowRusBar := not Settings.ShowRusBar;
3668
  RusBar.Visible := Settings.ShowRusBar;
3600
    RusBar.Visible := Settings.ShowRusBar;
3669
3601
3670
  SetLangBarSize;
3602
    SetLangBarSize;
3671
end;
3603
  end;
3672
3604
3605
  procedure TfrmMain.tbtnShowDeletedClick(Sender: TObject);
3606
  begin
3607
    SavePositions;
3673
3608
3674
procedure TfrmMain.tbtnShowDeletedClick(Sender: TObject);
3609
    Settings.DoNotShowDeleted := not Settings.DoNotShowDeleted;
3675
begin
3610
    tbtnShowDeleted.Down := Settings.DoNotShowDeleted;
3676
  SavePositions;
3677
3611
3678
  Settings.DoNotShowDeleted := not Settings.DoNotShowDeleted;
3612
    cbDeleted.Checked := Settings.DoNotShowDeleted;
3679
  tbtnShowDeleted.Down := Settings.DoNotShowDeleted;
3680
3613
3681
  cbDeleted.Checked := Settings.DoNotShowDeleted;
3614
    SetBooksFilter;
3615
    FillAllBooksTree;
3682
3616
3683
  SetBooksFilter;
3617
    RestorePositions;
3684
  FillAllBooksTree;
3618
  end;
3685
3619
3686
  RestorePositions;
3620
  procedure TfrmMain.tbtnStarClick(Sender: TObject);
3687
end;
3688
3621
3689
procedure TfrmMain.tbtnStarClick(Sender: TObject);
3622
  begin
3690
3623
3691
begin
3624
    if (pgControl.ActivePageIndex <> PAGE_AUTHORS) and (pgControl.ActivePageIndex <> PAGE_SERIES) then
3625
      Exit;
3692
3626
3693
  if (pgControl.ActivePageIndex <> PAGE_AUTHORS) and
3627
    Screen.Cursor := crHourGlass;
3694
     (pgControl.ActivePageIndex <> PAGE_SERIES)
3628
    case ActiveView of
3695
  then Exit;
3629
      ByAuthorView:
3630
        begin
3696
3631
3697
  Screen.Cursor := crHourGlass;
3632
          ClearLabels(PAGE_AUTHORS, True);
3698
  case ActiveView of
3633
          if Assigned(FLastLetterA) then
3699
    ByAuthorView:
3700
      begin
3701
3702
        ClearLabels(PAGE_AUTHORS, True);
3703
        if Assigned(FLastLetterA) then
3704
            FLastLetterA.Down := False;
3634
            FLastLetterA.Down := False;
3705
3635
3706
        FLastLetterA := (Sender as TToolButton);
3636
          FLastLetterA := (Sender as TToolButton); (Sender as TToolButton)
3707
        (Sender as TToolButton).Down := True;
3637
          .Down := True;
3708
        if (Sender as TToolButton).Tag >= 90 then
3638
          if (Sender as TToolButton).tag >= 90 then
3709
        case (Sender as TToolButton).Tag of
3639
            case (Sender as TToolButton).tag of
3710
          91: dmCollection.tblAuthors.Filter := 'UPPER(A_Family) >= "А*"';
3640
              91:
3711
          92: dmCollection.tblAuthors.Filter := 'UPPER(A_Family) < "А*"';
3641
                dmCollection.tblAuthors.Filter := 'UPPER(A_Family) >= "А*"';
3712
        end
3642
              92:
3713
        else
3643
                dmCollection.tblAuthors.Filter := 'UPPER(A_Family) < "А*"';
3714
        begin
3644
            end
3715
          edLocateAuthor.Text := (Sender as TToolButton).Caption;
3645
          else
3716
          dmCollection.tblAuthors.Filter := '(A_Family=' + QuotedStr((Sender as TToolButton).Caption + '*') +
3646
          begin
3717
               ') OR (A_Family=' + QuotedStr(AnsiLowercase((Sender as TToolButton).Caption) + '*') + ')';
3647
            edLocateAuthor.text := (Sender as TToolButton).Caption;
3718
        end;
3648
            dmCollection.tblAuthors.Filter := '(A_Family=' + QuotedStr((Sender as TToolButton).Caption + '*') + ') OR (A_Family=' + QuotedStr(AnsiLowercase((Sender as TToolButton).Caption) + '*') + ')';
3719
        dmCollection.tblAuthors.Filtered := (Sender as TToolButton).Tag <> 90;
3649
          end;
3720
        FillAuthorTree(tvAuthors);
3650
          dmCollection.tblAuthors.Filtered := (Sender as TToolButton).tag <> 90;
3651
          FillAuthorTree(tvAuthors);
3721
3652
3722
        //tvAuthors.Selected[tvAuthors.GetFirst] := True;
3653
          // tvAuthors.Selected[tvAuthors.GetFirst] := True;
3723
        edLocateAuthor.Perform(WM_KEYDOWN, VK_RIGHT, 0);
3654
          edLocateAuthor.Perform(WM_KEYDOWN, vk_Right, 0);
3724
      end;
3655
        end;
3725
    BySeriesView:
3656
      BySeriesView:
3726
      begin
3727
        ClearLabels(PAGE_SERIES, True);
3728
        if Assigned(FLastLetterS) then
3729
          FLastLetterS.Down := False;
3730
        FLastLetterS := (Sender as TToolButton);
3731
        (Sender as TToolButton).Down := True;
3732
3733
        if (Sender as TToolButton).Tag >= 90 then
3734
        case (Sender as TToolButton).Tag of
3735
          90: dmCollection.tblSeries.Filter := 'S_Title <>' + QuotedStr(NO_SERIES_TITLE);
3736
          91: dmCollection.tblSeries.Filter := 'UPPER(S_Title) >= "А*"';
3737
          92: dmCollection.tblSeries.Filter := 'UPPER(S_Title) < "A*" and S_Title <>' + QuotedStr(NO_SERIES_TITLE);
3738
        end
3739
        else
3740
        begin
3657
        begin
3741
          edLocateSeries.Text := (Sender as TToolButton).Caption;
3658
          ClearLabels(PAGE_SERIES, True);
3742
          dmCollection.tblSeries.Filter := '(S_Title=' + QuotedStr((Sender as TToolButton).Caption + '*') +
3659
          if Assigned(FLastLetterS) then
3743
               ') OR (S_Title=' + QuotedStr(AnsiLowercase((Sender as TToolButton).Caption) + '*') + ')';
3660
            FLastLetterS.Down := False;
3661
          FLastLetterS := (Sender as TToolButton); (Sender as TToolButton)
3662
          .Down := True;
3663
3664
          if (Sender as TToolButton).tag >= 90 then
3665
            case (Sender as TToolButton).tag of
3666
              90:
3667
                dmCollection.tblSeries.Filter := 'S_Title <>' + QuotedStr(NO_SERIES_TITLE);
3668
              91:
3669
                dmCollection.tblSeries.Filter := 'UPPER(S_Title) >= "А*"';
3670
              92:
3671
                dmCollection.tblSeries.Filter := 'UPPER(S_Title) < "A*" and S_Title <>' + QuotedStr(NO_SERIES_TITLE);
3672
            end
3673
          else
3674
          begin
3675
            edLocateSeries.text := (Sender as TToolButton).Caption;
3676
            dmCollection.tblSeries.Filter := '(S_Title=' + QuotedStr((Sender as TToolButton).Caption + '*') + ') OR (S_Title=' + QuotedStr(AnsiLowercase((Sender as TToolButton).Caption) + '*') + ')';
3677
          end;
3678
          dmCollection.tblSeries.Filtered := True;
3679
          FillSeriesTree;
3680
          tvSeries.Selected[tvSeries.GetFirst] := True;
3681
          edLocateSeries.Perform(WM_KEYDOWN, vk_Right, 0);
3744
        end;
3682
        end;
3745
        dmCollection.tblSeries.Filtered := true;
3683
    end;
3746
        FillSeriesTree;
3684
    Screen.Cursor := crDefault;
3747
        tvSeries.Selected[tvSeries.GetFirst] := True;
3748
        edLocateSeries.Perform(WM_KEYDOWN, VK_RIGHT, 0);
3749
      end;
3750
  end;
3685
  end;
3751
  Screen.Cursor := crDefault;
3752
end;
3753
3686
3754
procedure TfrmMain.TrayIconDblClick(Sender: TObject);
3687
  procedure TfrmMain.TrayIconDblClick(Sender: TObject);
3755
begin
3688
  begin
3756
  Visible := not Visible;
3689
    Visible := not Visible;
3757
  TrayIcon.Visible := not Visible;
3690
    TrayIcon.Visible := not Visible;
3758
end;
3691
  end;
3759
3692
3760
procedure TfrmMain.tbtnShowLocalOnlyClick(Sender: TObject);
3693
  procedure TfrmMain.tbtnShowLocalOnlyClick(Sender: TObject);
3761
begin
3694
  begin
3762
3695
3763
  SavePositions;
3696
    SavePositions;
3764
3697
3765
  Settings.ShowLocalOnly := not Settings.ShowLocalOnly;
3698
    Settings.ShowLocalOnly := not Settings.ShowLocalOnly;
3766
  tbtnShowLocalOnly.Down := Settings.ShowLocalOnly ;
3699
    tbtnShowLocalOnly.Down := Settings.ShowLocalOnly;
3767
3700
3768
  SetAuthorsShowLocalOnly;
3701
    SetAuthorsShowLocalOnly;
3769
  SetSeriesShowLocalOnly;
3702
    SetSeriesShowLocalOnly;
3770
  SetBooksFilter;
3703
    SetBooksFilter;
3771
3704
3772
  FillAuthorTree(tvAuthors);
3705
    FillAuthorTree(tvAuthors);
3773
  FillSeriesTree;
3706
    FillSeriesTree;
3774
  FillAllBooksTree;
3707
    FillAllBooksTree;
3775
3708
3776
  RestorePositions;
3709
    RestorePositions;
3777
end;
3710
  end;
3778
3711
3779
procedure TfrmMain.SetCoversVisible(State: boolean);
3712
  procedure TfrmMain.SetCoversVisible(State: Boolean);
3780
begin
3713
  begin
3781
  cpCoverA.Visible := State;
3714
    cpCoverA.Visible := State;
3782
  cpCoverS.Visible := State;
3715
    cpCoverS.Visible := State;
3783
  cpCoverG.Visible := State;
3716
    cpCoverG.Visible := State;
3784
  cpCoverF.Visible := State;
3717
    cpCoverF.Visible := State;
3785
  cpCoverSR.Visible := State;
3718
    cpCoverSR.Visible := State;
3786
end;
3719
  end;
3787
3720
3788
procedure TfrmMain.tbtnShowCoverClick(Sender: TObject);
3721
  procedure TfrmMain.tbtnShowCoverClick(Sender: TObject);
3789
var
3722
  var
3790
  Visible: boolean;
3723
    Visible: Boolean;
3791
begin
3724
  begin
3792
  Settings.ShowInfoPanel := not Settings.ShowInfoPanel;
3725
    Settings.ShowInfoPanel := not Settings.ShowInfoPanel;
3793
3726
3794
//  Visible := (Settings.ShowInfoPanel and not isNonFb2Collection(DMUser.ActiveCollection.CollectionType)
3727
    // Visible := (Settings.ShowInfoPanel and not isNonFb2Collection(DMUser.ActiveCollection.CollectionType)
3795
//             or (Settings.ShowInfoPanel and isNonFB2Collection(DMUser.ActiveCollection.CollectionType)
3728
    // or (Settings.ShowInfoPanel and isNonFB2Collection(DMUser.ActiveCollection.CollectionType)
3796
//                 and Settings.AllowMixed));
3729
    // and Settings.AllowMixed));
3797
3730
3798
  Visible :=  Settings.ShowInfoPanel;
3731
    Visible := Settings.ShowInfoPanel;
3799
3732
3800
  SetCoversVisible(Visible);
3733
    SetCoversVisible(Visible);
3801
  if Visible then
3734
    if Visible then
3802
        tvBooksTreeChange(Nil,Nil);
3735
      tvBooksTreeChange(nil, nil);
3803
end;
3736
  end;
3804
3737
3805
procedure TfrmMain.tbClearEdAuthorClick(Sender: TObject);
3738
  procedure TfrmMain.tbClearEdAuthorClick(Sender: TObject);
3806
begin
3739
  begin
3807
  edLocateAuthor.Clear;
3740
    edLocateAuthor.Clear;
3808
  frmMain.ActiveControl := edLocateAuthor;
3741
    frmMain.ActiveControl := edLocateAuthor;
3809
end;
3742
  end;
3810
3743
3811
procedure TfrmMain.tbCollapseClick(Sender: TObject);
3744
  procedure TfrmMain.tbCollapseClick(Sender: TObject);
3812
var
3745
  var
3813
  Tree: TVirtualStringTree;
3746
    Tree: TVirtualStringTree;
3814
begin
3747
  begin
3815
  GetActiveTree(Tree);
3748
    GetActiveTree(Tree);
3816
  if Tree.Expanded[Tree.GetFirst] then
3749
    if Tree.Expanded[Tree.GetFirst] then
3817
    Tree.FullCollapse(nil)
3750
      Tree.FullCollapse(nil)
3818
  else
3751
    else
3819
    Tree.FullExpand(nil);
3752
      Tree.FullExpand(nil);
3820
end;
3753
  end;
3821
3754
3822
function TfrmMain.GetViewTree(view: TView): TVirtualStringTree;
3755
  function TfrmMain.GetViewTree(view: TView): TVirtualStringTree;
3823
begin
3756
  begin
3824
  case view of
3757
    case view of
3825
    ByAuthorView: Result := tvBooksA;
3758
      ByAuthorView:
3826
    BySeriesView: Result := tvBooksS;
3759
        Result := tvBooksA;
3827
    ByGenreView: Result := tvBooksG;
3760
      BySeriesView:
3828
    SearchView: Result := tvBooksSR;
3761
        Result := tvBooksS;
3829
    FavoritesView: Result := tvBooksF;
3762
      ByGenreView:
3830
  else
3763
        Result := tvBooksG;
3831
    begin
3764
      SearchView:
3832
      Assert(False, 'Проверить использование, возможна ошибка');
3765
        Result := tvBooksSR;
3833
      Result := nil;
3766
      FavoritesView:
3767
        Result := tvBooksF;
3768
    else
3769
      begin
3770
        Assert(False, 'Проверить использование, возможна ошибка');
3771
        Result := nil;
3772
      end;
3834
    end;
3773
    end;
3835
  end;
3774
  end;
3836
end;
3837
3775
3838
procedure TfrmMain.GroupMenuItemClick(Sender: TObject);
3776
  procedure TfrmMain.GroupMenuItemClick(Sender: TObject);
3839
begin
3777
  begin
3840
  if DMUser.ActivateGroup((Sender as TMenuItem).Tag) then
3778
    if DMUser.ActivateGroup((Sender as TMenuItem).tag) then
3841
        miAddFavoritesClick(Sender);
3779
      miAddFavoritesClick(Sender);
3842
end;
3780
  end;
3843
3781
3844
procedure TfrmMain.GetActiveTree(var Tree: TVirtualStringTree);
3782
  procedure TfrmMain.GetActiveTree(var Tree: TVirtualStringTree);
3845
begin
3846
  Tree := GetViewTree(ActiveView);
3847
end;
3848
3849
procedure TfrmMain.Selection(SelState: boolean);
3850
var
3851
  Node: PVirtualNode;
3852
  tree: TVirtualStringTree;
3853
begin
3854
  GetActiveTree(Tree);
3855
  Tree.BeginUpdate;
3856
  Node := Tree.GetFirst;
3857
  while Assigned(Node) do
3858
  begin
3783
  begin
3859
    if SelState then
3784
    Tree := GetViewTree(ActiveView);
3860
      Node.CheckState := csCheckedNormal
3861
    else
3862
      Node.CheckState := csUnCheckedNormal;
3863
    Node := Tree.GetNext(Node);
3864
  end;
3785
  end;
3865
  Tree.EndUpdate;
3866
end;
3867
3786
3868
procedure TfrmMain.SelectNextBook(Changed, Frwrd: boolean);
3787
  procedure TfrmMain.Selection(SelState: Boolean);
3869
var
3788
  var
3870
  Tree : TVirtualstringTree;
3789
    Node: PVirtualNode;
3871
  NewNode, OldNode : PVirtualNode;
3790
    Tree: TVirtualStringTree;
3872
  Data : PBookData;
3791
  begin
3873
begin
3792
    GetActiveTree(Tree);
3874
  if Changed then SaveFb2DataAfterEdit(FLastBookRecord);
3793
    Tree.BeginUpdate;
3875
  GetActiveTree(Tree);
3794
    Node := Tree.GetFirst;
3876
  repeat
3795
    while Assigned(Node) do
3877
    OldNode := Tree.GetFirstSelected;
3878
    if Frwrd then
3879
    begin
3796
    begin
3880
      NewNode := Tree.GetNext(OldNode);
3797
      if SelState then
3881
      if NewNode = Nil then NewNode := Tree.GetFirst;
3798
        Node.CheckState := csCheckedNormal
3882
    end
3799
      else
3883
    else
3800
        Node.CheckState := csUncheckedNormal;
3884
    begin
3801
      Node := Tree.GetNext(Node);
3885
      NewNode := Tree.GetPrevious(OldNode);
3886
      if NewNode = Nil then NewNode := Tree.GetLast;
3887
    end;
3802
    end;
3888
    Tree.Selected[OldNode] := False;
3803
    Tree.EndUpdate;
3889
    Tree.Selected[NewNode] := True;
3804
  end;
3890
    Data := Tree.GetNodeData(NewNode);
3891
    FLastActiveBookID := Data.ID;
3892
  until Data.nodeType = ntBookInfo;
3893
  PrepareFb2EditData(Data, FLastBookRecord);
3894
end;
3895
3805
3896
procedure TfrmMain.tbSelectAllClick(Sender: TObject);
3806
  procedure TfrmMain.SelectNextBook(Changed, Frwrd: Boolean);
3897
begin
3807
  var
3898
  FSelectionState := not FSelectionState;
3808
    Tree: TVirtualStringTree;
3899
  Selection(FSelectionState);
3809
    NewNode, OldNode: PVirtualNode;
3900
end;
3810
    Data: PBookData;
3901
3811
  begin
3902
//- - - - - - Дерево книг для поиска, серий и избранного - - - - - - - - - - - -
3812
    if Changed then
3903
3813
      SaveFb2DataAfterEdit(FLastBookRecord);
3904
procedure TfrmMain.FillBooksTree(
3814
    GetActiveTree(Tree);
3905
  const ParentID: Integer;
3815
    repeat
3906
  const Tree: TVirtualStringTree;
3816
      OldNode := Tree.GetFirstSelected;
3907
  const Master: TDataset;
3817
      if Frwrd then
3908
  const Detail: TDataset;
3909
  ShowAuth: Boolean;
3910
  ShowSer: Boolean
3911
  );
3912
var
3913
  Data: PBookData;
3914
  authorNode: PVirtualNode;
3915
  seriesNode: PVirtualNode;
3916
  bookNode: PVirtualNode;
3917
  LastSeries: PVirtualNode;
3918
  Max, i: Integer;
3919
  DBCode: COLLECTION_TYPE;
3920
  TableA: TDataSet;
3921
  TableB: TDataSet;
3922
  Auth, LastAuth: String;
3923
  CollectionName: String;
3924
  Columns: TColumnSet;
3925
3926
      function GetColumns: TColumnSet;
3927
      var
3928
        i: integer;
3929
      begin
3818
      begin
3930
        Result := [];
3819
        NewNode := Tree.GetNext(OldNode);
3931
        for I := 0 to Tree.Header.Columns.Count - 1 do
3820
        if NewNode = nil then
3932
          Include(Result,Tree.Header.Columns[i].Tag);
3821
          NewNode := Tree.GetFirst;
3822
      end
3823
      else
3824
      begin
3825
        NewNode := Tree.GetPrevious(OldNode);
3826
        if NewNode = nil then
3827
          NewNode := Tree.GetLast;
3933
      end;
3828
      end;
3829
      Tree.Selected[OldNode] := False;
3830
      Tree.Selected[NewNode] := True;
3831
      Data := Tree.GetNodeData(NewNode);
3832
      FLastActiveBookID := Data.ID;
3833
    until Data.nodeType = ntBookInfo;
3834
    PrepareFb2EditData(Data, FLastBookRecord);
3835
  end;
3934
3836
3837
  procedure TfrmMain.tbSelectAllClick(Sender: TObject);
3838
  begin
3839
    FSelectionState := not FSelectionState;
3840
    Selection(FSelectionState);
3841
  end;
3935
3842
3936
begin
3843
  // - - - - - - Дерево книг для поиска, серий и избранного - - - - - - - - - - - -
3937
  if Assigned(Master) then
3938
    TableA := Master
3939
  else
3940
    TableA := Detail;
3941
3844
3942
  Columns := GetColumns;
3845
  procedure TfrmMain.FillBooksTree(const ParentID: Integer; const Tree: TVirtualStringTree; const Master: TDataset; const Detail: TDataset; ShowAuth: Boolean; ShowSer: Boolean);
3943
  spProgress.Visible := True;  
3846
  var
3944
  TableB := Detail;
3847
    Data: PBookData;
3848
    authorNode: PVirtualNode;
3849
    seriesNode: PVirtualNode;
3850
    bookNode: PVirtualNode;
3851
    LastSeries: PVirtualNode;
3852
    Max, i: Integer;
3853
    DBCode: COLLECTION_TYPE;
3854
    TableA: TDataset;
3855
    TableB: TDataset;
3856
    Auth, LastAuth: string;
3857
    CollectionName: string;
3858
    Columns: TColumnSet;
3945
3859
3946
  // Если включен "плоский" режим отображения, принудительно сбрасываем ключи
  // блокировки
  if Settings.TreeModes[Tree.Tag] = tmFlat then
3860
    function GetColumns: TColumnSet;
3861
    var
3862
      i: Integer;
3863
    begin
3864
      Result := [];
3865
      for i := 0 to Tree.Header.Columns.Count - 1 do
3866
        Include(Result, Tree.Header.Columns[i].tag);
3867
    end;
3868
3947
  begin
3869
  begin
3948
    ShowAuth := False;
3870
    if Assigned(Master) then
3949
    ShowSer  := False;
3871
      TableA := Master
3950
  end;
3872
    else
3873
      TableA := Detail;
3951
3874
3952
  DBCode := DMUser.ActiveCollection.CollectionType;
3875
    Columns := GetColumns;
3953
  LastAuth := '';
3876
    spProgress.Visible := True;
3954
  LastSeries := nil;
3877
    TableB := Detail;
3955
3878
3956
  BookTreeStatus := bsBusy;
3879
    // Если включен "плоский" режим отображения, принудительно сбрасываем ключи
    // блокировки
    if Settings.TreeModes[Tree.tag] = tmFlat then
3957
  try
3880
    begin
3958
    Tree.BeginUpdate;
3881
      ShowAuth := False;
3882
      ShowSer := False;
3883
    end;
3884
3885
    DBCode := DMUser.ActiveCollection.CollectionType;
3886
    LastAuth := '';
3887
    LastSeries := nil;
3888
3889
    BookTreeStatus := bsBusy;
3959
    try
3890
    try
3960
      Tree.Clear;
3891
      Tree.BeginUpdate;
3961
      Tree.NodeDataSize := SizeOf(TBookData);
3962
      Screen.Cursor := crHourGlass;
3963
      try
3892
      try
3964
        spStatus.Caption := 'Построение списка ...';
3893
        Tree.Clear;
3965
3894
        Tree.NodeDataSize := SizeOf(TBookData);
3966
        i := 0;
3895
        Screen.Cursor := crHourGlass;
3967
        try
3896
        try
3968
          TableB.DisableControls;
3897
          spStatus.Caption := 'Построение списка ...';
3898
3899
          i := 0;
3969
          try
3900
          try
3970
            Max := TableA.RecordCount;
3901
            TableB.DisableControls;
3902
            try
3903
              Max := TableA.RecordCount;
3971
3904
3972
            TableA.First;
3905
              TableA.First;
3973
            while not TableA.Eof do
3906
              while not TableA.Eof do
3974
            begin
3975
              //
3976
              // для этой записи в мастере нет книг, переходим к следующей записе
              //
3977
              if TableB.IsEmpty then
3978
              begin
3907
              begin
3979
                TableA.Next;
3908
                //
3980
                Continue;
3909
                // для этой записи в мастере нет книг, переходим к следующей записе
                //
3981
              end;
3910
                if TableB.IsEmpty then
3911
                begin
3912
                  TableA.Next;
3913
                  Continue;
3914
                end;
3982
3915
3983
              // обрабатываемое дерево не обязательно находится на активной вкладке!
3916
                // обрабатываемое дерево не обязательно находится на активной вкладке!
3984
              // это относится ко всем последующим проверкам
3917
                // это относится ко всем последующим проверкам
3985
              if Tree.Tag = 4 then
3918
                if Tree.tag = 4 then
3986
              begin
3919
                begin
3987
                if DMUser.ActivateCollection(TableB.FieldByName('DatabaseId').AsInteger) then
3920
                  if DMUser.ActivateCollection(TableB.FieldByName('DatabaseId').AsInteger) then
3988
                  CollectionName := DMUser.ActiveCollection.Name
3921
                    CollectionName := DMUser.ActiveCollection.name
3989
                else
3922
                  else
3990
                  CollectionName := 'неизвестная коллекция';
3923
                    CollectionName := 'неизвестная коллекция';
3991
              end;
3924
                end;
3992
3925
3993
              if Tree.Tag <> 4 then
3926
                if Tree.tag <> 4 then
3994
                 // Auth := dmCollection.FullName(TableB.FieldByName('Id').AsInteger)
3927
                  // Auth := dmCollection.FullName(TableB.FieldByName('Id').AsInteger)
3995
                 Auth := dmCollection.FullAuthorsString(TableB.FieldByName('Id').AsInteger)
3928
                  Auth := dmCollection.FullAuthorsString(TableB.FieldByName('Id').AsInteger)
3996
              else
3929
                else
3997
                  Auth := TableB.FieldByName('FullName').AsString;
3930
                  Auth := TableB.FieldByName('FullName').AsString;
3998
3931
3999
              if ShowAuth then
3932
                if ShowAuth then
4000
              begin
4001
                if LastAuth <> Auth then
4002
                begin
3933
                begin
4003
                  authorNode := Tree.AddChild(nil);
3934
                  if LastAuth <> Auth then
4004
                  Data := Tree.GetNodeData(authorNode);
3935
                  begin
4005
                  Data.nodeType := ntAuthorInfo;
3936
                    authorNode := Tree.AddChild(nil);
4006
                  Data.FullName := Auth;
3937
                    Data := Tree.GetNodeData(authorNode);
4007
                  LastAuth := Auth;
3938
                    Data.nodeType := ntAuthorInfo;
4008
                  LastSeries := nil;
3939
                    Data.FullName := Auth;
4009
                  if Tree.Tag = 4 then Data.ColName := CollectionName;
3940
                    LastAuth := Auth;
4010
                 end;
3941
                    LastSeries := nil;
4011
              end
3942
                    if Tree.tag = 4 then
4012
              else
3943
                      Data.ColName := CollectionName;
4013
                authorNode := nil;
3944
                  end;
4014
3945
                end
4015
              if ShowSer then
4016
              begin
4017
                if TableB.FieldByName('SerID').AsInteger = 1 then
4018
                  seriesNode := authorNode
4019
                else
3946
                else
4020
                begin
3947
                  authorNode := nil;
4021
                  seriesNode := FindSeriesInTree(Tree, authorNode, TableB.FieldByName('SerID').AsInteger);
4022
3948
4023
                  if not Assigned(seriesNode) then
3949
                if ShowSer then
3950
                begin
3951
                  if TableB.FieldByName('SerID').AsInteger = 1 then
3952
                    seriesNode := authorNode
3953
                  else
4024
                  begin
3954
                  begin
4025
                    if ShowAuth then
3955
                    seriesNode := FindSeriesInTree(Tree, authorNode, TableB.FieldByName('SerID').AsInteger);
3956
3957
                    if not Assigned(seriesNode) then
4026
                    begin
3958
                    begin
4027
                      if Assigned(LastSeries) then
3959
                      if ShowAuth then
4028
                        seriesNode := Tree.InsertNode(LastSeries, amInsertAfter)
3960
                      begin
3961
                        if Assigned(LastSeries) then
3962
                          seriesNode := Tree.InsertNode(LastSeries, amInsertAfter)
3963
                        else
3964
                          seriesNode := Tree.InsertNode(authorNode, amAddChildFirst);
3965
                      end
3966
                      else if not Assigned(LastSeries) then
3967
                        seriesNode := Tree.InsertNode(Tree.GetFirst, amInsertBefore)
4029
                      else
3968
                      else
4030
                        seriesNode := Tree.InsertNode(authorNode, amAddChildFirst);
3969
                        seriesNode := Tree.InsertNode(LastSeries, amInsertAfter);
4031
                    end
4032
                    else if not Assigned(LastSeries) then
4033
                      seriesNode := Tree.InsertNode(Tree.GetFirst, amInsertBefore)
4034
                    else
4035
                      seriesNode := Tree.InsertNode(LastSeries, amInsertAfter);
4036
3970
4037
                    Data := Tree.GetNodeData(seriesNode);
3971
                      Data := Tree.GetNodeData(seriesNode);
4038
                    Data.nodeType := ntSeriesInfo;
3972
                      Data.nodeType := ntSeriesInfo;
4039
                    Data.Series := TableB.FieldByName('Series').AsString;
3973
                      Data.Series := TableB.FieldByName('Series').AsString;
4040
                    Data.SeriesID := TableB.FieldByName('SerID').AsInteger;
3974
                      Data.SeriesID := TableB.FieldByName('SerID').AsInteger;
4041
3975
4042
                    LastSeries := seriesNode;
3976
                      LastSeries := seriesNode;
3977
                    end;
4043
                  end;
3978
                  end;
4044
                end;
3979
                end
4045
              end
3980
                else
4046
              else
3981
                  seriesNode := authorNode;
4047
                seriesNode := authorNode;
4048
3982
4049
              bookNode := Tree.AddChild(seriesNode);
3983
                bookNode := Tree.AddChild(seriesNode);
4050
              Data := Tree.GetNodeData(bookNode);
3984
                Data := Tree.GetNodeData(bookNode);
4051
              Data.ID := TableB.FieldByName('ID').AsInteger;
3985
                Data.ID := TableB.FieldByName('ID').AsInteger;
4052
              Data.Title := TableB.FieldByName('Title').AsString;
3986
                Data.Title := TableB.FieldByName('Title').AsString;
4053
              Data.Series := TableB.FieldByName('Series').AsString;
3987
                Data.Series := TableB.FieldByName('Series').AsString;
4054
3988
4055
              Data.FullName := Auth;
3989
                Data.FullName := Auth;
4056
              Data.Progress := TableB.FieldByName('Progress').AsInteger;
3990
                Data.Progress := TableB.FieldByName('Progress').AsInteger;
4057
              Data.Code := TableB.FieldByName('Code').AsInteger;
3991
                Data.Code := TableB.FieldByName('Code').AsInteger;
4058
3992
4059
              if (COL_NO) in Columns then Data.No := TableB.FieldByName('SeqNumber').AsInteger;
3993
                if (COL_NO) in Columns then
3994
                  Data.No := TableB.FieldByName('SeqNumber').AsInteger;
4060
3995
4061
              if (COL_SIZE in Columns) then Data.Size := TableB.FieldByName('Size').AsInteger;
3996
                if (COL_SIZE in Columns) then
3997
                  Data.Size := TableB.FieldByName('Size').AsInteger;
4062
3998
4063
              if (COL_DATE in Columns) then Data.Date := TableB.FieldByName('Date').AsDateTime;
3999
                if (COL_DATE in Columns) then
4000
                  Data.Date := TableB.FieldByName('Date').AsDateTime;
4064
4001
4065
              if (COL_TYPE in Columns) then
4002
                if (COL_TYPE in Columns) then
4066
              begin
4003
                begin
4067
                Data.FileType := TableB.FieldByName('Ext').AsString;
4004
                  Data.FileType := TableB.FieldByName('Ext').AsString;
4068
                Delete(Data.FileType,1,1);
4005
                  Delete(Data.FileType, 1, 1);
4069
              end;
4006
                end;
4070
4007
4071
              if (COL_COLLECTION in Columns) then Data.ColName := CollectionName;
4008
                if (COL_COLLECTION in Columns) then
4009
                  Data.ColName := CollectionName;
4072
4010
4073
              if Tree.Tag <> 4 then
4011
                if Tree.tag <> 4 then
4074
                  Data.Genre := dmCollection.GetBookGenres(TableB.FieldByName('ID').AsInteger,False)
4012
                  Data.Genre := dmCollection.GetBookGenres(TableB.FieldByName('ID').AsInteger, False)
4075
                else
4013
                else
4076
                  Data.Genre := TableB.FieldByName('Genres').AsString;
4014
                  Data.Genre := TableB.FieldByName('Genres').AsString;
4077
4015
4078
              if (COL_SERIES in Columns) and (TableB.FieldByName('SerID').AsInteger <> 1) then
4016
                if (COL_SERIES in Columns) and (TableB.FieldByName('SerID').AsInteger <> 1) then
4079
                Data.Series := TableB.FieldByName('Series').AsString;
4017
                  Data.Series := TableB.FieldByName('Series').AsString;
4080
4018
4081
              if isOnlineCollection(DBCode) and not TableB.FieldByName('Local').IsNull then
4019
                if isOnlineCollection(DBCode) and not TableB.FieldByName('Local').IsNull then
4082
                Data.Locale := TableB.FieldByName('Local').AsBoolean;
4020
                  Data.Locale := TableB.FieldByName('Local').AsBoolean;
4083
4021
4084
              if (COL_RATE in Columns) and (not TableB.FieldByName('Rate').IsNull) then
4022
                if (COL_RATE in Columns) and (not TableB.FieldByName('Rate').IsNull) then
4085
                Data.Rate := TableB.FieldByName('Rate').AsInteger;
4023
                  Data.Rate := TableB.FieldByName('Rate').AsInteger;
4086
4024
4087
              if (COL_LANG in Columns) and (not TableB.FieldByName('Lang').IsNull) then
4025
                if (COL_LANG in Columns) and (not TableB.FieldByName('Lang').IsNull) then
4088
                Data.Lang := TableB.FieldByName('Lang').AsString;
4026
                  Data.Lang := TableB.FieldByName('Lang').AsString;
4089
4027
4090
              if (COL_LIBRATE in Columns) and (not TableB.FieldByName('LibRate').IsNull) then
4028
                if (COL_LibRate in Columns) and (not TableB.FieldByName('LibRate').IsNull) then
4091
                Data.LibRate := TableB.FieldByName('LibRate').AsInteger;
4029
                  Data.LibRate := TableB.FieldByName('LibRate').AsInteger;
4092
4030
4093
              Data.Deleted := TableB.FieldByName('Deleted').Value;
4031
                Data.Deleted := TableB.FieldByName('Deleted').Value;
4094
4032
4095
              Data.nodeType := ntBookInfo;
4033
                Data.nodeType := ntBookInfo;
4096
4034
4097
              Inc(i);
4035
                inc(i);
4098
              spProgress.Percent := i * 100 div Max;
4036
                spProgress.Percent := i * 100 div Max;
4099
4037
4100
              TableA.Next;
4038
                TableA.Next;
4101
            end; //while
4039
              end; // while
4102
4040
4103
            Tree.FullExpand();
4041
              Tree.FullExpand();
4104
4042
4105
            if ShowSer then
4043
              if ShowSer then
4106
            begin
4107
              authorNode := Tree.GetFirst;
4108
              while Assigned(authorNode) do
4109
              begin
4044
              begin
4110
                Data := Tree.GetNodeData(authorNode);
4045
                authorNode := Tree.GetFirst;
4111
                if Data.nodeType = ntSeriesInfo then
4046
                while Assigned(authorNode) do
4112
                  SortChild(Tree, authorNode);
4047
                begin
4048
                  Data := Tree.GetNodeData(authorNode);
4049
                  if Data.nodeType = ntSeriesInfo then
4050
                    SortChild(Tree, authorNode);
4113
4051
4114
                if (Data.nodeType = ntAuthorInfo) and (authorNode.ChildCount = 0) then
4052
                  if (Data.nodeType = ntAuthorInfo) and (authorNode.ChildCount = 0) then
4115
                  Tree.DeleteNode(authorNode, True); { TODO -oNickR -cBug : при удалении ноды поведение GetNext неочевидно }
4053
                    Tree.DeleteNode(authorNode, True); { TODO -oNickR -cBug : при удалении ноды поведение GetNext неочевидно }
4116
4054
4117
                authorNode := Tree.GetNext(authorNode);
4055
                  authorNode := Tree.GetNext(authorNode);
4056
                end;
4118
              end;
4057
              end;
4119
            end;
4120
4058
4121
            case Tree.Tag of
4059
              case Tree.tag of
4122
              0: lblBooksTotalA.Caption := Format('(%d)', [i]);
4060
                0:
4123
              1: lblBooksTotalS.Caption := Format('(%d)', [i]);
4061
                  lblBooksTotalA.Caption := Format('(%d)', [i]);
4124
              2: lblBooksTotalG.Caption := Format('(%d)', [i]);
4062
                1:
4125
              4: lblBooksTotalF.Caption := Format('(%d)', [i]);
4063
                  lblBooksTotalS.Caption := Format('(%d)', [i]);
4126
              3: lblTotalBooksFL.Caption := Format('(%d)', [i]);
4064
                2:
4127
            end;
4065
                  lblBooksTotalG.Caption := Format('(%d)', [i]);
4066
                4:
4067
                  lblBooksTotalF.Caption := Format('(%d)', [i]);
4068
                3:
4069
                  lblTotalBooksFL.Caption := Format('(%d)', [i]);
4070
              end;
4128
4071
4129
          finally
4072
            finally
4130
            spProgress.Percent := 100;
4073
              spProgress.Percent := 100;
4131
            spProgress.Visible := False;
4074
              spProgress.Visible := False;
4132
            spStatus.Caption := 'Готово';
4075
              spStatus.Caption := 'Готово';
4133
            DMUser.ActivateCollection(Settings.ActiveCollection);
4076
              DMUser.ActivateCollection(Settings.ActiveCollection);
4134
4077
4135
            if (Settings.TreeModes[Tree.Tag] = tmFlat) then
4078
              if (Settings.TreeModes[Tree.tag] = tmFlat) then
4136
                  Tree.SortTree(FSortSettings[Tree.Tag].Column, FSortSettings[Tree.Tag].Direction);
4079
                Tree.SortTree(FSortSettings[Tree.tag].Column, FSortSettings[Tree.tag].Direction);
4080
            end;
4081
          finally
4082
            TableB.EnableControls;
4137
          end;
4083
          end;
4138
        finally
4084
        finally
4139
          TableB.EnableControls;
4085
          Screen.Cursor := crDefault;
4140
        end;
4086
        end;
4141
      finally
4087
      finally
4142
        Screen.Cursor := crDefault;
4088
        Tree.EndUpdate;
4143
      end;
4089
      end;
4144
    finally
4090
    finally
4145
      Tree.EndUpdate;
4091
      BookTreeStatus := bsFree;
4146
    end;
4092
    end;
4147
  finally
4148
    BookTreeStatus := bsFree;
4149
  end;
4093
  end;
4150
end;
4151
4094
4152
procedure TfrmMain.miCopyAuthorClick(Sender: TObject);
4095
  procedure TfrmMain.miCopyAuthorClick(Sender: TObject);
4153
var
4096
  var
4154
  treeView: TVirtualStringTree;
4097
    treeView: TVirtualStringTree;
4155
4098
4156
  Data: PAuthorData;
4099
    Data: PAuthorData;
4157
  DataG: PGenreData;
4100
    DataG: PGenreData;
4158
  strText: String;
4101
    strText: string;
4159
4102
4160
  Node: PVirtualNode;
4103
    Node: PVirtualNode;
4161
4104
4162
begin
4105
  begin
4163
  case ActiveView of
4106
    case ActiveView of
4164
    ByAuthorView: treeView := tvAuthors;
4107
      ByAuthorView:
4165
    BySeriesView: treeView := tvSeries;
4108
        treeView := tvAuthors;
4166
    ByGenreView: treeView := tvGenres;
4109
      BySeriesView:
4167
  else
4110
        treeView := tvSeries;
4168
    Assert(False);
4111
      ByGenreView:
4169
  end;
4112
        treeView := tvGenres;
4113
    else
4114
      Assert(False);
4115
    end;
4170
4116
4171
  strText := '';
4117
    strText := '';
4172
4118
4173
  case ActiveView of
4119
    case ActiveView of
4174
    ByAuthorView, BySeriesView:
4120
      ByAuthorView, BySeriesView:
4175
      begin
4176
        Node := treeView.GetFirstSelected;
4177
        while Node <> nil do
4178
        begin
4121
        begin
4179
          Data := treeView.GetNodeData(Node);
4122
          Node := treeView.GetFirstSelected;
4180
          if strText = '' then
4123
          while Node <> nil do
4181
            strText := Data.Text
4124
          begin
4182
          else
4125
            Data := treeView.GetNodeData(Node);
4183
            strText := strText + #13#10+ Data.Text;
4126
            if strText = '' then
4184
          Node := treeView.GetNextSelected(Node);
4127
              strText := Data.text
4128
            else
4129
              strText := strText + #13#10 + Data.text;
4130
            Node := treeView.GetNextSelected(Node);
4131
          end;
4185
        end;
4132
        end;
4186
      end;
4187
4133
4188
    ByGenreView:
4134
      ByGenreView:
4189
      begin
4190
        Node := treeView.GetFirstSelected;
4191
        while Node <> nil do
4192
        begin
4135
        begin
4193
          DataG := treeView.GetNodeData(Node);
4136
          Node := treeView.GetFirstSelected;
4194
          if strText = '' then
4137
          while Node <> nil do
4195
            strText := DataG.Text
4138
          begin
4196
          else
4139
            DataG := treeView.GetNodeData(Node);
4197
            strText := strText + #13#10+ DataG.Text;
4140
            if strText = '' then
4198
          Node := treeView.GetNextSelected(Node);
4141
              strText := DataG.text
4142
            else
4143
              strText := strText + #13#10 + DataG.text;
4144
            Node := treeView.GetNextSelected(Node);
4145
          end;
4199
        end;
4146
        end;
4200
      end;
4147
    end;
4148
    Clipboard.AsText := trim(strText);
4201
  end;
4149
  end;
4202
  Clipboard.AsText := trim(strText);
4203
end;
4204
4150
4205
procedure TfrmMain.miCopyClBrdClick(Sender: TObject);
4151
  procedure TfrmMain.miCopyClBrdClick(Sender: TObject);
4206
var
4152
  var
4207
  Tree: TVirtualStringTree;
4153
    Tree: TVirtualStringTree;
4208
  S,R: String;
4154
    S, R: string;
4209
  Data: PBookData;
4155
    Data: PBookData;
4210
  Node: PVirtualNode;
4156
    Node: PVirtualNode;
4211
4157
4212
begin
4158
  begin
4213
  GetActiveTree(Tree);
4159
    GetActiveTree(Tree);
4214
4160
4215
  S := ''; R := '';
4161
    S := '';
4162
    R := '';
4216
4163
4217
  Node := Tree.GetFirstSelected;
4164
    Node := Tree.GetFirstSelected;
4218
  while Node <> Nil do
4165
    while Node <> nil do
4219
  begin
4166
    begin
4220
    Data := Tree.GetNodeData(Node);
4167
      Data := Tree.GetNodeData(Node);
4221
4168
4222
    case Data.nodeType of
4169
      case Data.nodeType of
4223
      ntSeriesInfo:
4170
        ntSeriesInfo:
4224
        S := Data.FullName + '. Серия: ' + Data.Series;
4171
          S := Data.FullName + '. Серия: ' + Data.Series;
4225
4172
4226
      ntBookInfo:
4173
        ntBookInfo:
4227
        if (Data.Series = '---') or (Data.Series = '') then
4174
          if (Data.Series = '---') or (Data.Series = '') then
4228
          S := Data.FullName + '. ' + Data.Title
4175
            S := Data.FullName + '. ' + Data.Title
4229
        else
4176
          else
4230
          S := Data.FullName + '. Серия: ' + Data.Series + '. ' + Data.Title;
4177
            S := Data.FullName + '. Серия: ' + Data.Series + '. ' + Data.Title;
4231
    end;
4178
      end;
4232
    if S = '' then
4179
      if S = '' then
4233
        R := S
4180
        R := S
4234
      else
4181
      else
4235
        R := R + #13#10 + S;
4182
        R := R + #13#10 + S;
4236
4183
4237
    Node := Tree.GetNextSelected(Node);
4184
      Node := Tree.GetNextSelected(Node);
4185
    end;
4186
    Clipboard.AsText := trim(R);
4238
  end;
4187
  end;
4239
  Clipboard.AsText := trim(R);
4240
end;
4241
4188
4242
procedure TfrmMain.miDeleteBookClick(Sender: TObject);
4189
  procedure TfrmMain.miDeleteBookClick(Sender: TObject);
4243
var
4190
  var
4244
  Tree: TVirtualStringTree;
4191
    Tree: TVirtualStringTree;
4245
  Node, OldNode: PvirtualNode;
4192
    Node, OldNode: PVirtualNode;
4246
  Data: PBookData;
4193
    Data: PBookData;
4247
  ALibrary: TMHLLibrary;
4194
    ALibrary: TMHLLibrary;
4248
  FUpdateFavorites: Boolean;
4195
    FUpdateFavorites: Boolean;
4249
4196
4250
  FileName,Folder, Ext: string;
4197
    FileName, Folder, Ext: string;
4251
  No: integer;
4198
    No: Integer;
4252
4199
4253
4254
begin
4255
  FUpdateFavorites := False;
4256
4257
  if ActiveView = FavoritesView then
4258
  begin
4200
  begin
4259
    MessageDlg('Для удаления книги перейдите ' + #13 + 'в соответствующую коллекцию', mtWarning, [mbOk], 0);
4201
    FUpdateFavorites := False;
4260
    Exit;
4261
  end;
4262
4202
4263
  if MessageDlg('Удалить отмеченные книги?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
4203
    if ActiveView = FavoritesView then
4264
    Exit;
4204
    begin
4205
      MessageDlg('Для удаления книги перейдите ' + #13 + 'в соответствующую коллекцию', mtWarning, [mbOk], 0);
4206
      Exit;
4207
    end;
4265
4208
4209
    if MessageDlg('Удалить отмеченные книги?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
4210
      Exit;
4266
4211
4267
  Screen.Cursor := crHourGlass;
4212
    Screen.Cursor := crHourGlass;
4268
  GetActiveTree(Tree);
4213
    GetActiveTree(Tree);
4269
4214
4270
  ALibrary := TMHLLibrary.Create(nil);
4215
    ALibrary := TMHLLibrary.Create(nil);
4271
  try
4216
    try
4272
    ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
4217
      ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
4273
    ALibrary.Active := True;
4218
      ALibrary.Active := True;
4274
4219
4275
    Node := Tree.GetFirst;
4220
      Node := Tree.GetFirst;
4276
    while Assigned(Node) do
4221
      while Assigned(Node) do
4277
    begin
4278
      Data := Tree.GetNodeData(Node);
4279
      Assert(Assigned(Data));
4280
4281
      if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal)
4282
         or (Tree.Selected[Node])) then
4283
      begin
4222
      begin
4284
        dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
4223
        Data := Tree.GetNodeData(Node);
4285
        if (isOnline and Data.Locale)
4224
        Assert(Assigned(Data));
4286
           and DeleteFile(FCollectionRoot + Folder) then dmCollection.SetLocalStatus(Data.ID,False)
4225
4287
        else
4226
        if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
4288
        begin
4227
        begin
4289
          if Settings.DeleteFiles then
4228
          dmCollection.GetBookFileName(Data.ID, FileName, Folder, Ext, No);
4229
          if (IsOnline and Data.Locale) and DeleteFile(FCollectionRoot + Folder) then
4230
            dmCollection.SetLocalStatus(Data.ID, False)
4231
          else
4290
          begin
4232
          begin
4291
            if not isFB2 then
4233
            if Settings.DeleteFiles then
4292
            begin
4234
            begin
4293
              if (ExtractFileExt(FileName) = ZIP_EXTENSION) then
4235
              if not IsFB2 then
4294
                DeleteFile(FCollectionRoot + Folder + FileName)
4236
              begin
4295
              else
4237
                if (ExtractFileExt(FileName) = ZIP_EXTENSION) then
4296
                DeleteFile(FCollectionRoot + Folder + FileName + Ext);
4238
                  DeleteFile(FCollectionRoot + Folder + FileName)
4239
                else
4240
                  DeleteFile(FCollectionRoot + Folder + FileName + Ext);
4241
              end;
4242
4243
              if IsFB2 and IsPrivate then
4244
              begin
4245
                if (ExtractFileExt(Folder) = ZIP_EXTENSION) then
4246
                  DeleteFile(FCollectionRoot + Folder)
4247
                else
4248
                  DeleteFile(FCollectionRoot + Folder + FileName + Ext);
4249
              end;
4297
            end;
4250
            end;
4298
4251
4299
            if isFB2 and isPrivate
4252
            ALibrary.BeginBulkOperation;
4300
            then
4253
            try
4254
              ALibrary.DeleteBook(Data.ID);
4255
              ALibrary.EndBulkOperation(True);
4256
            except
4257
              ALibrary.EndBulkOperation(False);
4258
            end;
4259
4260
            if DMUser.tblGrouppedBooks.Locate('DatabaseID;OuterID', VarArrayOf([Settings.ActiveCollection, Data.ID]), []) then
4301
            begin
4261
            begin
4302
              if (ExtractFileExt(Folder) = ZIP_EXTENSION) then
4262
              DMUser.tblGrouppedBooks.Delete;
4303
                DeleteFile(FCollectionRoot + Folder)
4263
              FUpdateFavorites := True;
4304
              else
4305
                DeleteFile(FCollectionRoot + Folder + FileName + Ext);
4306
            end;
4264
            end;
4265
            DMUser.DeleteExtra(Data.ID);
4307
          end;
4266
          end;
4308
4267
4309
          ALibrary.BeginBulkOperation;
4268
          OldNode := Node;
4310
          try
4269
          Node := Tree.GetNext(Node);
4311
            ALibrary.DeleteBook(Data.ID);
4270
          Tree.DeleteNode(OldNode);
4312
            ALibrary.EndBulkOperation(True);
4271
          ClearLabels(Tree.tag, False);
4313
          except
4314
            ALibrary.EndBulkOperation(False);
4315
          end;
4316
4272
4317
          if DMUser.tblGrouppedBooks.Locate('DatabaseID;OuterID', VarArrayOf([Settings.ActiveCollection, Data.ID]), []) then
4273
        end
4318
          begin
4274
        else
4319
            DMUser.tblGrouppedBooks.Delete;
4275
          Node := Tree.GetNext(Node);
4320
            FUpdateFavorites := True;
4276
      end;
4321
          end;
4277
    finally
4322
          DMUser.DeleteExtra(Data.ID);
4278
      ALibrary.Free;
4323
        end;
4279
      Screen.Cursor := crDefault;
4324
4325
        OldNode := Node;
4326
        Node := Tree.GetNext(Node);
4327
        Tree.DeleteNode(OldNode);
4328
        ClearLabels(Tree.Tag, False);
4329
4330
      end
4331
      else
4332
        Node := Tree.GetNext(Node);
4333
    end;
4280
    end;
4334
  finally
4335
    ALibrary.Free;
4336
    Screen.Cursor := crDefault;
4337
  end;
4281
  end;
4338
end;
4339
4282
4340
procedure TfrmMain.miDeleteColClick(Sender: TObject);
4283
  procedure TfrmMain.miDeleteColClick(Sender: TObject);
4341
begin
4284
  begin
4342
  DMUser.ActivateCollection(Settings.ActiveCollection);
4285
    DMUser.ActivateCollection(Settings.ActiveCollection);
4343
4286
4344
  { TODO -oNickR -cUsability : Думаю, стоит сделать специальный диалог для этого случая. Тогда мы сможем спросить, удалять файл коллекции или нет. }
4287
    { TODO -oNickR -cUsability : Думаю, стоит сделать специальный диалог для этого случая. Тогда мы сможем спросить, удалять файл коллекции или нет. }
4345
  if MessageDlg('Удалить коллекцию "' + DMUser.ActiveCollection.Name + '"?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
4288
    if MessageDlg('Удалить коллекцию "' + DMUser.ActiveCollection.name + '"?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
4346
    Exit;
4289
      Exit;
4347
4290
4348
  DMUser.tblBases.Delete;
4291
    DMUser.tblBases.Delete;
4349
  DMUser.tblBases.First;
4292
    DMUser.tblBases.First;
4350
  Settings.ActiveCollection := DMUser.ActiveCollection.ID;
4293
    Settings.ActiveCollection := DMUser.ActiveCollection.ID;
4351
  InitCollection(True);
4294
    InitCollection(True);
4352
end;
4295
  end;
4353
4296
4354
procedure TfrmMain.miDeleteFilesClick(Sender: TObject);
4297
  procedure TfrmMain.miDeleteFilesClick(Sender: TObject);
4355
var
4298
  var
4356
  Node: PvirtualNode;
4299
    Node: PVirtualNode;
4357
  Data: PBookData;
4300
    Data: PBookData;
4358
  Tree: TVirtualStringTree;
4301
    Tree: TVirtualStringTree;
4359
begin
4360
  GetActiveTree(Tree);
4361
  Node := Tree.GetFirst;
4362
  while Assigned(Node) do
4363
  begin
4302
  begin
4364
    Data := Tree.GetNodeData(Node);
4303
    GetActiveTree(Tree);
4365
4304
    Node := Tree.GetFirst;
4366
    if (Data.nodeType = ntBookInfo) and
4305
    while Assigned(Node) do
4367
       ((tvBooksG.CheckState[Node] = csCheckedNormal) or (tvBooksG.Selected[Node]))
4368
       and Data.Locale then
4369
    begin
4306
    begin
4370
      if dmCollection.tblBooks.Locate('ID',Data.ID,[]) then
4307
      Data := Tree.GetNodeData(Node);
4308
4309
      if (Data.nodeType = ntBookInfo) and ((tvBooksG.CheckState[Node] = csCheckedNormal) or (tvBooksG.Selected[Node])) and Data.Locale then
4371
      begin
4310
      begin
4311
        if dmCollection.tblBooks.Locate('ID', Data.ID, []) then
4312
        begin
4372
4313
4373
        // только для online-коллекции. поэтому получаем путь к файлу по упрощенной схеме
4314
          // только для online-коллекции. поэтому получаем путь к файлу по упрощенной схеме
4374
        try
4315
          try
4375
          DeleteFile(FCollectionRoot + dmCollection.tblBooksFolder.Value);
4316
            DeleteFile(FCollectionRoot + dmCollection.tblBooksFolder.Value);
4376
        except
4317
          except
4377
4318
4378
        end;
4319
          end;
4379
4320
4380
        dmCollection.tblBooks.Edit;
4321
          dmCollection.tblBooks.Edit;
4381
        dmCollection.tblBooksLocal.Value := False;
4322
          dmCollection.tblBooksLocal.Value := False;
4382
        dmCollection.tblBooks.Post;
4323
          dmCollection.tblBooks.Post;
4383
4324
4384
        Data.Locale := False;
4325
          Data.Locale := False;
4385
        tvBooksG.CheckState[Node] := csUnCheckedNormal;
4326
          tvBooksG.CheckState[Node] := csUncheckedNormal;
4386
        Tree.RepaintNode(Node);
4327
          Tree.RepaintNode(Node);
4387
4328
4388
          // синхронизация с избранным
        DMUser.SetLocal(Data.ID, False);
4329
          // синхронизация с избранным
        DMUser.SetLocal(Data.ID, False);
4330
          DMUser.SetLocal(Data.ID, False);
4331
        end;
4389
      end;
4332
      end;
4333
      Node := Tree.GetNext(Node);
4390
    end;
4334
    end;
4391
    Node := Tree.GetNext(Node);
4392
  end;
4335
  end;
4393
end;
4394
4336
4395
procedure TfrmMain.miDelFavoritesClick(Sender: TObject);
4337
  procedure TfrmMain.miDelFavoritesClick(Sender: TObject);
4396
var
4338
  var
4397
  Node: PvirtualNode;
4339
    Node: PVirtualNode;
4398
  Data: PBookData;
4340
    Data: PBookData;
4399
begin
4400
  Node := tvBooksF.GetFirst;
4401
  while Assigned(Node) do
4402
  begin
4341
  begin
4403
    Data := tvBooksF.GetNodeData(Node);
4342
    Node := tvBooksF.GetFirst;
4404
    Assert(Assigned(Data));
4343
    while Assigned(Node) do
4405
    if (Data.nodeType = ntBookInfo) and ((tvBooksG.CheckState[Node] = csCheckedNormal) or (tvBooksG.Selected[Node])) then
4406
    begin
4344
    begin
4407
      DMUser.tblGrouppedBooks.Locate('ID', Data.ID, []);
4345
      Data := tvBooksF.GetNodeData(Node);
4408
      if DMUser.tblExtra.RecordCount <> 0 then DMUser.tblExtra.Delete;
4346
      Assert(Assigned(Data));
4409
      DMUser.tblGrouppedBooks.Delete;
4347
      if (Data.nodeType = ntBookInfo) and ((tvBooksG.CheckState[Node] = csCheckedNormal) or (tvBooksG.Selected[Node])) then
4348
      begin
4349
        DMUser.tblGrouppedBooks.Locate('ID', Data.ID, []);
4350
        if DMUser.tblExtra.RecordCount <> 0 then
4351
          DMUser.tblExtra.Delete;
4352
        DMUser.tblGrouppedBooks.Delete;
4353
      end;
4354
      Node := tvBooksF.GetNext(Node);
4410
    end;
4355
    end;
4411
    Node := tvBooksF.GetNext(Node);
4356
    FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
4357
    ClearLabels(PAGE_FAVORITES, True);
4412
  end;
4358
  end;
4413
  FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
4414
  ClearLabels(PAGE_FAVORITES, True);
4415
end;
4416
4359
4417
function TfrmMain.GetActiveBookTable(tag:integer):TAbsTable;
4360
  function TfrmMain.GetActiveBookTable(tag: Integer): TAbsTable;
4418
begin
4361
  begin
4419
  if Tag = 4 then
4362
    if tag = 4 then
4420
    Result := DMUser.tblGrouppedBooks
4363
      Result := DMUser.tblGrouppedBooks
4421
  else
4364
    else
4422
    Result := dmCollection.tblBooks;
4365
      Result := dmCollection.tblBooks;
4423
end;
4366
  end;
4424
4367
4425
procedure  TfrmMain.RefreshBooksState(Tree: TVirtualStringTree; BookIDList: TBookIdList );
4368
  procedure TfrmMain.RefreshBooksState(Tree: TVirtualStringTree; BookIDList: TBookIdList);
4426
var
4369
  var
4427
  i: integer;
4370
    i: Integer;
4428
  Data: PBookData;
4371
    Data: PBookData;
4429
  Node: PVirtualNode;
4372
    Node: PVirtualNode;
4430
  Max : integer;
4373
    Max: Integer;
4431
begin
4432
  //
4433
  // NickR - надеюсь, больше не нужна
4434
  // { TODO -oNickR -cunused code : удалить }
4435
  //
4436
  Node := Tree.GetFirst;
4437
  i := 0; Max := High(BookIDList);
4438
  while Assigned(Node) do
4439
  begin
4374
  begin
4440
    Data := Tree.GetNodeData(Node);
4375
    //
4441
    if Data.ID = BookIDList[i].ID then
4376
    // NickR - надеюсь, больше не нужна
4377
    // { TODO -oNickR -cunused code : удалить }
4378
    //
4379
    Node := Tree.GetFirst;
4380
    i := 0;
4381
    Max := high(BookIDList);
4382
    while Assigned(Node) do
4442
    begin
4383
    begin
4443
      Data.Locale := BookIDList[i].Res;
4384
      Data := Tree.GetNodeData(Node);
4444
      Tree.RepaintNode(Node);
4385
      if Data.ID = BookIDList[i].ID then
4445
      Inc(i);
4386
      begin
4446
      if i > Max then Break;
4387
        Data.Locale := BookIDList[i].Res;
4388
        Tree.RepaintNode(Node);
4389
        inc(i);
4390
        if i > Max then
4391
          Break;
4392
      end;
4393
      Node := Tree.GetNext(Node);
4447
    end;
4394
    end;
4448
    Node := Tree.GetNext(Node);
4449
  end;
4395
  end;
4450
end;
4451
4396
4452
procedure TfrmMain.miDownloadBooksClick(Sender: TObject);
4397
  procedure TfrmMain.miDownloadBooksClick(Sender: TObject);
4453
var
4398
  var
4454
  BookIDList: TBookIdList;
4399
    BookIDList: TBookIdList;
4455
  Tree: TVirtualStringTree;
4400
    Tree: TVirtualStringTree;
4456
4401
4457
  i: integer;
4402
    i: Integer;
4458
  Folder: string;
4403
    Folder: string;
4459
4404
4460
  LibID : integer;
4405
    LibID: Integer;
4461
4406
4462
  Node: PVirtualNode;
4407
    Node: PVirtualNode;
4463
  Data: PDownloadData;
4408
    Data: PDownloadData;
4464
4409
4465
  Local: boolean;
4410
    local: Boolean;
4466
4411
4467
    function CheckID(ID: integer):boolean;
4412
    function CheckID(ID: Integer): Boolean;
4468
    var
4413
    var
4469
      Node: PVirtualNode;
4414
      Node: PVirtualNode;
4470
      Data: PDownloadData;
4415
      Data: PDownloadData;
...
...
4488
      end;
4432
      end;
4489
    end;
4433
    end;
4490
4434
4491
begin
4492
  if ActiveView = DownloadView then
4493
  begin
4435
  begin
4494
    btnDeleteDownloadClick(Sender);
4436
    if ActiveView = DownloadView then
4495
    Exit;
4437
    begin
4496
  end;
4438
      btnDeleteDownloadClick(Sender);
4439
      Exit;
4440
    end;
4497
4441
4498
  GetActiveTree(Tree);
4442
    GetActiveTree(Tree);
4499
4443
4500
  FillBookIdList(Tree, BookIDList);
4444
    FillBookIdList(Tree, BookIDList);
4501
4445
4502
  for I := 0 to High(BookIDList) do
4446
    for i := 0 to high(BookIDList) do
4503
  begin
4447
    begin
4504
4448
4505
    dmCollection.FieldByName(BookIDList[i].ID, 'Local', Local);
4449
      dmCollection.FieldByName(BookIDList[i].ID, 'Local', local);
4506
    if Local then Continue;
4450
      if local then
4451
        Continue;
4507
4452
4508
    if ActiveView = FavoritesView then
4453
      if ActiveView = FavoritesView then
4509
    begin
4454
      begin
4510
      DMUser.tblGrouppedBooks.Locate('OuterID', BookIDList[i].ID, []);
4455
        DMUser.tblGrouppedBooks.Locate('OuterID', BookIDList[i].ID, []);
4511
      if DMUser.tblGrouppedBooksDataBaseId.Value <> DMUser.ActiveCollection.ID then
4456
        if DMUser.tblGrouppedBooksDatabaseID.Value <> DMUser.ActiveCollection.ID then
4512
         Continue;
4457
          Continue;
4513
    end;
4458
      end;
4514
4459
4515
    if CheckID(BookIDList[i].ID) then
4460
      if CheckID(BookIDList[i].ID) then
4516
      Continue;
4461
        Continue;
4517
4462
4518
    dmCollection.GetBookFolder(BookIDList[i].ID,Folder);
4463
      dmCollection.GetBookFolder(BookIDList[i].ID, Folder);
4519
4464
4520
    Node := tvDownloadList.AddChild(nil);
4465
      Node := tvDownloadList.AddChild(nil);
4521
    Data := tvDownloadList.GetNodeData(Node);
4466
      Data := tvDownloadList.GetNodeData(Node);
4522
4467
4523
    if ActiveView = FavoritesView  then
4468
      if ActiveView = FavoritesView then
4524
      Data.Author := DMUser.tblGrouppedBooksFullName.Value
4469
        Data.Author := DMUser.tblGrouppedBooksFullName.Value
4525
    else
4470
      else
4526
      Data.Author := dmCollection.FullName(BookIDList[i].ID);
4471
        Data.Author := dmCollection.FullName(BookIDList[i].ID);
4527
4472
4528
    dmCollection.FieldByName(BookIDList[i].ID, 'Title', Data.Title);
4473
      dmCollection.FieldByName(BookIDList[i].ID, 'Title', Data.Title);
4529
    dmCollection.FieldByName(BookIDList[i].ID, 'Size', Data.Size);
4474
      dmCollection.FieldByName(BookIDList[i].ID, 'Size', Data.Size);
4530
    dmCollection.FieldByName(BookIDList[i].ID, 'LibID', LibID);
4475
      dmCollection.FieldByName(BookIDList[i].ID, 'LibID', LibID);
4531
    Data.ID := BookIDList[i].ID;
4476
      Data.ID := BookIDList[i].ID;
4532
    Data.State := dsWait;
4477
      Data.State := dsWait;
4533
    Data.FileName := Folder;
4478
      Data.FileName := Folder;
4534
    Data.URL := Format(Settings.InpxURL + 'b/%d/get', [LibID]);
4479
      Data.URL := Format(Settings.InpxURL + 'b/%d/get', [LibID]);
4535
  end; // for
4480
    end; // for
4536
4481
4537
  lblDownloadCount.Caption := Format('(%d)',[tvDownloadList.ChildCount[Nil]]);
4482
    lblDownloadCount.Caption := Format('(%d)', [tvDownloadList.ChildCount[nil]]);
4538
4483
4539
  if Settings.AutoStartDwnld then
4484
    if Settings.AutoStartDwnld then
4540
    btnStartDownloadClick(Sender);
4485
      btnStartDownloadClick(Sender);
4541
end;
4486
  end;
4542
4487
4543
procedure TfrmMain.miEditAuthorClick(Sender: TObject);
4488
  procedure TfrmMain.miEditAuthorClick(Sender: TObject);
4544
var
4489
  var
4545
  Tree: TVirtualStringTree;
4490
    Tree: TVirtualStringTree;
4546
  Node: PVirtualNode;
4491
    Node: PVirtualNode;
4547
  Data: PBookData;
4492
    Data: PBookData;
4548
  Res: boolean;
4493
    Res: Boolean;
4549
  S: string;
4494
    S: string;
4550
4495
4551
  old_AiD: integer;
4496
    old_AiD: Integer;
4552
  new_AiD: integer;
4497
    new_AiD: Integer;
4553
4498
4554
  frmEditAuthor: TfrmEditAuthorDataEx;
4499
    frmEditAuthor: TfrmEditAuthorDataEx;
4555
begin
4556
  if ActiveView = FavoritesView then
4557
  begin
4500
  begin
4558
    MessageDlg('Редактирование книг из избранного невозможно.', mtWarning, [mbOk], 0);
4501
    if ActiveView = FavoritesView then
4559
    Exit;
4502
    begin
4560
  end;
4503
      MessageDlg('Редактирование книг из избранного невозможно.', mtWarning, [mbOk], 0);
4504
      Exit;
4505
    end;
4561
4506
4562
  if IsLibRusecEdit(0) then
4507
    if IsLibRusecEdit(0) then
4563
    Exit;
4508
      Exit;
4564
4509
4565
  GetActiveTree(Tree);
4510
    GetActiveTree(Tree);
4566
4511
4567
  Node := Tree.GetFirstSelected;
4512
    Node := Tree.GetFirstSelected;
4568
  Data := Tree.GetNodeData(Node);
4513
    Data := Tree.GetNodeData(Node);
4569
  if not Assigned(Data) then
4514
    if not Assigned(Data) then
4570
    Exit;
4515
      Exit;
4571
4516
4572
  dmCollection.tblAuthor_List.Locate('AL_BookId', Data.ID, []);
4517
    dmCollection.tblAuthor_List.Locate('AL_BookId', Data.ID, []);
4573
  dmCollection.tblAuthors.Locate('A_ID', dmCollection.tblAuthor_List['AL_AuthID'], []);
4518
    dmCollection.tblAuthors.Locate('A_ID', dmCollection.tblAuthor_List['AL_AuthID'], []);
4574
  old_AiD := dmCollection.tblAuthor_List['AL_AuthID'];
4519
    old_AiD := dmCollection.tblAuthor_List['AL_AuthID'];
4575
4520
4576
  frmEditAuthor := TfrmEditAuthorDataEx.Create(Self);
4521
    frmEditAuthor := TfrmEditAuthorDataEx.Create(self);
4577
  try
4522
    try
4578
    frmEditAuthor.LastName := dmCollection.tblAuthors.FieldByName('A_Family').AsString;
4523
      frmEditAuthor.LastName := dmCollection.tblAuthors.FieldByName('A_Family').AsString;
4579
    frmEditAuthor.FirstName := dmCollection.tblAuthors.FieldByName('A_Name').AsString;
4524
      frmEditAuthor.FirstName := dmCollection.tblAuthors.FieldByName('A_Name').AsString;
4580
    frmEditAuthor.MidName := dmCollection.tblAuthors.FieldByName('A_Middle').AsString;
4525
      frmEditAuthor.MidName := dmCollection.tblAuthors.FieldByName('A_Middle').AsString;
4581
4526
4582
    if frmEditAuthor.ShowModal = mrOk then
4527
      if frmEditAuthor.ShowModal = mrOk then
4583
    begin
4584
      S := Trim(AnsiUpperCase(frmEditAuthor.LastName + ' ' +
4585
                                   frmEditAuthor.FirstName + ' ' +
4586
                                   frmEditAuthor.MidName));
4587
4588
      if (not frmEditAuthor.AddNew) and (not frmEditAuthor.SaveLinks) then
4589
      begin
4528
      begin
4590
        // меняем только данные об авторе, все ссылки остаются на месте
        if dmCollection.tblAuthors.Locate(
4529
        S := trim(AnsiUpperCase(frmEditAuthor.LastName + ' ' + frmEditAuthor.FirstName + ' ' + frmEditAuthor.MidName));
4591
          'A_Family;A_Name;A_Middle',
4530
4592
          VarArrayOf([frmEditAuthor.LastName, frmEditAuthor.FirstName, frmEditAuthor.MidName]),
4531
        if (not frmEditAuthor.AddNew) and (not frmEditAuthor.SaveLinks) then
4593
          [loCaseInsensitive]
4594
          )
4595
        then
4596
        begin
4532
        begin
4597
          // если новый автор уже есть, меняем сслыки на него  (объединение)
4533
          begin
4598
          new_AiD := dmCollection.tblAuthorsID.Value;
4534
            // если новый автор уже есть, меняем сслыки на него  (объединение)
4599
          repeat
4535
            new_AiD := dmCollection.tblAuthorsID.Value;
4600
            // меняем старые Id на новые
          // меняем только данные об авторе, все ссылки остаются на месте
          if dmCollection.tblAuthors.Locate('A_Family;A_Name;A_Middle', VarArrayOf([frmEditAuthor.LastName, frmEditAuthor.FirstName, frmEditAuthor.MidName]), [loCaseInsensitive]) then
4536
            repeat
4601
            dmCollection.tblAuthor_List.MasterSource := nil;
4537
              // меняем старые Id на новые
              { TODO -oNickR -cRefactoring : можно заменить на один UPDATE }
4538
              dmCollection.tblAuthor_List.MasterSource := nil;
4539
4540
              Res := dmCollection.tblAuthor_List.Locate('AL_AuthID', old_AiD, []);
4541
              if Res then
4542
              begin
4543
                dmCollection.tblAuthor_List.Edit;
4544
                dmCollection.tblAuthor_ListAL_AuthID.Value := new_AiD;
4545
                dmCollection.tblAuthor_List.Post;
4546
              end;
4547
            until not Res;
4548
4549
            // обновляем индексное поле
            { TODO -oNickR -cRefactoring : можно заменить на один UPDATE }
4550
            repeat
4551
              Res := dmCollection.tblBooks.Locate('FullName', AnsiUpperCase(Data.FullName), [loCaseInsensitive]);
4552
              if Res then
4553
              begin
4554
                dmCollection.tblBooks.Edit;
4555
                dmCollection.tblBooksFullName.Value := S;
4556
                dmCollection.tblBooks.Post;
4557
              end;
4558
            until not Res;
4602
4559
4603
            Res := dmCollection.tblAuthor_List.Locate('AL_AuthID',old_Aid,[]);
4560
            // старого автора удаляем
4604
            if Res then
4561
            if dmCollection.tblAuthors.Locate('A_ID', old_AiD, []) then
4605
            begin
4562
              dmCollection.tblAuthors.Delete;
4606
              dmCollection.tblAuthor_List.Edit;
4607
              dmCollection.tblAuthor_ListAL_AuthID.Value := new_AiD;
4608
              dmCollection.tblAuthor_List.Post;
4609
            end;
4610
          until not Res;
4611
4563
4612
          // обновляем индексное поле
          { TODO -oNickR -cRefactoring : можно заменить на один UPDATE }
4564
            dmCollection.tblAuthor_List.MasterSource := dmCollection.dsAuthors;
4565
          end // if Locate
4566
          else // если нет - просто редактируем ФИО
4567
          begin
4568
            dmCollection.tblAuthors.Edit;
4569
            dmCollection.tblAuthorsFamily.Value := frmEditAuthor.LastName;
4570
            dmCollection.tblAuthorsName.Value := frmEditAuthor.FirstName;
4571
            dmCollection.tblAuthorsMiddle.Value := frmEditAuthor.MidName;
4572
            dmCollection.tblAuthors.Post;
4573
          end;
4574
4613
          repeat
4575
          repeat
4576
            { TODO -oNickR -cRefactoring : можно заменить на один UPDATE }
4614
            Res := dmCollection.tblBooks.Locate('FullName', AnsiUpperCase(Data.FullName), [loCaseInsensitive]);
4577
            Res := dmCollection.tblBooks.Locate('FullName', AnsiUpperCase(Data.FullName), [loCaseInsensitive]);
4615
            if Res then
4578
            if Res then
4616
            begin
4579
            begin
...
...
4622
              dmCollection.tblBooks.Post;
4586
              dmCollection.tblBooks.Post;
4623
            end;
4587
            end;
4624
          until not Res;
4588
          until not Res;
4625
4626
          // старого автора удаляем
4627
          if dmCollection.tblAuthors.Locate('A_ID', old_Aid,[]) then
4628
             dmCollection.tblAuthors.Delete;
4629
4630
          dmCollection.tblAuthor_List.MasterSource := dmCollection.dsAuthors;
4631
        end // if Locate
4632
        else  // если нет - просто редактируем ФИО
4633
        begin
4634
          dmCollection.tblAuthors.Edit;
4635
          dmCollection.tblAuthorsFamily.Value := frmEditAuthor.LastName;
4636
          dmCollection.tblAuthorsName.Value := frmEditAuthor.FirstName;
4637
          dmCollection.tblAuthorsMiddle.Value := frmEditAuthor.MidName;
4638
          dmCollection.tblAuthors.Post;
4639
        end;
4589
        end;
4640
4590
4641
        repeat
4591
        if (frmEditAuthor.AddNew) then
4642
          { TODO -oNickR -cRefactoring : можно заменить на один UPDATE }
4592
        begin // заменяем автора на нового
4643
          Res := dmCollection.tblBooks.Locate('FullName', AnsiUpperCase(Data.FullName), [loCaseInsensitive]);
4593
          // добавляем нового автора
4644
          if Res then
4594
          if not dmCollection.tblAuthors.Locate('A_Family;A_Name;A_Middle', VarArrayOf([frmEditAuthor.LastName, frmEditAuthor.FirstName, frmEditAuthor.MidName]), [loCaseInsensitive]) then
4645
          begin
4595
          begin
4646
            dmCollection.tblBooks.Edit;
4596
            dmCollection.tblAuthors.Insert;
4647
            dmCollection.tblBooksFullName.Value := S;
4597
            dmCollection.tblAuthorsFamily.Value := frmEditAuthor.LastName;
4648
            dmCollection.tblBooks.Post;
4598
            dmCollection.tblAuthorsName.Value := frmEditAuthor.FirstName;
4599
            dmCollection.tblAuthorsMiddle.Value := frmEditAuthor.MidName;
4600
            dmCollection.tblAuthors.Post;
4649
          end;
4601
          end;
4650
        until not Res;
4651
      end;
4652
4602
4653
      if (frmEditAuthor.AddNew) then
4603
          // меняем ссылки
4654
      begin    // заменяем автора на нового
4604
          dmCollection.tblAuthor_List.MasterSource := nil;
4655
        // добавляем нового автора
4656
        if not dmCollection.tblAuthors.Locate(
4657
          'A_Family;A_Name;A_Middle',
4658
          VarArrayOf([frmEditAuthor.LastName, frmEditAuthor.FirstName, frmEditAuthor.MidName]),
4659
          [loCaseInsensitive]
4660
          )
4661
        then
4662
        begin
4663
          dmCollection.tblAuthors.Insert;
4664
          dmCollection.tblAuthorsFamily.Value := frmEditAuthor.LastName;
4665
          dmCollection.tblAuthorsName.Value := frmEditAuthor.FirstName;
4666
          dmCollection.tblAuthorsMiddle.Value := frmEditAuthor.MidName;
4667
          dmCollection.tblAuthors.Post;
4668
        end;
4669
4605
4670
        // меняем ссылки
4606
          Node := Tree.GetFirst;
4671
        dmCollection.tblAuthor_List.MasterSource := nil;
4607
          while Node <> nil do
4672
4673
        Node := Tree.GetFirst;
4674
        while Node <> Nil do
4675
        begin
4676
          Data := Tree.GetNodeData(Node);
4677
          if (Data.nodeType = ntBookInfo) and
4678
              ((Tree.CheckState[Node] = csCheckedNormal) or
4679
              (Tree.Selected[Node])) then
4680
          begin
4608
          begin
4681
            if not frmEditAuthor.SaveLinks then   // заменяем ссылки
4609
            Data := Tree.GetNodeData(Node);
4610
            if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
4682
            begin
4611
            begin
4683
              if dmCollection.tblAuthor_List.Locate('AL_BookID',Data.ID,[]) then
4612
              if not frmEditAuthor.SaveLinks then // заменяем ссылки
4684
              begin
4613
              begin
4685
                dmCollection.tblAuthor_List.Edit;
4614
                if dmCollection.tblAuthor_List.Locate('AL_BookID', Data.ID, []) then
4686
                dmCollection.tblAuthor_ListAL_AuthID.Value := dmCollection.tblAuthorsID.Value;
4615
                begin
4687
                dmCollection.tblAuthor_List.Post;
4616
                  dmCollection.tblAuthor_List.Edit;
4617
                  dmCollection.tblAuthor_ListAL_AuthID.Value := dmCollection.tblAuthorsID.Value;
4618
                  dmCollection.tblAuthor_List.Post;
4619
                end
4688
              end
4620
              end
4689
            end
4621
              else
4690
            else
4622
              begin // добавляем второго автора
4691
            begin // добавляем второго автора
4623
                dmCollection.tblAuthor_List.Insert;
4692
              dmCollection.tblAuthor_List.Insert;
4624
                dmCollection.tblAuthor_ListAL_AuthID.Value := dmCollection.tblAuthorsID.Value;
4693
              dmCollection.tblAuthor_ListAL_AuthID.Value := dmCollection.tblAuthorsID.Value;
4625
                dmCollection.tblAuthor_ListAL_BookID.Value := Data.ID;
4694
              dmCollection.tblAuthor_ListAL_BookID.Value := Data.ID;
4695
4626
4696
              dmCollection.tblAuthor_ListAL_Series.Value := Copy(Data.Series, 1, IndexSize);
4627
                dmCollection.tblAuthor_ListAL_Series.Value := copy(Data.Series, 1, IndexSize);
4697
              dmCollection.tblAuthor_ListAL_Title.Value := Copy(Data.Title, 1, IndexSize);
4628
                dmCollection.tblAuthor_ListAL_Title.Value := copy(Data.Title, 1, IndexSize);
4698
4629
4699
              dmCollection.tblAuthor_List.Post;
4630
                dmCollection.tblAuthor_List.Post;
4631
              end;
4632
              dmCollection.tblBooks.Locate('ID', Data.ID, []);
4633
              dmCollection.tblBooks.Edit;
4634
              dmCollection.tblBooksFullName.Value := S;
4635
              dmCollection.tblBooks.Post;
4700
            end;
4636
            end;
4701
            dmCollection.tblBooks.Locate('ID', Data.ID, []);
4637
            Node := Tree.GetNext(Node, False);
4702
            dmCollection.tblBooks.Edit;
4703
            dmCollection.tblBooksFullName.Value:= S;
4704
            dmCollection.tblBooks.Post;
4705
          end;
4638
          end;
4706
          Node := Tree.GetNext(Node,False);
4639
          dmCollection.tblAuthor_List.MasterSource := dmCollection.dsAuthors;
4707
        end;
4640
        end;
4708
        dmCollection.tblAuthor_List.MasterSource := dmCollection.dsAuthors;
4641
        InitCollection(True);
4709
      end;
4642
      end;
4710
      InitCollection(True);
4643
    finally
4644
      frmEditAuthor.Free;
4711
    end;
4645
    end;
4712
  finally
4713
    frmEditAuthor.Free;
4714
  end;
4646
  end;
4715
end;
4716
4647
4717
function TfrmMain.IsLibRusecEdit(ID: integer): boolean;
4648
  function TfrmMain.IsLibRusecEdit(ID: Integer): Boolean;
4718
begin
4719
  if isExternalCollection(DMUser.ActiveCollection.CollectionType) then
4720
  begin
4649
  begin
4721
    if MessageDlg('Изменения информации о книгах в коллекциях "lib.rus.ec" возможно только на сайте.' + #13 +
4650
    if isExternalCollection(DMUser.ActiveCollection.CollectionType) then
4722
      'Перейти на сайт "Электронная библиотека lib.rus.ec"?',
4723
      mtWarning, [mbYes, mbNo], 0) = mrYes then
4724
    begin
4651
    begin
4725
      dmCollection.tblBooks.Locate('ID', ID, []);
4652
      if MessageDlg('Изменения информации о книгах в коллекциях "lib.rus.ec" возможно только на сайте.' + #13 + 'Перейти на сайт "Электронная библиотека lib.rus.ec"?', mtWarning, [mbYes, mbNo], 0) = mrYes then
4726
      ShellExecute(handle, 'open', PChar('http://lib.rus.ec/b/' + IntToStr(dmCollection.tblBooks['LibID']) + '/edit'), nil, nil, SW_SHOW);
4653
      begin
4727
    end;
4654
        dmCollection.tblBooks.Locate('ID', ID, []);
4728
    Result := True;
4655
        ShellExecute(Handle, 'open', PChar('http://lib.rus.ec/b/' + IntToStr(dmCollection.tblBooks['LibID']) + '/edit'), nil, nil, SW_SHOW);
4729
  end
4656
      end;
4730
  else
4657
      Result := True;
4731
    Result := False;
4658
    end
4732
end;
4659
    else
4660
      Result := False;
4661
  end;
4733
4662
4734
procedure TfrmMain.PrepareFb2EditData(Data: PBookData; var R: TBookRecord);
4663
  procedure TfrmMain.PrepareFb2EditData(Data: PBookData; var R: TBookRecord);
4735
var
4664
  var
4736
  Family: TListItem;
4665
    Family: TListItem;
4737
4666
4738
  Author: TAuthorRecord;
4667
    Author: TAuthorRecord;
4739
  Genre: TGenreRecord;
4668
    Genre: TGenreRecord;
4740
4669
4741
begin
4742
4743
  GetBookRecord(Data.ID, R);
4744
  frmEditBookInfo.lvAuthors.Items.Clear;
4745
  for Author in R.Authors do
4746
  begin
4670
  begin
4747
    Family := frmEditBookInfo.lvAuthors.Items.Add;
4748
    Family.Caption := Author.LastName;
4749
    Family.SubItems.Add(Author.FirstName);
4750
    Family.SubItems.Add(Author.MiddleName);
4751
  end;
4752
  frmEditBookInfo.lblGenre.Text := '';
4753
  FillGenresTree(frmGenreTree.tvGenresTree);
4754
  for Genre in R.Genres do
4755
  begin
4756
    frmGenreTree.SelectGenres(Genre.GenreCode);
4757
    frmEditBookInfo.lblGenre.Text := frmEditBookInfo.lblGenre.Text + Genre.Alias + ';';
4758
  end;
4759
  frmEditBookInfo.edT.Text := R.Title;
4760
4671
4761
  if R.Series = NO_SERIES_TITLE then
4672
    GetBookRecord(Data.ID, R);
4762
    frmEditBookInfo.cbSeries.Text := ''
4673
    frmEditBookInfo.lvAuthors.Items.Clear;
4763
  else
4674
    for Author in R.Authors do
4764
    frmEditBookInfo.cbSeries.Text := R.Series;
4675
    begin
4676
      Family := frmEditBookInfo.lvAuthors.Items.Add;
4677
      Family.Caption := Author.LastName;
4678
      Family.SubItems.Add(Author.FirstName);
4679
      Family.SubItems.Add(Author.MiddleName);
4680
    end;
4681
    frmEditBookInfo.lblGenre.text := '';
4682
    FillGenresTree(frmGenreTree.tvGenresTree);
4683
    for Genre in R.Genres do
4684
    begin
4685
      frmGenreTree.SelectGenres(Genre.GenreCode);
4686
      frmEditBookInfo.lblGenre.text := frmEditBookInfo.lblGenre.text + Genre.Alias + ';';
4687
    end;
4688
    frmEditBookInfo.edT.text := R.Title;
4765
4689
4766
  frmEditBookInfo.edSN.Text := IntToStr(R.SeqNumber);
4690
    if R.Series = NO_SERIES_TITLE then
4767
  frmEditBookInfo.edKeyWords.Text := R.KeyWords;
4691
      frmEditBookInfo.cbSeries.text := ''
4768
  frmEditBookInfo.cbLang.Text := R.Lang;
4692
    else
4693
      frmEditBookInfo.cbSeries.text := R.Series;
4769
4694
4770
end;
4695
    frmEditBookInfo.edSN.text := IntToStr(R.SeqNumber);
4696
    frmEditBookInfo.edKeyWords.text := R.KeyWords;
4697
    frmEditBookInfo.cbLang.text := R.Lang;
4771
4698
4772
procedure TfrmMain.SaveFb2DataAfterEdit(R: TBookRecord);
4699
  end;
4773
var
4774
  Tree: TVirtualStringTree;
4775
  Data: PBookData;
4776
  Node: PVirtualNode;
4777
  i: integer;
4778
  ALibrary : TMHLLibrary;
4779
4700
4780
  OldID: integer;
4701
  procedure TfrmMain.SaveFb2DataAfterEdit(R: TBookRecord);
4781
begin
4702
  var
4703
    Tree: TVirtualStringTree;
4704
    Data: PBookData;
4705
    Node: PVirtualNode;
4706
    i: Integer;
4707
    ALibrary: TMHLLibrary;
4782
4708
4783
  GetActiveTree(Tree);
4709
    OldID: Integer;
4784
  Node := Tree.GetFirstSelected;
4710
  begin
4785
4711
4786
  Data := Tree.GetNodeData(Node);
4712
    GetActiveTree(Tree);
4787
  if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
4713
    Node := Tree.GetFirstSelected;
4788
    Exit;
4789
4714
4790
  R.ClearAuthors;
4715
    Data := Tree.GetNodeData(Node);
4716
    if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
4717
      Exit;
4791
4718
4792
  for I := 0 to frmEditBookInfo.lvAuthors.Items.Count - 1 do
4719
    R.ClearAuthors;
4793
      R.AddAuthor(
4794
        frmEditBookInfo.lvAuthors.Items[i].Caption,
4795
        frmEditBookInfo.lvAuthors.Items[i].SubItems[0],
4796
        frmEditBookInfo.lvAuthors.Items[i].SubItems[1]
4797
        );
4798
4720
4799
  frmGenreTree.GetSelectedGenres(R);
4721
    for i := 0 to frmEditBookInfo.lvAuthors.Items.Count - 1 do
4800
  R.Title := frmEditBookInfo.edT.Text;
4722
      R.AddAuthor(frmEditBookInfo.lvAuthors.Items[i].Caption, frmEditBookInfo.lvAuthors.Items[i].SubItems[0], frmEditBookInfo.lvAuthors.Items[i].SubItems[1]);
4801
  R.Series := frmEditBookInfo.cbSeries.Text;
4802
4723
4803
  R.SeqNumber := StrToIntDef(frmEditBookInfo.edSN.Text, 0);
4724
    frmGenreTree.GetSelectedGenres(R);
4804
  R.KeyWords := frmEditBookInfo.edKeyWords.Text;
4725
    R.Title := frmEditBookInfo.edT.text;
4805
  R.Lang := frmEditBookInfo.cbLang.Text;
4726
    R.Series := frmEditBookInfo.cbSeries.text;
4806
4727
4807
  OldID := Data.ID;
4728
    R.SeqNumber := StrToIntDef(frmEditBookInfo.edSN.text, 0);
4729
    R.KeyWords := frmEditBookInfo.edKeyWords.text;
4730
    R.Lang := frmEditBookInfo.cbLang.text;
4808
4731
4809
  ALibrary := TMHLLibrary.Create(nil);
4732
    OldID := Data.ID;
4810
  try
4811
    ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
4812
    ALibrary.Active := True;
4813
4733
4814
    ALibrary.BeginBulkOperation;
4734
    ALibrary := TMHLLibrary.Create(nil);
4815
    try
4735
    try
4816
      ALibrary.DeleteBook(Data.ID, False);
4736
      ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
4817
      Data.ID := ALibrary.InsertBook(R, False, False);
4737
      ALibrary.Active := True;
4818
      ALibrary.CorrectExtra(OldID, Data.ID);
4819
      ALibrary.EndBulkOperation(True);
4820
    except
4821
      ALibrary.EndBulkOperation(False);
4822
    end;
4823
4738
4824
    DMUser.CorrectExtra(OLdID, Data.ID);
4739
      ALibrary.BeginBulkOperation;
4740
      try
4741
        ALibrary.DeleteBook(Data.ID, False);
4742
        Data.ID := ALibrary.InsertBook(R, False, False);
4743
        ALibrary.CorrectExtra(OldID, Data.ID);
4744
        ALibrary.EndBulkOperation(True);
4745
      except
4746
        ALibrary.EndBulkOperation(False);
4747
      end;
4825
4748
4826
    Data.Title := frmEditBookInfo.edT.Text;
4749
      DMUser.CorrectExtra(OldID, Data.ID);
4827
    Data.Genre := frmEditBookInfo.lblGenre.Text;
4750
4828
    Data.No := StrToIntDef(frmEditBookInfo.edSN.Text, 0);
4751
      Data.Title := frmEditBookInfo.edT.text;
4829
    Data.Lang := frmEditBookInfo.cbLang.Text;
4752
      Data.Genre := frmEditBookInfo.lblGenre.text;
4830
    Tree.RepaintNode(Node);
4753
      Data.No := StrToIntDef(frmEditBookInfo.edSN.text, 0);
4831
  finally
4754
      Data.Lang := frmEditBookInfo.cbLang.text;
4832
    ALibrary.Free;
4755
      Tree.RepaintNode(Node);
4756
    finally
4757
      ALibrary.Free;
4758
    end;
4833
  end;
4759
  end;
4834
end;
4835
4760
4836
procedure TfrmMain.miEditBookClick(Sender: TObject);
4761
  procedure TfrmMain.miEditBookClick(Sender: TObject);
4837
var
4762
  var
4838
  Tree: TVirtualStringTree;
4763
    Tree: TVirtualStringTree;
4839
  Data: PBookData;
4764
    Data: PBookData;
4840
  Node: PVirtualNode;
4765
    Node: PVirtualNode;
4841
begin
4842
  if (ActiveView = FavoritesView) or (ActiveView = DownloadView) then
4843
  begin
4766
  begin
4844
    MessageDlg('Редактирование книг из избранного или списка закачек невозможно.', mtWarning, [mbOk], 0);
4767
    if (ActiveView = FavoritesView) or (ActiveView = DownloadView) then
4845
    Exit;
4768
    begin
4846
  end;
4769
      MessageDlg('Редактирование книг из избранного или списка закачек невозможно.', mtWarning, [mbOk], 0);
4770
      Exit;
4771
    end;
4847
4772
4848
  GetActiveTree(Tree);
4773
    GetActiveTree(Tree);
4849
  Node := Tree.GetFirstSelected;
4774
    Node := Tree.GetFirstSelected;
4850
  Data := Tree.GetNodeData(Node);
4775
    Data := Tree.GetNodeData(Node);
4851
  if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
4776
    if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
4852
    Exit;
4777
      Exit;
4853
4778
4854
  if IsLibRusecEdit(Data.Id) then
4779
    if IsLibRusecEdit(Data.ID) then
4855
    Exit;
4780
      Exit;
4856
4781
4857
  PrepareFb2EditData(Data, FLastBookRecord);
4782
    PrepareFb2EditData(Data, FLastBookRecord);
4858
4783
4859
  if frmEditBookInfo.ShowModal = mrOk then
4784
    if frmEditBookInfo.ShowModal = mrOk then
4860
  begin
4785
    begin
4861
    SaveFb2DataAfterEdit(FLastBookRecord);
4786
      SaveFb2DataAfterEdit(FLastBookRecord);
4862
    SavePositions;
4787
      SavePositions;
4863
    InitCollection(True);
4788
      InitCollection(True);
4864
    RestorePositions;
4789
      RestorePositions;
4790
    end;
4865
  end;
4791
  end;
4866
end;
4867
4792
4868
procedure TfrmMain.miEditGenresClick(Sender: TObject);
4793
  procedure TfrmMain.miEditGenresClick(Sender: TObject);
4869
var
4794
  var
4870
  NodeB, NodeG: PvirtualNode;
4795
    NodeB, NodeG: PVirtualNode;
4871
  DataG: PGenreData;
4796
    DataG: PGenreData;
4872
  DataB: PBookData;
4797
    DataB: PBookData;
4873
  Tree: TVirtualStringTree;
4798
    Tree: TVirtualStringTree;
4874
  ALibrary: TMHLLibrary;
4799
    ALibrary: TMHLLibrary;
4875
begin
4876
  if ActiveView = FavoritesView then
4877
  begin
4800
  begin
4878
    MessageDlg('Редактирование книг из избранного невозможно.', mtWarning, [mbOk], 0);
4801
    if ActiveView = FavoritesView then
4879
    Exit;
4802
    begin
4880
  end;
4803
      MessageDlg('Редактирование книг из избранного невозможно.', mtWarning, [mbOk], 0);
4804
      Exit;
4805
    end;
4881
4806
4882
  if IsLibRusecEdit(0) then
4807
    if IsLibRusecEdit(0) then
4883
    Exit;
4808
      Exit;
4884
4809
4885
  GetActiveTree(Tree);
4810
    GetActiveTree(Tree);
4886
4811
4887
  FillGenresTree(frmGenreTree.tvGenresTree);
4812
    FillGenresTree(frmGenreTree.tvGenresTree);
4888
4813
4889
  if frmGenreTree.ShowModal = mrOk then
4814
    if frmGenreTree.ShowModal = mrOk then
4890
  begin
4815
    begin
4891
    ALibrary := TMHLLibrary.Create(nil);
4816
      ALibrary := TMHLLibrary.Create(nil);
4892
    try
4817
      try
4893
      ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
4818
        ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
4894
      ALibrary.Active := True;
4819
        ALibrary.Active := True;
4895
4820
4896
      NodeB := Tree.GetFirst;
4821
        NodeB := Tree.GetFirst;
4897
      while Assigned(NodeB) do
4822
        while Assigned(NodeB) do
4898
      begin
4899
        DataB := Tree.GetNodeData(NodeB);
4900
        if (DataB.nodeType = ntBookInfo) and ((Tree.CheckState[NodeB] = csCheckedNormal) or (Tree.Selected[NodeB])) then
4901
        begin
4823
        begin
4902
          ALibrary.CleanBookGenres(DataB.ID);
4824
          DataB := Tree.GetNodeData(NodeB);
4903
4825
          if (DataB.nodeType = ntBookInfo) and ((Tree.CheckState[NodeB] = csCheckedNormal) or (Tree.Selected[NodeB])) then
4904
          DataB.Genre := '';
4905
          NodeG := frmGenreTree.tvGenresTree.GetFirstSelected;
4906
          while Assigned(NodeG) do
4907
          begin
4826
          begin
4908
            DataG := frmGenreTree.tvGenresTree.GetNodeData(NodeG);
4827
            ALibrary.CleanBookGenres(DataB.ID);
4909
4828
4910
            ALibrary.AddBookGenre(DataB.ID, DataG.Code);
4829
            DataB.Genre := '';
4830
            NodeG := frmGenreTree.tvGenresTree.GetFirstSelected;
4831
            while Assigned(NodeG) do
4832
            begin
4833
              DataG := frmGenreTree.tvGenresTree.GetNodeData(NodeG);
4911
4834
4912
            DataB.Genre := DataB.Genre + DataG.Text + ' / ';
4835
              ALibrary.AddBookGenre(DataB.ID, DataG.Code);
4913
            NodeG := frmGenreTree.tvGenresTree.GetNextSelected(NodeG);
4914
          end;
4915
4836
4916
          Delete(DataB.Genre, length(DataB.Genre) - 2, 3);
4837
              DataB.Genre := DataB.Genre + DataG.text + ' / ';
4838
              NodeG := frmGenreTree.tvGenresTree.GetNextSelected(NodeG);
4839
            end;
4840
4841
            Delete(DataB.Genre, Length(DataB.Genre) - 2, 3);
4842
          end;
4843
          Tree.RepaintNode(NodeB);
4844
          NodeB := Tree.GetNext(NodeB);
4917
        end;
4845
        end;
4918
        Tree.RepaintNode(NodeB);
4846
      finally
4919
        NodeB := Tree.GetNext(NodeB);
4847
        ALibrary.Free;
4920
      end;
4848
      end;
4921
    finally
4922
      ALibrary.Free;
4923
    end;
4849
    end;
4924
  end;
4850
  end;
4925
end;
4926
4851
4927
procedure TfrmMain.miEditSeriesClick(Sender: TObject);
4852
  procedure TfrmMain.miEditSeriesClick(Sender: TObject);
4928
var
4853
  var
4929
  Tree: TVirtualStringTree;
4854
    Tree: TVirtualStringTree;
4930
  Data: PBookData;
4855
    Data: PBookData;
4931
  Node: PVirtualNode;
4856
    Node: PVirtualNode;
4932
  AuthID: integer;
4857
    AuthID: Integer;
4933
  S: string;
4858
    S: string;
4934
begin
4935
  if ActiveView = FavoritesView then
4936
  begin
4859
  begin
4937
    MessageDlg('Редактирование книг из избранного невозможно.', mtWarning, [mbOk], 0);
4860
    if ActiveView = FavoritesView then
4938
    Exit;
4861
    begin
4939
  end;
4862
      MessageDlg('Редактирование книг из избранного невозможно.', mtWarning, [mbOk], 0);
4863
      Exit;
4864
    end;
4940
4865
4941
  GetActiveTree(Tree);
4866
    GetActiveTree(Tree);
4942
  Node := Tree.GetFirstSelected;
4867
    Node := Tree.GetFirstSelected;
4943
  Data := Tree.GetNodeData(Node);
4868
    Data := Tree.GetNodeData(Node);
4944
  if not Assigned(Data) then
4869
    if not Assigned(Data) then
4945
    Exit;
4870
      Exit;
4946
4871
4947
  if IsLibRusecEdit(Data.ID) then
4872
    if IsLibRusecEdit(Data.ID) then
4948
    Exit;
4873
      Exit;
4949
4874
4950
  S := Data.Series;
4875
    S := Data.Series;
4951
4876
4952
  if Data.nodeType = ntBookInfo then // добавляем новую серию
4877
    if Data.nodeType = ntBookInfo then // добавляем новую серию
4953
  begin
4954
    AuthID := dmCollection.AuthorID(Data.ID);
4955
4956
    if InputQuery('Создание серии/ Перенос в серию', 'Название:', S) then
4957
    begin
4878
    begin
4958
      if S = '' then S:= NO_SERIES_TITLE;
4879
      AuthID := dmCollection.AuthorID(Data.ID);
4959
4880
4960
      if not dmCollection.tblSeriesB.Locate('S_Title;S_AuthID', VarArrayOf([S,AuthID]), []) then
4881
      if InputQuery('Создание серии/ Перенос в серию', 'Название:', S) then
4961
      begin
4882
      begin
4962
        dmCollection.tblSeriesB.Insert;
4883
        if S = '' then
4963
        dmCollection.tblSeriesBS_Title.Value := S;
4884
          S := NO_SERIES_TITLE;
4964
        dmCollection.tblSeriesBS_AuthID.Value := AuthID;
4885
4965
        dmCollection.tblSeriesBS_GenreCode.Value := dmCollection.GetGenreCode(Data.ID);
4886
        if not dmCollection.tblSeriesB.Locate('S_Title;S_AuthID', VarArrayOf([S, AuthID]), []) then
4966
        dmCollection.tblSeriesB.Post;
4967
      end;
4968
      Node := Tree.GetFirst;
4969
      while Node <> nil do
4970
      begin
4971
        Data := Tree.GetNodeData(Node);
4972
        if ((Tree.CheckState[Node] = csCheckedNormal) or
4973
           (Tree.Selected[Node])) then
4974
        begin
4887
        begin
4975
          dmCollection.tblBooks.Locate('ID', Data.ID, []);
4888
          dmCollection.tblSeriesB.Insert;
4976
          dmCollection.tblBooks.Edit;
4889
          dmCollection.tblSeriesBS_Title.Value := S;
4977
          dmCollection.tblBooksSerID.Value:= dmCollection.tblSeriesBS_ID.Value;
4890
          dmCollection.tblSeriesBS_AuthID.Value := AuthID;
4978
          dmCollection.tblBooks.Post;
4891
          dmCollection.tblSeriesBS_GenreCode.Value := dmCollection.GetGenreCode(Data.ID);
4892
          dmCollection.tblSeriesB.Post;
4979
        end;
4893
        end;
4980
        Node := Tree.GetNext(Node);
4894
        Node := Tree.GetFirst;
4895
        while Node <> nil do
4896
        begin
4897
          Data := Tree.GetNodeData(Node);
4898
          if ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
4899
          begin
4900
            dmCollection.tblBooks.Locate('ID', Data.ID, []);
4901
            dmCollection.tblBooks.Edit;
4902
            dmCollection.tblBooksSerID.Value := dmCollection.tblSeriesBS_ID.Value;
4903
            dmCollection.tblBooks.Post;
4904
          end;
4905
          Node := Tree.GetNext(Node);
4906
        end;
4907
        FillAllBooksTree;
4981
      end;
4908
      end;
4982
      FillAllBooksTree;
4909
    end
4983
    end;
4910
    else // редактирукм название существующей
      if InputQuery('Редактирование серии', 'Название:', S) then
4984
  end
4985
  else     // редактирукм название существующей
    if InputQuery('Редактирование серии', 'Название:', S) then
4986
    begin
4911
    begin
4987
      if S = '' then    { TODO : заменить на один update }
4912
      if S = '' then { TODO : заменить на один update }
4988
      begin
4913
      begin
4989
        while dmCollection.tblBooks.Locate('SerID', Data.SeriesID, []) do
4914
        while dmCollection.tblBooks.Locate('SerID', Data.SeriesID, []) do
4990
        begin
4915
        begin
4991
          dmCollection.tblBooks.Edit;
4916
          dmCollection.tblBooks.Edit;
4992
          dmCollection.tblBooksSerID.Value:= 1;
4917
          dmCollection.tblBooksSerID.Value := 1;
4993
          dmCollection.tblBooks.Post;
4918
          dmCollection.tblBooks.Post;
4994
        end;
4919
        end;
4995
        FillAllBooksTree;
4920
        FillAllBooksTree;
...
...
5006
      end;
4931
      end;
5007
    end;
4932
    end;
5008
4933
5009
end;
4934
  end;
5010
4935
5011
procedure TfrmMain.miAddFavoritesClick(Sender: TObject);
4936
  procedure TfrmMain.miAddFavoritesClick(Sender: TObject);
5012
var
4937
  var
5013
  Tree: TVirtualStringTree;
4938
    Tree: TVirtualStringTree;
5014
  i, Max: integer;
4939
    i, Max: Integer;
5015
  Data: PBookData;
4940
    Data: PBookData;
5016
  GroupData: PGroupData;
4941
    GroupData: PGroupData;
5017
4942
5018
  Node: PVirtualNode;
4943
    Node: PVirtualNode;
5019
begin
4944
  begin
5020
  GetActiveTree(Tree);
4945
    GetActiveTree(Tree);
5021
  Max := Tree.TotalCount;
4946
    Max := Tree.TotalCount;
5022
4947
5023
  if Max = 0 then Exit;
4948
    if Max = 0 then
4949
      Exit;
5024
4950
5025
  if Sender is TMenuItem then
4951
    if Sender is TMenuItem then
5026
       DMUser.ActivateGroup((Sender as TMenuItem).Tag)
4952
      DMUser.ActivateGroup((Sender as TMenuItem).tag)
5027
  else
4953
    else
5028
       DMUser.ActivateGroup(1);
4954
      DMUser.ActivateGroup(1);
5029
4955
5030
  spProgress.Visible := True;
4956
    spProgress.Visible := True;
5031
  spStatus.Caption := 'Добавляем в избранное...';
4957
    spStatus.Caption := 'Добавляем в избранное...';
5032
  Screen.Cursor := crHourglass;
4958
    Screen.Cursor := crHourGlass;
5033
  dmCollection.tblBooks.DisableControls;
4959
    dmCollection.tblBooks.DisableControls;
5034
  DMUser.tblGrouppedBooks.DisableControls;
4960
    DMUser.tblGrouppedBooks.DisableControls;
5035
4961
5036
  Node := Tree.GetFirst;
4962
    Node := Tree.GetFirst;
5037
  i := 0;
4963
    i := 0;
5038
  while Assigned(Node) do
4964
    while Assigned(Node) do
5039
  begin
4965
    begin
5040
    Data := Tree.GetNodeData(Node);
4966
      Data := Tree.GetNodeData(Node);
5041
    if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
4967
      if (Data.nodeType = ntBookInfo) and ((Tree.CheckState[Node] = csCheckedNormal) or (Tree.Selected[Node])) then
5042
      DMUser.InsertToGroupTable(Data.ID, Data.Genre);
4968
        DMUser.InsertToGroupTable(Data.ID, Data.Genre);
5043
4969
5044
    // Tree.CheckState[Node]:=csUnCheckedNormal;
4970
      // Tree.CheckState[Node]:=csUnCheckedNormal;
5045
    Inc(i);
4971
      inc(i);
5046
    spProgress.Percent := i * 100 div Max;
4972
      spProgress.Percent := i * 100 div Max;
5047
    spProgress.Repaint;
4973
      spProgress.Repaint;
5048
4974
5049
    Node := Tree.GetNext(Node);
4975
      Node := Tree.GetNext(Node);
4976
    end;
4977
    spProgress.Visible := False;
4978
    Selection(False);
4979
    dmCollection.tblBooks.EnableControls;
4980
    DMUser.tblGrouppedBooks.EnableControls;
4981
    Screen.Cursor := crDefault;
4982
4983
    // если выделенная группа совпадает с той, куда добавляем книги, нужно перерисовать список
4984
    if (tvGroups.SelectedCount > 0) then
4985
    begin
4986
      GroupData := tvGroups.GetNodeData(tvGroups.GetFirstSelected);
4987
      if GroupData.ID = DMUser.tblGroupListID.Value then
4988
        FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // жанры
    end;
5050
  end;
4989
  end;
5051
  spProgress.Visible := False;
5052
  Selection(False);
5053
  dmCollection.tblBooks.EnableControls;
5054
  DMUser.tblGrouppedBooks.EnableControls;
5055
  Screen.Cursor := crDefault;
5056
4990
5057
  // если выделенная группа совпадает с той, куда добавляем книги, нужно перерисовать список
4991
  procedure TfrmMain.miAddToSearchClick(Sender: TObject);
5058
  if (tvGroups.SelectedCount > 0) then
4992
  var
4993
    Edit: TRzButtonEdit;
4994
    treeView: TVirtualStringTree;
4995
    Node: PVirtualNode;
4996
    Data: PAuthorData;
5059
  begin
4997
  begin
5060
    GroupData := tvGroups.GetNodeData(tvGroups.GetFirstSelected);
4998
    case ActiveView of
5061
    if GroupData.ID = DMUser.tblGroupListID.Value then
4999
      ByAuthorView:
5062
      FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // жанры
  end;
5000
        begin
5063
 end;
5001
          treeView := tvAuthors;
5002
          Edit := edFFullName;
5003
        end;
5004
      BySeriesView:
5005
        begin
5006
          treeView := tvSeries;
5007
          Edit := edFSeries;
5008
        end
5009
      else
5010
        Assert(False);
5011
    end;
5064
5012
5065
procedure TfrmMain.miAddToSearchClick(Sender: TObject);
5013
    Node := treeView.GetFirstSelected;
5066
var
5014
    while Node <> nil do
5067
  Edit: TRzButtonEdit;
5015
    begin
5068
  treeView: TVirtualStringTree;
5016
      Data := treeView.GetNodeData(Node);
5069
  Node: PVirtualNode;
5017
      if Edit.text = '' then
5070
  Data: PAuthorData;
5018
        Edit.text := Format('="%s"', [Data.text])
5071
begin
5019
      else
5072
  case ActiveView of
5020
        Edit.text := Format('%s OR%s="%s"', [Edit.text, #13#10, Data.text]);
5073
    ByAuthorView: begin
5021
      Node := treeView.GetNextSelected(Node);
5074
                    treeView := tvAuthors;
5022
    end;
5075
                    Edit := edFFullName;
5023
5076
                  end;
5077
    BySeriesView: begin
5078
                    treeView := tvSeries;
5079
                    Edit := edFSeries;
5080
                  end
5081
  else
5082
    Assert(False);
5083
  end;
5024
  end;
5084
5025
5085
  Node := treeView.GetFirstSelected;
5026
  procedure TfrmMain.miFastBookSearchClick(Sender: TObject);
5086
  while Node <> nil do
5087
  begin
5027
  begin
5088
    Data := treeView.GetNodeData(Node);
5028
    unit_Utils.LocateBook;
5089
    if Edit.Text = '' then
5090
         Edit.Text := Format('="%s"',[Data.Text])
5091
    else
5092
         Edit.Text := Format('%s OR%s="%s"',[Edit.Text,#13#10,Data.Text]);
5093
    Node := treeView.GetNextSelected(Node);
5094
  end;
5029
  end;
5095
5030
5096
end;
5031
  procedure TfrmMain.miFb2ImportClick(Sender: TObject);
5032
  begin
5033
    DMUser.ActivateCollection(Settings.ActiveCollection);
5034
    dmCollection.DBCollection.Connected := False;
5097
5035
5098
procedure TfrmMain.miFastBookSearchClick(Sender: TObject);
5036
    unit_Import.ImportFB2(DMUser.ActiveCollection);
5099
begin
5100
  unit_Utils.LocateBook;
5101
end;
5102
5037
5103
procedure TfrmMain.miFb2ImportClick(Sender: TObject);
5038
    InitCollection(True);
5104
begin
5039
  end;
5105
  DMUser.ActivateCollection(Settings.ActiveCollection);
5106
  dmCollection.DBCollection.Connected := False;
5107
5040
5108
  unit_Import.ImportFB2(DMUser.ActiveCollection);
5041
  procedure TfrmMain.miFb2ZipImportClick(Sender: TObject);
5042
  begin
5043
    DMUser.ActivateCollection(Settings.ActiveCollection);
5044
    dmCollection.DBCollection.Connected := False;
5109
5045
5110
  InitCollection(True);
5046
    unit_Import.ImportFB2ZIP(DMUser.ActiveCollection);
5111
end;
5112
5047
5113
procedure TfrmMain.miFb2ZipImportClick(Sender: TObject);
5048
    InitCollection(True);
5114
begin
5049
  end;
5115
  DMUser.ActivateCollection(Settings.ActiveCollection);
5116
  dmCollection.DBCollection.Connected := False;
5117
5050
5118
  unit_Import.ImportFB2ZIP(DMUser.ActiveCollection);
5051
  procedure TfrmMain.miFBDImportClick(Sender: TObject);
5052
  begin
5053
    DMUser.ActivateCollection(Settings.ActiveCollection);
5054
    dmCollection.DBCollection.Connected := False;
5119
5055
5120
  InitCollection(True);
5056
    unit_Import.ImportFBD(DMUser.ActiveCollection);
5121
end;
5122
5057
5123
procedure TfrmMain.miFBDImportClick(Sender: TObject);
5058
    InitCollection(True);
5124
begin
5059
  end;
5125
  DMUser.ActivateCollection(Settings.ActiveCollection);
5126
  dmCollection.DBCollection.Connected := False;
5127
5060
5128
  unit_Import.ImportFBD(DMUser.ActiveCollection);
5061
  procedure TfrmMain.miSetRateClick(Sender: TObject);
5129
5062
  var
5130
  InitCollection(True);
5063
    Tree: TVirtualStringTree;
5131
end;
5064
    Data: PBookData;
5132
5065
    Node: PVirtualNode;
5133
procedure TfrmMain.miSetRateClick(Sender: TObject);
5134
var
5135
  Tree: TVirtualStringTree;
5136
  Data: PBookData;
5137
  Node: PVirtualNode;
5138
begin
5139
  GetActiveTree(Tree);
5140
  Node := Tree.GetFirstSelected;
5141
  Data := Tree.GetNodeData(Node);
5142
  if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
5143
    exit;
5144
  Data.Rate := (Sender as TMenuItem).Tag;
5145
  BookTreeStatus := bsBusy;
5146
  if GetActiveView <> FavoritesView then
5147
  begin
5066
  begin
5067
    GetActiveTree(Tree);
5068
    Node := Tree.GetFirstSelected;
5069
    Data := Tree.GetNodeData(Node);
5070
    if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
5071
      Exit;
5072
    Data.Rate := (Sender as TMenuItem).tag;
5073
    BookTreeStatus := bsBusy;
5074
    if GetActiveView <> FavoritesView then
5075
    begin
5148
5076
5149
    DMUser.SetRate(Data.ID, Data.Rate);
5077
      DMUser.SetRate(Data.ID, Data.Rate);
5150
5078
5151
    //
5079
      //
5152
    // Синхронизация с избранным
    //
5080
      // Синхронизация с избранным
      //
5153
    if (DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID',
5081
      if (DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID', VarArrayOf([DMUser.ActiveCollection.ID, Data.ID]), [])) then
5154
                                  VarArrayOf([DMUser.ActiveCollection.ID,Data.ID]),[]))
5082
      begin
5155
    then
5083
        DMUser.tblGrouppedBooks.Edit;
5084
        DMUser.tblGrouppedBooksRate.Value := Data.Rate;
5085
        DMUser.tblGrouppedBooks.Post;
5086
        FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
5087
      end;
5088
    end
5089
    else // активная вкладка - избранное
5156
    begin
5090
    begin
5091
      DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;', VarArrayOf([DMUser.ActiveCollection.ID, Data.ID]), []);
5157
      DMUser.tblGrouppedBooks.Edit;
5092
      DMUser.tblGrouppedBooks.Edit;
5158
      DMUser.tblGrouppedBooksRate.Value := Data.Rate;
5093
      DMUser.tblGrouppedBooksRate.Value := Data.Rate;
5159
      DMUser.tblGrouppedBooks.Post;
5094
      DMUser.tblGrouppedBooks.Post;
5160
      FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
5161
    end;
5162
  end
5163
  else // активная вкладка - избранное
5164
  begin
5165
    DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;',
5166
                                    VarArrayOf([DMUser.ActiveCollection.ID,Data.ID]),[]);
5167
    DMUser.tblGrouppedBooks.Edit;
5168
    DMUser.tblGrouppedBooksRate.Value := Data.Rate;
5169
    DMUser.tblGrouppedBooks.Post;
5170
5095
5171
    //
5096
      //
5172
    // Синхронизация с таблицей рейтингов
5097
      // Синхронизация с таблицей рейтингов
5173
    //
5098
      //
5174
5099
5175
    DMUser.SetRate(DMUser.tblGrouppedBooksOuterID.Value, Data.Rate);
5100
      DMUser.SetRate(DMUser.tblGrouppedBooksOuterId.Value, Data.Rate);
5176
5101
5177
    FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
5102
      FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
    end;
5178
    FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
      FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
5103
5104
    Tree.RepaintNode(Node);
5105
    BookTreeStatus := bsFree;
5179
  end;
5106
  end;
5180
5107
5181
  Tree.RepaintNode(Node);
5108
  procedure TfrmMain.btnSavePresetClick(Sender: TObject);
5182
  BookTreeStatus := bsFree;
5109
  const
5183
end;
5110
    d = '~;~';
5111
  var
5112
    SL: TStringList;
5113
    S: string;
5114
    FN: string;
5184
5115
5185
procedure TfrmMain.btnSavePresetClick(Sender: TObject);
5116
  begin
5186
const d='~;~';
5117
    if cbPresetName.text = '' then
5187
var
5118
      Exit;
5188
  SL : TStringList;
5189
  S  : String;
5190
  FN: string;
5191
5119
5192
begin
5120
    FN := cbPresetName.text + '.mhlf';
5193
  if cbPresetName.Text = '' then Exit;
5194
5121
5195
  FN := cbPresetName.Text + '.mhlf';
5122
    if not FileExists(Settings.PresetPath + FN) then
5123
      cbPresetName.Items.Add(cbPresetName.text);
5196
5124
5197
  if not FileExists(Settings.PresetPath + FN) then
5125
    SL := TStringList.Create;
5198
    cbPresetName.Items.Add(cbPresetName.Text);
5126
    try
5127
      S := '~' + edFFullName.text + d + edFTitle.text + d + edFSeries.text + d + edFGenre.text + d + edFGenre.Hint + d + edFAnnotation.text + d + edFFile.text + d + edFFolder.text + d + edFExt.text + d + cbDate.text + d + cbDownloaded.text + d + BoolToStr(cbDeleted.Checked) + d + cbLang.text + d + edFKeyWords.text + '~';
5199
5128
5200
  SL := TStringList.Create;
5129
      SL.Add(S);
5201
  try
5130
      SL.SaveToFile(Settings.PresetPath + FN, TEncoding.UTF8);
5202
    S := '~' + edFFullName.Text + d +
5203
         edFTitle.Text + d +
5204
         edFSeries.Text + d +
5205
         edFGenre.Text + d +
5206
         edFGenre.Hint + d +
5207
         edFAnnotation.Text + d +
5208
         edFFile.Text + d +
5209
         edFFolder.Text + d +
5210
         edFExt.Text + d +
5211
         cbDate.Text + d +
5212
         cbDownloaded.Text + d +
5213
         BoolToStr(cbDeleted.Checked) + d +
5214
         cbLang.Text + d +
5215
         edFKeyWords.Text + '~';
5216
5131
5217
    SL.Add(S);
5132
      btnDeletePreset.Enabled := True;
5218
    SL.SaveToFile(Settings.PresetPath + FN,TEncoding.UTF8);
5133
    finally
5219
5134
      SL.Free;
5220
    btnDeletePreset.Enabled := True;
5135
    end;
5221
  finally
5222
    SL.Free;
5223
  end;
5136
  end;
5224
end;
5225
5137
5226
procedure TfrmMain.LocateAuthor(text: String; Tree: TVirtualStringTree);
5138
  procedure TfrmMain.LocateAuthor(text: string; Tree: TVirtualStringTree);
5227
var
5139
  var
5228
  Node: PVirtualNode;
5140
    Node: PVirtualNode;
5229
  Data: PAuthorData;
5141
    Data: PAuthorData;
5230
  L : integer;
5142
    L: Integer;
5231
begin
5143
  begin
5232
  Tree.ClearSelection;
5144
    Tree.ClearSelection;
5233
  Node := Tree.GetFirst;
5145
    Node := Tree.GetFirst;
5234
5146
5235
  L := Length(text);
5147
    L := Length(text);
5236
  text := AnsiUpperCase(text);
5148
    text := AnsiUpperCase(text);
5237
5149
5238
  while Assigned(Node) do
5150
    while Assigned(Node) do
5239
  begin
5240
    Data := Tree.GetNodeData(Node);
5241
    Assert(Assigned(Data));
5242
    if text = Copy(AnsiUpperCase(Data.Text),1,L) then
5243
    begin
5151
    begin
5244
      Tree.Selected[Node] := True;
5152
      Data := Tree.GetNodeData(Node);
5245
      Tree.FocusedNode := Node;
5153
      Assert(Assigned(Data));
5246
      Exit;
5154
      if text = copy(AnsiUpperCase(Data.text), 1, L) then
5155
      begin
5156
        Tree.Selected[Node] := True;
5157
        Tree.FocusedNode := Node;
5158
        Exit;
5159
      end;
5160
      Node := Tree.GetNext(Node);
5247
    end;
5161
    end;
5248
    Node := Tree.GetNext(Node);
5249
  end;
5162
  end;
5250
end;
5251
5163
5252
procedure TfrmMain.LocateBook(text: String; Next: boolean );
5164
  procedure TfrmMain.LocateBook(text: string; Next: Boolean);
5253
var
5165
  var
5254
  Node: PVirtualNode;
5166
    Node: PVirtualNode;
5255
  Data: PBookData;
5167
    Data: PBookData;
5256
  L : integer;
5168
    L: Integer;
5257
  Tree: TVirtualStringTree;
5169
    Tree: TVirtualStringTree;
5258
begin
5170
  begin
5259
  GetActiveTree(Tree);
5171
    GetActiveTree(Tree);
5260
5172
5261
  Tree.ClearSelection;
5173
    Tree.ClearSelection;
5262
5174
5263
  if not Next then FLastFoundBook := Nil;
5175
    if not Next then
5176
      FLastFoundBook := nil;
5264
5177
5178
    if Next and (FLastFoundBook <> nil) then
5179
      Node := Tree.GetNext(FLastFoundBook)
5180
    else
5181
      Node := Tree.GetFirst;
5265
5182
5266
  if Next and (FLastFoundBook <> Nil) then
5183
    L := Length(text);
5267
    Node := Tree.GetNext(FLastFoundBook)
5184
    text := AnsiUpperCase(text);
5268
  else
5269
    Node := Tree.GetFirst;
5270
5185
5271
  L := Length(text);
5186
    while Assigned(Node) do
5272
  text := AnsiUpperCase(text);
5273
5274
  while Assigned(Node) do
5275
  begin
5276
    Data := Tree.GetNodeData(Node);
5277
    Assert(Assigned(Data));
5278
    if text = Copy(AnsiUpperCase(Data.Title),1,L) then
5279
    begin
5187
    begin
5280
      Tree.Selected[Node] := True;
5188
      Data := Tree.GetNodeData(Node);
5281
      Tree.FocusedNode := Node;
5189
      Assert(Assigned(Data));
5190
      if text = copy(AnsiUpperCase(Data.Title), 1, L) then
5191
      begin
5192
        Tree.Selected[Node] := True;
5193
        Tree.FocusedNode := Node;
5282
5194
5283
      if not next then
5195
        if not Next then
5284
           FFirstFoundBook := Node;
5196
          FFirstFoundBook := Node;
5285
5197
5286
      FLastFoundBook := Node;
5198
        FLastFoundBook := Node;
5287
5199
5288
      Exit;
5200
        Exit;
5201
      end;
5202
      Node := Tree.GetNext(Node);
5289
    end;
5203
    end;
5290
    Node := Tree.GetNext(Node);
5291
  end;
5292
5204
5293
  if FFirstFoundBook <> nil then
5205
    if FFirstFoundBook <> nil then
5294
  begin
5206
    begin
5295
    FLastFoundBook := FFirstFoundBook;
5207
      FLastFoundBook := FFirstFoundBook;
5296
5208
5297
    Tree.FocusedNode := FLastFoundBook;
5209
      Tree.FocusedNode := FLastFoundBook;
5298
    Tree.Selected[FLastFoundBook] := True;
5210
      Tree.Selected[FLastFoundBook] := True;
5211
    end;
5212
5299
  end;
5213
  end;
5300
5214
5301
end;
5215
  procedure TfrmMain.edLocateAuthorChange(Sender: TObject);
5302
5216
  var
5303
procedure TfrmMain.edLocateAuthorChange(Sender: TObject);
5217
    S: string;
5304
var
5218
    OldText: string;
5305
  S : string;
5306
  OldText:string;
5307
begin
5308
  if FIgnoreChange then Exit;
5309
  S := AnsiUpperCase(copy(edLocateAuthor.Text,1,1));
5310
  if S <> FLastLetterA.Caption then
5311
  begin
5219
  begin
5312
    OldText := edLocateAuthor.Text;
5220
    if FIgnoreChange then
5313
    ChangeLetterButton(S);
5221
      Exit;
5314
    edLocateAuthor.Text := OldText;
5222
    S := AnsiUpperCase(copy(edLocateAuthor.text, 1, 1));
5315
    edLocateAuthor.Perform(WM_KEYDOWN, VK_RIGHT, 0);
5223
    if S <> FLastLetterA.Caption then
5224
    begin
5225
      OldText := edLocateAuthor.text;
5226
      ChangeLetterButton(S);
5227
      edLocateAuthor.text := OldText;
5228
      edLocateAuthor.Perform(WM_KEYDOWN, vk_Right, 0);
5229
    end;
5230
    if not FDoNotLocate then
5231
      LocateAuthor(edLocateAuthor.text, tvAuthors);
5316
  end;
5232
  end;
5317
  if not FDoNotLocate then
5318
    LocateAuthor(edLocateAuthor.Text, tvAuthors);
5319
end;
5320
5233
5321
procedure TfrmMain.edLocateAuthorKeyDown(Sender: TObject; var Key: Word;
5234
  procedure TfrmMain.edLocateAuthorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
5322
  Shift: TShiftState);
5323
5235
5324
begin
5325
  if ActiveView = ByAuthorView then
5326
  begin
5236
  begin
5327
    if Key = VK_UP then
5237
    if ActiveView = ByAuthorView then
5328
      tvAuthors.Perform(WM_KEYDOWN, VK_UP, 0);
5329
    if Key = VK_DOWN  then
5330
      tvAuthors.Perform(WM_KEYDOWN, VK_DOWN, 0);
5331
    if Key = VK_RETURN then
5332
    begin
5238
    begin
5333
      tvAuthorsClick(Sender);
5239
      if Key = VK_UP then
5334
      frmMain.ActiveControl := tvBooksA;
5240
        tvAuthors.Perform(WM_KEYDOWN, VK_UP, 0);
5241
      if Key = VK_DOWN then
5242
        tvAuthors.Perform(WM_KEYDOWN, VK_DOWN, 0);
5243
      if Key = VK_RETURN then
5244
      begin
5245
        tvAuthorsClick(Sender);
5246
        frmMain.ActiveControl := tvBooksA;
5247
      end;
5335
    end;
5248
    end;
5249
5250
    if ActiveView = BySeriesView then
5251
    begin
5252
      if Key = VK_UP then
5253
        tvSeries.Perform(WM_KEYDOWN, VK_UP, 0);
5254
      if Key = VK_DOWN then
5255
        tvSeries.Perform(WM_KEYDOWN, VK_DOWN, 0);
5256
      if Key = VK_RETURN then
5257
        if Key = VK_RETURN then
5258
        begin
5259
          tvSeriesClick(Sender);
5260
          frmMain.ActiveControl := tvBooksS;
5261
        end;
5262
    end;
5336
  end;
5263
  end;
5337
5264
5338
  if ActiveView = BySeriesView then
5265
  procedure TfrmMain.edFFullNameButtonClick(Sender: TObject);
5266
  var
5267
    frmEditor: TfrmEditor;
5339
  begin
5268
  begin
5340
    if Key = VK_UP then
5269
    frmEditor := TfrmEditor.Create(self);
5341
      tvSeries.Perform(WM_KEYDOWN, VK_UP, 0);
5270
    try
5342
    if Key = VK_DOWN  then
5271
      frmEditor.text := (Sender as TRzButtonEdit).text;
5343
      tvSeries.Perform(WM_KEYDOWN, VK_DOWN, 0);
5272
      if frmEditor.ShowModal = mrOk then (Sender as TRzButtonEdit)
5344
        if Key = VK_RETURN then
5273
        .text := frmEditor.text;
5345
    if Key = VK_RETURN then
5274
    finally
5346
    begin
5275
      frmEditor.Free;
5347
      tvSeriesClick(Sender);
5348
      frmMain.ActiveControl := tvBooksS;
5349
    end;
5276
    end;
5350
  end;
5277
  end;
5351
end;
5352
5278
5353
procedure TfrmMain.edFFullNameButtonClick(Sender: TObject);
5279
  procedure TfrmMain.edFFullNameKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
5354
var
5280
  begin
5355
  frmEditor: TfrmEditor;
5281
    if Key = VK_RETURN then
5356
begin
5282
      btnApplyFilterClick(Sender);
5357
  frmEditor := TfrmEditor.Create(Self);
5358
  try
5359
     frmEditor.Text := (Sender as TrzButtonEdit).Text;
5360
     if frmEditor.ShowModal = mrOk then
5361
       (Sender as TrzButtonEdit).Text := frmEditor.Text;
5362
  finally
5363
    frmEditor.Free;
5364
  end;
5283
  end;
5365
end;
5366
5284
5367
procedure TfrmMain.edFFullNameKeyDown(Sender: TObject; var Key: Word;
5285
  procedure TfrmMain.edFGenreButtonClick(Sender: TObject);
5368
  Shift: TShiftState);
5286
  var
5369
begin
5287
    Data: PGenreData;
5370
  if Key = VK_RETURN then
5288
    Node: PVirtualNode;
5371
    btnApplyFilterClick(Sender);
5372
end;
5373
5374
procedure TfrmMain.edFGenreButtonClick(Sender: TObject);
5375
var
5376
  Data : PGenreData;
5377
  Node : PVirtualNode;
5378
begin
5379
  FillGenresTree(frmGenreTree.tvGenresTree);
5380
  if frmGenreTree.ShowModal=mrOk then
5381
  begin
5289
  begin
5382
    edFGenre.Text := '';
5290
    FillGenresTree(frmGenreTree.tvGenresTree);
5383
    edFGenre.Hint:= '';
5291
    if frmGenreTree.ShowModal = mrOk then
5384
    with frmGenreTree.tvGenresTree do
5385
    begin
5292
    begin
5386
      Node := GetFirstSelected;
5293
      edFGenre.text := '';
5387
      while Node <> Nil do
5294
      edFGenre.Hint := '';
5295
      with frmGenreTree.tvGenresTree do
5388
      begin
5296
      begin
5389
        Data :=GetNodeData(Node);
5297
        Node := GetFirstSelected;
5390
        if edFGenre.Text = '' then
5298
        while Node <> nil do
5391
        begin
5299
        begin
5392
          edFGenre.Text := Data.Text;
5300
          Data := GetNodeData(Node);
5393
          edFGenre.Hint := Format('(g.GL_Code = "%s")',[Data.Code]);
5301
          if edFGenre.text = '' then
5394
        end
5302
          begin
5395
        else begin
5303
            edFGenre.text := Data.text;
5396
          edFGenre.Text := edFGenre.Text + '/' + Data.Text;
5304
            edFGenre.Hint := Format('(g.GL_Code = "%s")', [Data.Code]);
5397
          edFGenre.Hint := Format('%s OR (g.GL_Code = "%s")',[edFGenre.Hint, Data.Code]);
5305
          end
5306
          else
5307
          begin
5308
            edFGenre.text := edFGenre.text + '/' + Data.text;
5309
            edFGenre.Hint := Format('%s OR (g.GL_Code = "%s")', [edFGenre.Hint, Data.Code]);
5310
          end;
5311
          Node := GetNextSelected(Node, False);
5398
        end;
5312
        end;
5399
        Node := GetNextSelected(Node,False);
5400
      end;
5313
      end;
5401
    end;
5314
    end;
5402
  end;
5315
  end;
5403
end;
5404
5316
5405
procedure TfrmMain.edFGenreKeyPress(Sender: TObject; var Key: Char);
5317
  procedure TfrmMain.edFGenreKeyPress(Sender: TObject; var Key: Char);
5406
begin
5407
  if Key = chr(8) then
5408
  begin
5318
  begin
5409
    edFGenre.Text := '';
5319
    if Key = chr(8) then
5410
    edFGenre.Hint := '';
5320
    begin
5321
      edFGenre.text := '';
5322
      edFGenre.Hint := '';
5323
    end;
5324
    Key := chr(0);
5411
  end;
5325
  end;
5412
  Key := chr(0);
5413
end;
5414
5326
5415
procedure TfrmMain.edLocateSeriesChange(Sender: TObject);
5327
  procedure TfrmMain.edLocateSeriesChange(Sender: TObject);
5416
var
5328
  var
5417
  S : string;
5329
    S: string;
5418
  OldText:string;
5330
    OldText: string;
5419
begin
5420
  if FIgnoreChange or (Length(edLocateSeries.Text)=0) then Exit;
5421
  S := AnsiUpperCase(copy(edLocateSeries.Text,1,1));
5422
  if S <> FLastLetterS.Caption then
5423
  begin
5331
  begin
5424
    OldText := edLocateSeries.Text;
5332
    if FIgnoreChange or (Length(edLocateSeries.text) = 0) then
5425
    ChangeLetterButton(S);
5333
      Exit;
5426
    edLocateSeries.Text := OldText;
5334
    S := AnsiUpperCase(copy(edLocateSeries.text, 1, 1));
5427
    edLocateSeries.Perform(WM_KEYDOWN, VK_RIGHT, 0);
5335
    if S <> FLastLetterS.Caption then
5336
    begin
5337
      OldText := edLocateSeries.text;
5338
      ChangeLetterButton(S);
5339
      edLocateSeries.text := OldText;
5340
      edLocateSeries.Perform(WM_KEYDOWN, vk_Right, 0);
5341
    end;
5342
    if not FDoNotLocate then
5343
      LocateAuthor(edLocateSeries.text, tvSeries);
5428
  end;
5344
  end;
5429
  if not FDoNotLocate then
5430
    LocateAuthor(edLocateSeries.Text, tvSeries);
5431
end;
5432
5345
5433
procedure TfrmMain.FillAuthorTree(Tree: TVirtualStringTree; FullMode: boolean);
5346
  procedure TfrmMain.FillAuthorTree(Tree: TVirtualStringTree; FullMode: Boolean);
5434
var
5347
  var
5435
  Node: PVirtualNode;
5348
    Node: PVirtualNode;
5436
  NodeData: PAuthorData;
5349
    NodeData: PAuthorData;
5437
begin
5350
  begin
5438
  Tree.NodeDataSize := Sizeof(TAuthorData);
5351
    Tree.NodeDataSize := SizeOf(TAuthorData);
5439
5352
5440
  Tree.BeginUpdate;
5353
    Tree.BeginUpdate;
5441
  try
5442
    Tree.Clear;
5443
    dmCollection.tblAuthors.DisableControls;
5444
5445
    if FullMode then dmCollection.tblAuthors.Filtered := False;
5446
5447
    try
5354
    try
5448
      dmCollection.tblAuthors.First;
5355
      Tree.Clear;
5356
      dmCollection.tblAuthors.DisableControls;
5449
5357
5450
      if dmCollection.tblAuthorsFamily.IsNull then
5358
      if FullMode then
5451
        tvBooksA.Clear;
5359
        dmCollection.tblAuthors.Filtered := False;
5452
5360
5453
      while not dmCollection.tblAuthors.Eof do
5361
      try
5454
      begin
5362
        dmCollection.tblAuthors.First;
5455
        Node := Tree.AddChild(nil);
5456
        NodeData := Tree.GetNodeData(Node);
5457
        NodeData.ID := dmCollection.tblAuthorsID.Value;
5458
5363
5459
        if FullMode then
5364
        if dmCollection.tblAuthorsFamily.IsNull then
5365
          tvBooksA.Clear;
5366
5367
        while not dmCollection.tblAuthors.Eof do
5460
        begin
5368
        begin
5461
          NodeData.First := dmCollection.tblAuthorsName.Value;
5369
          Node := Tree.AddChild(nil);
5462
          NodeData.Last := dmCollection.tblAuthorsFamily.Value;
5370
          NodeData := Tree.GetNodeData(Node);
5463
          NodeData.Middle := dmCollection.tblAuthorsMiddle.Value;
5371
          NodeData.ID := dmCollection.tblAuthorsID.Value;
5464
          NodeData.Text := NodeData.Last + ' ' + NodeData.First + ' ' + NodeData.Middle;
5465
        end
5466
        else
5467
          NodeData.Text := trim(dmCollection.tblAuthorsFamily.Value + ' ' +
5468
                                dmCollection.tblAuthorsName.Value +  ' ' +
5469
                                dmCollection.tblAuthorsMiddle.Value);
5470
5372
5471
        dmCollection.tblAuthors.Next;
5373
          if FullMode then
5374
          begin
5375
            NodeData.First := dmCollection.tblAuthorsName.Value;
5376
            NodeData.Last := dmCollection.tblAuthorsFamily.Value;
5377
            NodeData.Middle := dmCollection.tblAuthorsMiddle.Value;
5378
            NodeData.text := NodeData.Last + ' ' + NodeData.First + ' ' + NodeData.Middle;
5379
          end
5380
          else
5381
            NodeData.text := trim(dmCollection.tblAuthorsFamily.Value + ' ' + dmCollection.tblAuthorsName.Value + ' ' + dmCollection.tblAuthorsMiddle.Value);
5382
5383
          dmCollection.tblAuthors.Next;
5384
        end;
5385
      finally
5386
        dmCollection.tblAuthors.EnableControls;
5472
      end;
5387
      end;
5388
      /// dmCollection.tblAuthors.First;
5389
5390
      Tree.Selected[Tree.GetFirst] := True;
5473
    finally
5391
    finally
5474
      dmCollection.tblAuthors.EnableControls;
5392
      Tree.EndUpdate;
5393
      if FullMode then
5394
        dmCollection.tblAuthors.Filtered := True;
5475
    end;
5395
    end;
5476
    /// dmCollection.tblAuthors.First;
5477
5478
    Tree.Selected[Tree.GetFirst] := True;
5479
  finally
5480
    Tree.EndUpdate;
5481
    if FullMode then dmCollection.tblAuthors.Filtered := True;
5482
  end;
5396
  end;
5483
end;
5484
5397
5485
procedure TfrmMain.FillSeriesTree;
5398
  procedure TfrmMain.FillSeriesTree;
5486
var
5399
  var
5487
  Node: PVirtualNode;
5400
    Node: PVirtualNode;
5488
  NodeData: PAuthorData;
5401
    NodeData: PAuthorData;
5489
begin
5402
  begin
5490
  tvSeries.NodeDataSize := Sizeof(TAuthorData);
5403
    tvSeries.NodeDataSize := SizeOf(TAuthorData);
5491
5404
5492
  tvSeries.BeginUpdate;
5405
    tvSeries.BeginUpdate;
5493
  try
5494
    tvSeries.Clear;
5495
5496
    dmCollection.tblSeries.DisableControls;
5497
    try
5406
    try
5498
      dmCollection.tblSeries.First;
5407
      tvSeries.Clear;
5499
5408
5500
      if dmCollection.tblSeriesTitle.IsNull then
5409
      dmCollection.tblSeries.DisableControls;
5501
        tvBooksS.Clear;
5410
      try
5411
        dmCollection.tblSeries.First;
5502
5412
5503
      while not dmCollection.tblSeries.Eof do
5413
        if dmCollection.tblSeriesTitle.IsNull then
5504
      begin
5414
          tvBooksS.Clear;
5505
        Node := tvSeries.AddChild(nil);
5415
5506
        NodeData := tvSeries.GetNodeData(Node);
5416
        while not dmCollection.tblSeries.Eof do
5507
        NodeData.ID := dmCollection.tblSeriesID.AsInteger;
5417
        begin
5508
        NodeData.Text := dmCollection.tblSeriesTitle.AsString;
5418
          Node := tvSeries.AddChild(nil);
5509
        dmCollection.tblSeries.Next;
5419
          NodeData := tvSeries.GetNodeData(Node);
5420
          NodeData.ID := dmCollection.tblSeriesID.AsInteger;
5421
          NodeData.text := dmCollection.tblSeriesTitle.AsString;
5422
          dmCollection.tblSeries.Next;
5423
        end;
5424
      finally
5425
        dmCollection.tblSeries.EnableControls;
5510
      end;
5426
      end;
5427
      /// dmCollection.tblSeries.First;
5511
    finally
5428
    finally
5512
      dmCollection.tblSeries.EnableControls;
5429
      tvSeries.EndUpdate;
5513
    end;
5430
    end;
5514
    /// dmCollection.tblSeries.First;
5515
  finally
5516
    tvSeries.EndUpdate;
5517
  end;
5431
  end;
5518
end;
5519
5432
5520
procedure TfrmMain.FillGenresTree(Tree: TVirtualStringTree; FillFB2: boolean);
5433
  procedure TfrmMain.FillGenresTree(Tree: TVirtualStringTree; FillFB2: Boolean);
5521
var
5434
  var
5522
  genreNode: PVirtualNode;
5435
    genreNode: PVirtualNode;
5523
  genreData: PGenreData;
5436
    genreData: PGenreData;
5524
  Nodes: TStringList;
5437
    Nodes: TStringList;
5525
  strParentCode: string;
5438
    strParentCode: string;
5526
  nParentIndex: Integer;
5439
    nParentIndex: Integer;
5527
  ParentNode: PVirtualNode;
5440
    ParentNode: PVirtualNode;
5528
begin
5441
  begin
5529
  Nodes := TStringList.Create;
5442
    Nodes := TStringList.Create;
5530
  Nodes.Sorted := True;
5443
    Nodes.Sorted := True;
5531
  try
5532
    Tree.NodeDataSize := SizeOf(TGenreData);
5533
5534
    Tree.BeginUpdate;
5535
    try
5444
    try
5536
      Tree.Clear;
5445
      Tree.NodeDataSize := SizeOf(TGenreData);
5537
5446
5538
      dmCollection.tblGenres.First;
5447
      Tree.BeginUpdate;
5539
      while not dmCollection.tblGenres.Eof do
5448
      try
5540
      begin
5449
        Tree.Clear;
5541
        strParentCode := dmCollection.tblGenresG_ParentCode.Value;
5542
5450
5543
        ParentNode := nil;
5451
        dmCollection.tblGenres.First;
5544
        if (strParentCode <> '0') and Nodes.Find(strParentCode, nParentIndex) then
5452
        while not dmCollection.tblGenres.Eof do
5545
          ParentNode := PVirtualNode(Nodes.Objects[nParentIndex]);
5453
        begin
5454
          strParentCode := dmCollection.tblGenresG_ParentCode.Value;
5546
5455
5547
        genreNode := Tree.AddChild(ParentNode);
5456
          ParentNode := nil;
5457
          if (strParentCode <> '0') and Nodes.Find(strParentCode, nParentIndex) then
5458
            ParentNode := PVirtualNode(Nodes.Objects[nParentIndex]);
5548
5459
5549
        genreData := Tree.GetNodeData(genreNode);
5460
          genreNode := Tree.AddChild(ParentNode);
5550
        genreData.id := dmCollection.tblGenresG_ID.Value;
5551
        genreData.Text := dmCollection.tblGenresG_Alias.Value;
5552
        genreData.Code := dmCollection.tblGenresG_Code.Value;
5553
        genreData.ParentCode := strParentCode;
5554
5461
5555
        if FillFB2 then
5462
          genreData := Tree.GetNodeData(genreNode);
5556
          genredata.FB2Code := dmCollection.tblGenresG_FB2Code.Value;
5463
          genreData.ID := dmCollection.tblGenresG_ID.Value;
5464
          genreData.text := dmCollection.tblGenresG_Alias.Value;
5465
          genreData.Code := dmCollection.tblGenresG_Code.Value;
5466
          genreData.ParentCode := strParentCode;
5557
5467
5558
        Nodes.AddObject(genreData.Code, TObject(genreNode));
5468
          if FillFB2 then
5469
            genreData.FB2Code := dmCollection.tblGenresG_FB2Code.Value;
5559
5470
5560
        dmCollection.tblGenres.Next;
5471
          Nodes.AddObject(genreData.Code, TObject(genreNode));
5472
5473
          dmCollection.tblGenres.Next;
5474
        end;
5475
      finally
5476
        Tree.EndUpdate;
5561
      end;
5477
      end;
5562
    finally
5478
    finally
5563
      Tree.EndUpdate;
5479
      Nodes.Free;
5564
    end;
5480
    end;
5565
  finally
5566
    Nodes.Free;
5567
  end;
5481
  end;
5568
end;
5569
5482
5570
procedure TfrmMain.FillGroupsList;
5483
  procedure TfrmMain.FillGroupsList;
5571
var
5484
  var
5572
  Node : PVirtualNode;
5485
    Node: PVirtualNode;
5573
  Data : PGenreData;
5486
    Data: PGenreData;
5574
begin
5575
  tvGroups.Clear;
5576
5577
  DMUser.tblGroupList.First;
5578
  while not DMUser.tblGroupList.Eof do
5579
  begin
5487
  begin
5580
    Node := tvGroups.AddChild(Nil);
5488
    tvGroups.Clear;
5581
    Data := tvGroups.GetNodeData(Node);
5582
5489
5583
    Data.Text := DMUser.tblGroupListName.Value;
5490
    DMUser.tblGroupList.First;
5584
    Data.ID := DMUser.tblGroupListID.Value;
5491
    while not DMUser.tblGroupList.Eof do
5492
    begin
5493
      Node := tvGroups.AddChild(nil);
5494
      Data := tvGroups.GetNodeData(Node);
5585
5495
5586
    DMUser.tblGroupList.Next;
5496
      Data.text := DMUser.tblGroupListName.Value;
5587
  end;
5497
      Data.ID := DMUser.tblGroupListID.Value;
5588
5498
5589
  // активируем последнюю группу в списке
5499
      DMUser.tblGroupList.Next;
5590
  tvGroups.Selected[tvGroups.GetLast] := True;
5500
    end;
5591
end;
5592
5501
5593
procedure TfrmMain.miAboutClick(Sender: TObject);
5502
    // активируем последнюю группу в списке
5594
var
5503
    tvGroups.Selected[tvGroups.GetLast] := True;
5595
  frmAbout: TfrmAbout;
5596
begin
5597
  frmAbout := TfrmAbout.Create(Application);
5598
  try
5599
    frmAbout.ShowModal;
5600
  finally
5601
    frmAbout.Free;
5602
  end;
5504
  end;
5603
end;
5604
5505
5605
procedure TfrmMain.miActiveCollectionClick(Sender: TObject);
5506
  procedure TfrmMain.miAboutClick(Sender: TObject);
5606
var
5507
  var
5607
  I: integer;
5508
    frmAbout: TfrmAbout;
5608
begin
5609
  I := (Sender as TMenuItem).Tag;
5610
  if DMUser.ActivateCollection(I) then
5611
  begin
5509
  begin
5612
    (Sender as TMenuItem).Checked := True;
5510
    frmAbout := TfrmAbout.Create(Application);
5613
    Settings.ActiveCollection := I;
5511
    try
5614
    InitCollection(True);
5512
      frmAbout.ShowModal;
5513
    finally
5514
      frmAbout.Free;
5515
    end;
5615
  end;
5516
  end;
5616
end;
5617
5517
5618
function TfrmMain.ExtractBookToStream(CR: string; var Table: TAbsTable; var FS: TMemoryStream):boolean;
5518
  procedure TfrmMain.miActiveCollectionClick(Sender: TObject);
5619
var
5519
  var
5620
  Zip: TZipForge;
5520
    i: Integer;
5621
  F: TZFArchiveItem;
5521
  begin
5622
  NoFb2Info: boolean;
5522
    i := (Sender as TMenuItem).tag;
5523
    if DMUser.ActivateCollection(i) then
5524
    begin (Sender as TMenuItem)
5525
      .Checked := True;
5526
      Settings.ActiveCollection := i;
5527
      InitCollection(True);
5528
    end;
5529
  end;
5623
5530
5624
begin
5531
  function TfrmMain.ExtractBookToStream(CR: string; var Table: TAbsTable; var FS: TMemoryStream): Boolean;
5625
  NoFb2Info := False;
5532
  var
5626
  if ExtractFileExt(CR) = ZIP_EXTENSION then
5533
    Zip: TZipForge;
5534
    F: TZFArchiveItem;
5627
  begin
5535
  begin
5536
    Result := False;
5537
5628
    if not FileExists(CR) then
5538
    if not FileExists(CR) then
5539
    begin
5629
      if IsLocal then
5540
      if IsLocal then
5630
      begin
5541
        ShowMessage('Архив ' + CR + ' не найден!');
5631
         ShowMessage('Архив ' + CR + ' не найден!');
5542
      Exit;
5632
         Exit;
5543
    end;
5633
       end
5634
       else
5635
         NoFb2Info := True;
5636
5544
5637
      if not NoFb2Info then
5545
    if ExtractFileExt(CR) = ZIP_EXTENSION then
5638
      begin
5546
    begin
5639
        Zip := TZipForge.Create(Self);
5547
      Zip := TZipForge.Create(self);
5640
        try
5548
      try
5641
          Zip.FileName := CR;
5549
        Zip.FileName := CR;
5642
          Zip.OpenArchive;
5550
        Zip.OpenArchive;
5643
          Zip.ExtractToStream(GetFileNameZip(Zip,Table['InsideNo']),FS);
5551
        Zip.ExtractToStream(GetFileNameZip(Zip, Table['InsideNo']), FS);
5644
          Zip.CloseArchive;
5552
        Zip.CloseArchive;
5645
        finally
5553
5646
          Zip.Free;
5554
        Result := True;
5647
        end;
5555
      finally
5556
        Zip.Free;
5648
      end;
5557
      end;
5649
    end
5558
    end
5650
    else  // файл не внутри зипа
      if ExtractFileExt(Table['FileName']) = ZIP_EXTENSION then  // fbd
5559
    else if ExtractFileExt(Table['FileName']) = ZIP_EXTENSION then // fbd
5651
      begin
5560
    begin
5652
        if not NoFb2Info then
5561
      Zip := TZipForge.Create(self);
5653
        begin
5562
      try
5654
          Zip := TZipForge.Create(Self);
5563
        Zip.FileName := CR + Table['FileName'];
5655
          try
5564
        Zip.OpenArchive;
5656
            Zip.FileName := CR + Table['FileName'];
5565
        Zip.FindFirst('*.fbd', F);
5657
            Zip.OpenArchive;
5566
        Zip.ExtractToStream(F.FileName, FS);
5658
            zip.FindFirst('*.fbd',F);
5567
        Zip.CloseArchive;
5659
            Zip.ExtractToStream(F.FileName,FS);
5660
            Zip.CloseArchive;
5661
          finally
5662
            Zip.Free;
5663
          end;
5664
        end;
5665
      end
5666
      else
5667
        if not NoFb2Info then  // просто файл
5668
            FS.LoadFromFile(CR + Table['FileName'] + Table['Ext']);
5669
  Result := NoFb2Info;
5670
end;
5671
5568
5672
procedure TfrmMain.pmiBookInfoClick(Sender: TObject);
5569
        Result := True;
5673
var
5570
      finally
5674
  Tree: TVirtualStringTree;
5571
        Zip.Free;
5675
  CR, s: string;
5572
      end;
5676
  Data: PBookData;
5573
    end
5677
  Table, Extra: TAbsTable;
5574
    else
5678
  frmBookDetails: TfrmBookDetails;
5575
    begin
5576
      //
5577
      // просто файл
5578
      //
5579
      FS.LoadFromFile(CR + Table['FileName'] + Table['Ext']);
5679
5580
5680
  FS : TMemoryStream;
5581
      Result := True;
5681
  ReviewEditable: boolean;
5582
    end;
5583
  end;
5682
5584
5683
  URL: string;
5585
  procedure TfrmMain.pmiBookInfoClick(Sender: TObject);
5684
begin
5586
  var
5685
  // if not isFb2 then Exit;
5587
    Tree: TVirtualStringTree;
5588
    CR: string;
5589
    Data: PBookData;
5590
    Table, Extra: TAbsTable;
5591
    frmBookDetails: TfrmBookDetails;
5686
5592
5687
  GetActiveTree(Tree);
5593
    FS: TMemoryStream;
5594
    ReviewEditable: Boolean;
5688
5595
5689
  if Tree.FocusedNode= nil then
5596
    URL: string;
5690
      Exit;
5691
5597
5692
  Table := GetActiveBookTable(Tree.Tag);
5598
    R: TBookRecord;
5693
  Data := Tree.GetNodeData(Tree.FocusedNode);
5599
    strReview: string;
5600
  begin
5601
    // if not isFb2 then Exit;
5694
5602
5695
  if not Assigned(Data) or (Data.nodeType <> ntBookInfo) or Table.IsEmpty then
5603
    GetActiveTree(Tree);
5696
    Exit;
5604
    Assert(Assigned(Tree));
5697
5605
5698
  Table.Locate('ID', Data.ID, []);
5606
    if not Assigned(Tree.FocusedNode) then
5699
  FFormBusy := True;
5607
      Exit;
5700
  if DMUser.ActiveCollection.URL <> ''then
5701
    URL :=  Format('%sb/%d/',[DMUser.ActiveCollection.URL, Table.FieldByName('LibID').AsInteger])
5702
  else
5703
    URL :=  Format('%sb/%d/',[Settings.InpxURL, Table.FieldByName('LibID').AsInteger]);
5704
5608
5705
  frmBookDetails := TfrmBookDetails.Create(Application);
5609
    Table := GetActiveBookTable(Tree.tag);
5610
    Data := Tree.GetNodeData(Tree.FocusedNode);
5706
5611
5707
  ReviewEditable := true;
5612
    if not Assigned(Data) or (Data.nodeType <> ntBookInfo) or Table.IsEmpty then
5613
      Exit;
5708
5614
5709
  if ActiveView = FavoritesView then
5615
    FFormBusy := True;
5710
  begin
5616
    try
5711
    Extra := dmUser.tblExtra;
5617
      Table.Locate('ID', Data.ID, []);
5712
    CR := GetFullBookPath(Table,'');
5618
      dmCollection.GetCurrentBook(R);
5713
5619
5714
    ReviewEditable := (Table['DatabaseID'] =  DMUser.ActiveCollection.ID);
5620
      { TODO -oNickR -cLibDesc : этот URL должен формироваться обвязкой библиотеки, т к его формат может меняться }
5715
    frmBookDetails.mmReview.ReadOnly := not ReviewEditable;
5621
      if DMUser.ActiveCollection.URL <> '' then
5622
        URL := Format('%sb/%d/', [DMUser.ActiveCollection.URL, Table.FieldByName('LibID').AsInteger])
5623
      else
5624
        URL := Format('%sb/%d/', [Settings.InpxURL, Table.FieldByName('LibID').AsInteger]);
5716
5625
5717
  end
5626
      ReviewEditable := True;
5718
  else  begin
5719
    Extra := dmCollection.tblExtra;
5720
    CR := GetFullBookPath(Table,FCollectionRoot);
5721
  end;
5722
5627
5723
  FS := TMemoryStream.Create;
5628
      if ActiveView = FavoritesView then
5724
  try
5629
      begin
5725
    if not ExtractBookToStream(CR, Table, FS) then
5630
        Extra := DMUser.tblExtra;
5726
    begin
5631
        CR := GetFullBookPath(Table, '');
5727
      frmBookDetails.TabSheet1.TabVisible := True;
5728
      frmBookDetails.RzPageControl1.ActivePageIndex := 0;
5729
    end
5730
    else
5731
    begin
5732
      frmBookDetails.TabSheet1.TabVisible := False;
5733
      frmBookDetails.RzPageControl1.ActivePageIndex := 1;
5734
    end;
5735
5632
5736
    try
5633
        ReviewEditable := (Table['DatabaseID'] = DMUser.ActiveCollection.ID);
5737
      frmBookDetails.ShowBookInfo(FS);
5634
      end
5738
      frmBookDetails.mmInfo.Lines.Add('Добавлено: ' + Table.FieldByName('Date').AsString);
5635
      else
5636
      begin
5637
        Extra := dmCollection.tblExtra;
5638
        CR := GetFullBookPath(Table, FCollectionRoot);
5639
      end;
5739
5640
5740
        if not isPrivate and ReviewEditable  then
5641
      frmBookDetails := TfrmBookDetails.Create(Application);
5741
            frmBookDetails.AllowOnlineReview(URL);
5642
      try
5643
        // frmBookDetails.Book := R;
5644
        frmBookDetails.mmReview.readonly := not ReviewEditable;
5742
5645
5646
        FS := TMemoryStream.Create;
5647
        try
5648
          { TODO -oNickR -cRefactoring : не очень удачный прототип функции. Использование результата неочевидно }
5649
          if ExtractBookToStream(CR, Table, FS) then
5650
          begin
5651
            // frmBookDetails.tsInfo.TabVisible := True;
5652
            // frmBookDetails.RzPageControl1.ActivePageIndex := 0;
5653
            frmBookDetails.FillBookInfo(R, FS);
5654
            { TODO -oNickR : восстановить этот код }
5655
            // frmBookDetails.mmInfo.Lines.Add('Добавлено: ' + Table.FieldByName('Date').AsString);
5656
          end
5657
          else
5658
          begin
5659
            // frmBookDetails.tsInfo.TabVisible := False;
5660
            // frmBookDetails.tsReview.TabVisible := False;
5661
            // frmBookDetails.RzPageControl1.ActivePageIndex := 1;
5662
            frmBookDetails.FillBookInfo(R, nil);
5663
          end;
5664
        finally
5665
          FS.Free;
5666
        end;
5667
5668
        if not IsPrivate and ReviewEditable then
5669
          frmBookDetails.AllowOnlineReview(URL);
5670
5743
        if Table['Code'] = 1 then
5671
        if Table['Code'] = 1 then
5744
          frmBookDetails.Review := Extra.FieldByName('E_Review').AsWideString
5672
          frmBookDetails.Review := Extra.FieldByName('E_Review').AsWideString
5745
        else
5673
        else if not IsPrivate and Settings.AutoLoadReview then
5746
          if not isPrivate and Settings.AutoLoadReview then
5674
          DownloadReview(frmBookDetails, URL);
5747
            DownloadReview(frmBookDetails, URL);
5748
5675
5749
        frmBookDetails.ShowModal;
5676
        frmBookDetails.ShowModal;
5750
5677
5751
        // обрабатываем рецензию
5678
        if not frmBookDetails.ReviewChanged then
5752
        if frmBookDetails.ReviewChanged then
5679
          Exit;
5753
        begin
5754
          case Table['Code'] of     // сначала - основгая таблица
5755
            0:  if (frmBookDetails.Review <> '') then
5756
                begin
5757
                  if Extra.RecordCount = 0 then
5758
                  begin
5759
                    Extra.Insert;
5760
                    Extra.FieldByName('E_Review').AsWideString := frmBookDetails.Review;
5761
                    Extra.Post;
5762
                  end
5763
                  else
5764
                  begin
5765
                    Extra.Edit;
5766
                    Extra.FieldByName('E_Review').AsWideString := frmBookDetails.Review;
5767
                    Extra.Post;
5768
                  end;
5769
5680
5770
                  Table.Edit;
5681
        strReview := frmBookDetails.Review;
5771
                  Table['Code'] := Table['Code'] or 1;
5682
      finally
5772
                  Table.Post;
5683
        FreeAndNil(frmBookDetails);
5684
      end;
5773
5685
5774
                  Data.Code := 1;
5686
      //
5775
                  Tree.RepaintNode(Tree.FocusedNode);
5687
      // обрабатываем рецензию
5776
                end;
5688
      //
5777
            1: if frmBookDetails.Review <> '' then
5689
      { TODO -oNickR -cRefactoring : хорошо бы вынести этот код куда-нибудь в более подходящее место }
5778
               begin
5690
      case Table['Code'] of // сначала - основная таблица
5779
                  Extra.Edit;
5691
        0:
5780
                  Extra.FieldByName('E_Review').AsWideString := frmBookDetails.Review;
5692
          if (strReview <> '') then
5781
                  Extra.Post;
5693
          begin
5782
                end
5694
            if Extra.RecordCount = 0 then
5783
                else
5695
              Extra.Insert
5784
                begin // рецензия была, а теперь ее нет
5696
            else
5785
                  Table.Edit;
5697
              Extra.Edit;
5786
                  Table['Code'] := 0;
5787
                  Table.Post;
5788
                  Extra.Delete;
5789
                end;
5790
          end; // case
5791
5698
5792
          // затем синхронизация
5699
            Extra.FieldByName('E_Review').AsWideString := strReview;
5700
            Extra.Post;
5793
5701
5794
          if ActiveView <> FavoritesView then
5702
            Table.Edit;
5703
            Table['Code'] := Table['Code'] or 1;
5704
            Table.Post;
5705
5706
            Data.Code := 1;
5707
            Tree.RepaintNode(Tree.FocusedNode);
5708
          end;
5709
5710
        1:
5711
          if strReview <> '' then
5795
          begin
5712
          begin
5796
            if DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;',
5713
            Extra.Edit;
5797
                            VarArrayOf([DMUser.ActiveCollection.ID,Data.ID]),[])
5714
            Extra.FieldByName('E_Review').AsWideString := strReview;
5798
            then       // если книга есть в избранном - синхронизируем
5715
            Extra.Post;
5799
            begin
5716
          end
5800
              DMUser.tblGrouppedBooks.Edit;
5717
          else
5801
              DMUser.tblGrouppedBooksCode.Value := Table['Code'];
5718
          begin // рецензия была, а теперь ее нет
5802
              DMUser.tblGrouppedBooks.Post;
5719
            Table.Edit;
5720
            Table['Code'] := 0;
5721
            Table.Post;
5722
            Extra.Delete;
5723
          end;
5724
      end; // case
5803
5725
5804
              if dmUser.tblExtra.Locate('ID',DMUser.tblGrouppedBooksID.Value,[]) then
5726
      // затем синхронизация
5805
              case Table['Code'] of
5727
5806
                0: if DMUser.tblExtra.RecordCount <> 0 then
5728
      if ActiveView <> FavoritesView then
5807
                      DMUser.tblExtra.Delete;
5729
      begin
5808
                1: begin
5730
        // если книга есть в избранном - синхронизируем
5809
                   dmUser.tblExtra.Edit;
5731
        if DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;', VarArrayOf([DMUser.ActiveCollection.ID, Data.ID]), []) then
5810
//                   dmUser.tblExtraReview.Value := frmBookDetails.Review;
5732
        begin
5811
                   dmUser.tblExtra.Post;
5733
          DMUser.tblGrouppedBooks.Edit;
5812
                 end;
5734
          DMUser.tblGrouppedBooksCode.Value := Table['Code'];
5813
              end
5735
          DMUser.tblGrouppedBooks.Post;
5814
              else
5736
5815
                if Table['Code'] = 1 then
5737
          if DMUser.tblExtra.Locate('ID', DMUser.tblGrouppedBooksID.Value, []) then
5738
          begin
5739
            case Table['Code'] of
5740
              0:
5741
                if DMUser.tblExtra.RecordCount <> 0 then
5742
                  DMUser.tblExtra.Delete;
5743
5744
              1:
5816
                begin
5745
                begin
5817
                  dmUser.tblExtra.Insert;
5746
                  DMUser.tblExtra.Edit;
5818
//                  dmUser.tblExtraReview.Value := frmBookDetails.Review;
5747
                  // dmUser.tblExtraReview.Value := frmBookDetails.Review;
5819
                  dmUser.tblExtra.Post;
5748
                  DMUser.tblExtra.Post;
5820
                end;
5749
                end;
5821
              FillBooksTree(0,tvBooksF,Nil,DMUser.tblGrouppedBooks,true, true);
5822
            end
5750
            end
5823
          end
5751
          end
5824
          else   // если активная вкладка - группы, вносим изменения в коллекцию
5752
          else if Table['Code'] = 1 then
5825
          begin
5753
          begin
5826
            DMCollection.tblBooks.Locate('Id', Table['OuterID'], []);
5754
            DMUser.tblExtra.Insert;
5827
            DMCollection.tblBooks.Edit;
5755
            // dmUser.tblExtraReview.Value := frmBookDetails.Review;
5828
            DMCollection.tblBooksCode.Value := Table['Code'];
5756
            DMUser.tblExtra.Post;
5829
            DMCollection.tblBooks.Post;
5757
          end;
5758
          FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
5759
        end
5760
      end
5761
      else // если активная вкладка - группы, вносим изменения в коллекцию
5762
      begin
5763
        dmCollection.tblBooks.Locate('Id', Table['OuterID'], []);
5764
        dmCollection.tblBooks.Edit;
5765
        dmCollection.tblBooksCode.Value := Table['Code'];
5766
        dmCollection.tblBooks.Post;
5830
5767
5831
            if DMCollection.tblExtraE_Review <> Nil then
5768
        if dmCollection.tblExtraE_Review <> nil then
5832
            case Table['Code'] of
5769
        begin
5833
              0: if DMCollection.tblExtra.RecordCount <> 0 then
5770
          case Table['Code'] of
5834
                        DMCollection.tblExtra.Delete;
5771
            0:
5835
              1: begin
5772
              if dmCollection.tblExtra.RecordCount <> 0 then
5836
                   DMCollection.tblExtra.Edit;
5773
                dmCollection.tblExtra.Delete;
5837
                   DMCollection.tblExtraE_Review.Value := frmBookDetails.Review;
5774
            1:
5838
                   DMCollection.tblExtra.Post;
5839
               end;
5840
            end
5841
            else
5842
              if Table['Code'] = 1 then
5843
              begin
5775
              begin
5844
                DMCollection.tblExtra.Insert;
5776
                dmCollection.tblExtra.Edit;
5845
                DMCollection.tblExtraE_Review.Value := frmBookDetails.Review;
5777
                dmCollection.tblExtraE_Review.Value := strReview;
5846
                DMCollection.tblExtra.Post;
5778
                dmCollection.tblExtra.Post;
5847
              end;
5779
              end;
5848
            FillAllBooksTree;
5780
          end
5849
          end;
5781
        end
5850
5782
        else if Table['Code'] = 1 then
5851
5783
        begin
5852
          Data.Code := Table['Code'];
5784
          dmCollection.tblExtra.Insert;
5853
          Tree.RepaintNode(Tree.FocusedNode);
5785
          dmCollection.tblExtraE_Review.Value := strReview;
5786
          dmCollection.tblExtra.Post;
5854
        end;
5787
        end;
5855
      finally
5788
        FillAllBooksTree;
5856
        FreeAndNil(frmBookDetails);
5857
      end;
5789
      end;
5858
  finally
5790
5859
    FS.Free;
5791
      Data.Code := Table['Code'];
5860
    FFormBusy := False;
5792
      Tree.RepaintNode(Tree.FocusedNode);
5793
    finally
5794
      FFormBusy := False;
5795
    end;
5861
  end;
5796
  end;
5862
end;
5863
5797
5864
procedure TfrmMain.miClearRateClick(Sender: TObject);
5798
  procedure TfrmMain.miClearRateClick(Sender: TObject);
5865
var
5799
  var
5866
  Tree: TVirtualstringTree;
5800
    Tree: TVirtualStringTree;
5867
  Data: PbookData;
5801
    Data: PBookData;
5868
  Node: PVirtualNode;
5802
    Node: PVirtualNode;
5869
begin
5870
  GetactiveTree(Tree);
5871
  Node := Tree.FocusedNode;
5872
  Data := Tree.GetNodeData(Node);
5873
  if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
5874
    Exit;
5875
  Data.Rate := 0;
5876
  BookTreeStatus := bsBusy;
5877
  if GetActiveView <> FavoritesView then
5878
  begin
5803
  begin
5879
    DMUser.DeleteRate(Data.ID);
5804
    GetActiveTree(Tree);
5880
5805
    Node := Tree.FocusedNode;
5881
    if DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID',
5806
    Data := Tree.GetNodeData(Node);
5882
                                  VarArrayOf([DMUser.ActiveCollection.ID,Data.ID]),[]) then
5807
    if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
5808
      Exit;
5809
    Data.Rate := 0;
5810
    BookTreeStatus := bsBusy;
5811
    if GetActiveView <> FavoritesView then
5883
    begin
5812
    begin
5884
      DMUser.tblGrouppedBooks.Edit;
5813
      DMUser.DeleteRate(Data.ID);
5885
      DMUser.tblGrouppedBooksRate.Value := 0;
5886
      DMUser.tblGrouppedBooks.Post;
5887
5814
5888
      FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
5815
      if DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID', VarArrayOf([DMUser.ActiveCollection.ID, Data.ID]), []) then
5889
    end;
5816
      begin
5890
  end
5817
        DMUser.tblGrouppedBooks.Edit;
5891
  else if DMUser.tblGrouppedBooks.Locate('ID',Data.ID,[]) then
5818
        DMUser.tblGrouppedBooksRate.Value := 0;
5819
        DMUser.tblGrouppedBooks.Post;
5820
5821
        FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
5822
      end;
5823
    end
5824
    else if DMUser.tblGrouppedBooks.Locate('ID', Data.ID, []) then
5892
    begin
5825
    begin
5893
      DMUser.tblGrouppedBooks.Edit;
5826
      DMUser.tblGrouppedBooks.Edit;
5894
      DMUser.tblGrouppedBooksRate.Value := 0;
5827
      DMUser.tblGrouppedBooksRate.Value := 0;
5895
      DMUser.tblGrouppedBooks.Post;
5828
      DMUser.tblGrouppedBooks.Post;
5896
5829
5897
      DMUser.DeleteRate(DMUser.tblGrouppedBooksOuterID.Value, DMUser.tblGrouppedBooksDatabaseID.Value);
5830
      DMUser.DeleteRate(DMUser.tblGrouppedBooksOuterId.Value, DMUser.tblGrouppedBooksDatabaseID.Value);
5898
5831
5899
      FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
5832
      FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
5900
      FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
    end;
5833
      FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
    end;
5901
5834
5902
  Tree.RepaintNode(Node);
5835
    Tree.RepaintNode(Node);
5903
  BookTreeStatus := bsFree;
5836
    BookTreeStatus := bsFree;
5904
end;
5837
  end;
5905
5838
5906
procedure TfrmMain.miQuitAppClick(Sender: TObject);
5839
  procedure TfrmMain.miQuitAppClick(Sender: TObject);
5907
begin
5840
  begin
5908
  Close;
5841
    Close;
5909
end;
5842
  end;
5910
5843
5911
procedure TfrmMain.pmiCheckAllClick(Sender: TObject);
5844
  procedure TfrmMain.pmiCheckAllClick(Sender: TObject);
5912
begin
5845
  begin
5913
  Selection(True);
5846
    Selection(True);
5914
end;
5847
  end;
5915
5848
5916
procedure TfrmMain.pmAuthorPopup(Sender: TObject);
5849
  procedure TfrmMain.pmAuthorPopup(Sender: TObject);
5917
begin
5850
  begin
5918
  miAddToSearch.Visible := (ActiveView <>  ByGenreView);
5851
    miAddToSearch.Visible := (ActiveView <> ByGenreView);
5919
end;
5852
  end;
5920
5853
5921
procedure TfrmMain.pmiDeselectAllClick(Sender: TObject);
5854
  procedure TfrmMain.pmiDeselectAllClick(Sender: TObject);
5922
begin
5855
  begin
5923
  Selection(False);
5856
    Selection(False);
5924
end;
5857
  end;
5925
5858
5926
procedure TfrmMain.pmiSelectAllClick(Sender: TObject);
5859
  procedure TfrmMain.pmiSelectAllClick(Sender: TObject);
5927
var
5860
  var
5928
  tree: TVirtualStringTree;
5861
    Tree: TVirtualStringTree;
5929
begin
5862
  begin
5930
  GetActiveTree(Tree);
5863
    GetActiveTree(Tree);
5931
  Tree.SelectAll(False);
5864
    Tree.SelectAll(False);
5932
end;
5865
  end;
5933
5866
5934
procedure TfrmMain.miGoForumClick(Sender: TObject);
5867
  procedure TfrmMain.miGoForumClick(Sender: TObject);
5935
begin
5868
  begin
5936
  ShellExecute(handle, 'open', '"http://myhomelib.org/"', nil, nil, SW_SHOW);
5869
    ShellExecute(Handle, 'open', '"http://myhomelib.org/"', nil, nil, SW_SHOW);
5937
end;
5870
  end;
5938
5871
5939
procedure TfrmMain.miGoSiteClick(Sender: TObject);
5872
  procedure TfrmMain.miGoSiteClick(Sender: TObject);
5940
begin
5873
  begin
5941
  ShellExecute(handle, 'open', 'http://home-lib.net/', nil, nil, SW_SHOW);
5874
    ShellExecute(Handle, 'open', 'http://home-lib.net/', nil, nil, SW_SHOW);
5942
end;
5875
  end;
5943
5876
5944
procedure TfrmMain.miGoToAuthorClick(Sender: TObject);
5877
  procedure TfrmMain.miGoToAuthorClick(Sender: TObject);
5945
var
5878
  var
5946
  I: integer;
5879
    i: Integer;
5947
  Data: PBookData;
5880
    Data: PBookData;
5948
  Node: PvirtualNode;
5881
    Node: PVirtualNode;
5949
  Tree: TVirtualstringTree;
5882
    Tree: TVirtualStringTree;
5950
  FN: string;
5883
    FN: string;
5951
begin
5884
  begin
5952
  GetActiveTree(Tree);
5885
    GetActiveTree(Tree);
5953
5886
5954
  Node := Tree.FocusedNode;
5887
    Node := Tree.FocusedNode;
5955
  Assert(Assigned(Node));
5888
    Assert(Assigned(Node));
5956
5889
5957
  Data := Tree.GetNodeData(Node);
5890
    Data := Tree.GetNodeData(Node);
5958
5891
5959
  if not Assigned(Data) then Exit;
5892
    if not Assigned(Data) then
5893
      Exit;
5960
5894
5961
  if (Data.nodeType <> ntBookInfo) then
5895
    if (Data.nodeType <> ntBookInfo) then
5962
  begin
5963
    if not Tree.HasChildren[Node] then Exit;
5964
    repeat
5965
      Node := Tree.GetFirstChild(Node);
5966
      Data := Tree.GetNodeData(Node);
5967
    until (Data.nodeType = ntBookInfo);
5968
  end;
5969
5970
  Screen.Cursor := crHourGlass;
5971
  try
5972
    if ActiveView = FavoritesView then
5973
    begin
5896
    begin
5974
      I := DMUser.tblGrouppedBooksDatabaseID.Value;
5897
      if not Tree.HasChildren[Node] then
5975
      if I <> Settings.ActiveCollection then
5898
        Exit;
5899
      repeat
5900
        Node := Tree.GetFirstChild(Node);
5901
        Data := Tree.GetNodeData(Node);
5902
      until (Data.nodeType = ntBookInfo);
5903
    end;
5904
5905
    Screen.Cursor := crHourGlass;
5906
    try
5907
      if ActiveView = FavoritesView then
5976
      begin
5908
      begin
5977
        if DMUser.ActivateCollection(I) then
5909
        i := DMUser.tblGrouppedBooksDatabaseID.Value;
5910
        if i <> Settings.ActiveCollection then
5978
        begin
5911
        begin
5979
          Settings.ActiveCollection := I;
5912
          if DMUser.ActivateCollection(i) then
5980
          InitCollection(True);
5913
          begin
5981
          CreateCollectionMenu;
5914
            Settings.ActiveCollection := i;
5982
        end
5915
            InitCollection(True);
5983
        else
5916
            CreateCollectionMenu;
5984
        begin
5917
          end
5985
          Screen.Cursor := crDefault;
5918
          else
5986
          ShowMessage('Коллекция не зарегистрирована !');
5919
          begin
5987
          Exit;
5920
            Screen.Cursor := crDefault;
5921
            ShowMessage('Коллекция не зарегистрирована !');
5922
            Exit;
5923
          end;
5988
        end;
5924
        end;
5989
      end;
5925
        DMUser.tblGrouppedBooks.Locate('ID', Data.ID, []);
5990
      DMUser.tblGrouppedBooks.Locate('ID', Data.ID, []);
5926
        FN := DMUser.tblGrouppedBooksFullName.Value;
5991
      FN := DMUser.tblGrouppedBooksFullName.Value;
5927
      end
5992
    end
5928
      else
5993
    else
5929
        FN := dmCollection.FullName(Data.ID);
5994
      FN := dmCollection.FullName(Data.ID);
5930
      pgControl.ActivePageIndex := 0;
5995
    pgControl.ActivePageIndex := 0;
5931
      edLocateAuthor.text := FN;
5996
    edLocateAuthor.Text := FN;
5932
      LocateBook(Data.Title, False);
5997
    LocateBook(Data.Title, False);
5933
    finally
5998
  finally
5934
      Screen.Cursor := crDefault;
5999
    Screen.Cursor := crDefault;
5935
    end;
6000
  end;
5936
  end;
6001
end;
6002
5937
6003
procedure TfrmMain.miCheckUpdatesClick(Sender: TObject);
5938
  procedure TfrmMain.miCheckUpdatesClick(Sender: TObject);
6004
var
5939
  var
6005
  SL: TStringList;
5940
    SL: TStringList;
6006
  LF: TMemoryStream;
5941
    LF: TMemoryStream;
6007
  i: integer;
5942
    i: Integer;
6008
  S: string;
5943
    S: string;
6009
  HTTP: TidHTTP;
5944
    HTTP: TidHTTP;
6010
begin
5945
  begin
6011
  LF := TMemoryStream.Create;
5946
    LF := TMemoryStream.Create;
6012
  try
6013
    SL := TStringList.Create;
6014
    try
5947
    try
6015
      HTTP := TidHTTP.Create;
5948
      SL := TStringList.Create;
6016
      SetProxySettings(HTTP);
6017
      try
5949
      try
6018
        Http.Get(InclideUrlSlash(Settings.UpdateURL)+PROGRAM_VERINFO_FILENAME, LF);
5950
        HTTP := TidHTTP.Create;
6019
      except
5951
        SetProxySettings(HTTP);
5952
        try
5953
          HTTP.Get(InclideUrlSlash(Settings.UpdateURL) + PROGRAM_VERINFO_FILENAME, LF);
5954
        except
6020
          on E: EIdSocketError do
5955
          on E: EIdSocketError do
6021
            if E.LastError = 11001 then
5956
            if E.LastError = 11001 then
6022
              ShowMessage('Проверка обновления не удалось! Сервер не найден.'+
5957
              ShowMessage('Проверка обновления не удалось! Сервер не найден.' + #13 + 'Код ошибки: ' + IntToStr(E.LastError))
6023
                           #13+'Код ошибки: '+IntToStr(E.LastError))
6024
            else
5958
            else
6025
              ShowMessage('Проверка обновления не удалось! Ошибка подключения.'+
5959
              ShowMessage('Проверка обновления не удалось! Ошибка подключения.' + #13 + 'Код ошибки: ' + IntToStr(E.LastError));
6026
                           #13+'Код ошибки: '+IntToStr(E.LastError));
5960
          on E: Exception do
6027
           on E: Exception do
5961
            ShowMessage('Проверка обновления не удалось! Сервер сообщает об ошибке ' + #13 + 'Код ошибки: ' + IntToStr(HTTP.ResponseCode));
6028
             ShowMessage('Проверка обновления не удалось! Сервер сообщает об ошибке '+
5962
        end;
6029
                          #13+'Код ошибки: '+IntToStr(HTTP.ResponseCode));
5963
        { TODO -oNickR -cRefactoring : проверить использование файла last_version.info. Возможно он больше нигде не нужен и можно не сохранять его на диск }
6030
      end;
5964
        LF.SaveToFile(Settings.SystemFileName[sfAppVerInfo]);
6031
      { TODO -oNickR -cRefactoring : проверить использование файла last_version.info. Возможно он больше нигде не нужен и можно не сохранять его на диск }
5965
        SL.LoadFromFile(Settings.SystemFileName[sfAppVerInfo]);
6032
      LF.SaveToFile(Settings.SystemFileName[sfAppVerInfo]);
5966
        if SL.Count > 0 then
6033
      SL.LoadFromFile(Settings.SystemFileName[sfAppVerInfo]);
5967
          if CompareStr(VersionInfo.FileVersion, SL[0]) < 0 then
6034
      if SL.Count > 0 then
5968
          begin
6035
        if CompareStr(VersionInfo.FileVersion, SL[0]) < 0 then
5969
            S := #13;
6036
        begin
5970
            for i := 1 to SL.Count - 1 do
6037
          S := #13;
5971
              S := S + '  ' + SL[i] + #13;
6038
          for I := 1 to SL.Count - 1 do
6039
            S := S + '  ' + SL[i] + #13;
6040
5972
6041
          ShowMessage('Доступна новая версия - ' + SL[0] + #13 + S + #13 +
5973
            ShowMessage('Доступна новая версия - ' + SL[0] + #13 + S + #13 + 'Посетите сайт программы для загрузки обновлений.');
6042
            'Посетите сайт программы для загрузки обновлений.');
5974
          end
6043
        end
5975
          else if not FAutoCheck then
6044
        else if not FAutoCheck then
5976
            ShowMessage('У вас самая свежая версия.');
6045
          ShowMessage('У вас самая свежая версия.');
5977
        FAutoCheck := False;
6046
      FAutoCheck := False;
5978
      finally
5979
        HTTP.Free;
5980
        SL.Free;
5981
      end;
6047
    finally
5982
    finally
6048
      HTTP.Free;
5983
      LF.Free;
6049
      SL.Free;
6050
    end;
5984
    end;
6051
  finally
6052
    LF.Free;
6053
  end;
5985
  end;
6054
end;
6055
5986
6056
procedure TfrmMain.miStatClick(Sender: TObject);
5987
  procedure TfrmMain.miStatClick(Sender: TObject);
6057
var
5988
  var
6058
  frmStat: TfrmStat;
5989
    frmStat: TfrmStat;
6059
begin
5990
  begin
6060
  DMUser.ActivateCollection(Settings.ActiveCollection);
5991
    DMUser.ActivateCollection(Settings.ActiveCollection);
6061
5992
6062
  frmStat := TfrmStat.Create(Application);
5993
    frmStat := TfrmStat.Create(Application);
6063
  try
5994
    try
6064
    frmStat.LoadCollectionInfo;
5995
      frmStat.LoadCollectionInfo;
6065
    frmStat.ShowModal;
5996
      frmStat.ShowModal;
6066
  finally
5997
    finally
6067
    frmStat.Free;
5998
      frmStat.Free;
5999
    end;
6068
  end;
6000
  end;
6069
end;
6070
6001
6071
procedure TfrmMain.miSyncOnlineClick(Sender: TObject);
6002
  procedure TfrmMain.miSyncOnlineClick(Sender: TObject);
6072
begin
6003
  begin
6073
  SavePositions;
6004
    SavePositions;
6074
6005
6075
  if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
6006
    if isOnlineCollection(DMUser.ActiveCollection.CollectionType) then
6076
      unit_Utils.SyncOnLineFiles
6007
      unit_Utils.SyncOnLineFiles
6077
    else
6008
    else
6078
      unit_Utils.SyncFolders;
6009
      unit_Utils.SyncFolders;
6079
  InitCollection(True);
6010
    InitCollection(True);
6080
6011
6081
  RestorePositions;
6012
    RestorePositions;
6082
end;
6013
  end;
6083
6014
6084
procedure TfrmMain.miUpdateClick(Sender: TObject);
6015
  procedure TfrmMain.miUpdateClick(Sender: TObject);
6085
var
6016
  var
6086
  ActiveColIndex:  integer;
6017
    ActiveColIndex: Integer;
6087
begin
6088
  if CheckLibUpdates(False) then
6089
  begin
6018
  begin
6090
    SavePositions;
6019
    if CheckLibUpdates(False) then
6020
    begin
6021
      SavePositions;
6091
6022
6092
    ActiveColIndex := DMUser.ActiveCollection.ID;
6023
      ActiveColIndex := DMUser.ActiveCollection.ID;
6093
    StartLibUpdate;
6024
      StartLibUpdate;
6094
    Settings.ActiveCollection := ActiveColIndex;
6025
      Settings.ActiveCollection := ActiveColIndex;
6095
    DMUser.ActivateCollection(ActiveColIndex);
6026
      DMUser.ActivateCollection(ActiveColIndex);
6096
    InitCollection(True);
6027
      InitCollection(True);
6097
6028
6098
    RestorePositions;
6029
      RestorePositions;
6030
    end;
6099
  end;
6031
  end;
6100
end;
6101
6032
6102
procedure TfrmMain.mi_dwnl_LocateAuthorClick(Sender: TObject);
6033
  procedure TfrmMain.mi_dwnl_LocateAuthorClick(Sender: TObject);
6103
var
6034
  var
6104
  Data: PDownloadData;
6035
    Data: PDownloadData;
6105
begin
6106
  Data := tvDownloadList.GetNodeData(tvDownloadList.FocusedNode);
6107
  if Data <> nil then
6108
  begin
6036
  begin
6109
    pgControl.ActivePageIndex := 0;
6037
    Data := tvDownloadList.GetNodeData(tvDownloadList.FocusedNode);
6110
    edLocateAuthor.Text := Data.Author;
6038
    if Data <> nil then
6111
    LocateBook(Data.Title, False);
6039
    begin
6040
      pgControl.ActivePageIndex := 0;
6041
      edLocateAuthor.text := Data.Author;
6042
      LocateBook(Data.Title, False);
6043
    end;
6112
  end;
6044
  end;
6113
end;
6114
6045
6115
procedure TfrmMain.N27Click(Sender: TObject);
6046
  procedure TfrmMain.N27Click(Sender: TObject);
6116
begin
6047
  begin
6117
  DeleteFile(Settings.SystemFileName[sfColumnsStore]);
6048
    DeleteFile(Settings.SystemFileName[sfColumnsStore]);
6118
  SetColumns;
6049
    SetColumns;
6119
  SetHeaderPopUp;
6050
    SetHeaderPopUp;
6120
end;
6051
  end;
6121
6052
6122
procedure TfrmMain.miCompactDataBaseClick(Sender: TObject);
6053
  procedure TfrmMain.miCompactDataBaseClick(Sender: TObject);
6123
begin
6054
  begin
6124
  try
6055
    try
6125
    dmCollection.DBCollection.Close;
6056
      dmCollection.DBCollection.Close;
6126
    dmCollection.DBCollection.CompactDatabase;
6057
      dmCollection.DBCollection.CompactDatabase;
6127
  except
6058
    except
6128
6059
6060
    end;
6061
    dmCollection.DBCollection.Open;
6062
    DMUser.SetTableState(True);
6063
    dmCollection.SetTableState(True);
6129
  end;
6064
  end;
6130
  dmCollection.DBCollection.Open;
6131
  dmUser.SetTableState(True);
6132
  dmCollection.SetTableState(True);
6133
end;
6134
6065
6135
procedure TfrmMain.miConverToFBDClick(Sender: TObject);
6066
  procedure TfrmMain.miConverToFBDClick(Sender: TObject);
6136
begin
6137
  if (ActiveView = FavoritesView) or (ActiveView = DownloadView) then
6138
  begin
6067
  begin
6139
    MessageDlg('Для конвертации книги перейдите ' + #13 + 'в соответствующую коллекцию', mtWarning, [mbOk], 0);
6068
    if (ActiveView = FavoritesView) or (ActiveView = DownloadView) then
6140
    Exit;
6069
    begin
6070
      MessageDlg('Для конвертации книги перейдите ' + #13 + 'в соответствующую коллекцию', mtWarning, [mbOk], 0);
6071
      Exit;
6072
    end;
6073
    frmConvertToFBD.EditorMode := miConverToFBD.tag <> 0;
6074
    frmConvertToFBD.ShowModal;
6141
  end;
6075
  end;
6142
  frmConvertToFBD.EditorMode := miConverToFBD.Tag <> 0;
6143
  frmConvertToFBD.ShowModal;
6144
end;
6145
6076
6146
procedure TfrmMain.N33Click(Sender: TObject);
6077
  procedure TfrmMain.N33Click(Sender: TObject);
6147
begin
6078
  begin
6148
  Close;
6079
    Close;
6149
end;
6080
  end;
6150
6081
6151
procedure TfrmMain.N34Click(Sender: TObject);
6082
  procedure TfrmMain.N34Click(Sender: TObject);
6152
begin
6083
  begin
6153
  if DirectoryExists(Settings.ReadDir) then ClearDir(Settings.ReadDir);
6084
    if DirectoryExists(Settings.ReadDir) then
6154
end;
6085
      ClearDir(Settings.ReadDir);
6086
  end;
6155
6087
6156
procedure TfrmMain.miEditToolbarVisibleClick(Sender: TObject);
6088
  procedure TfrmMain.miEditToolbarVisibleClick(Sender: TObject);
6157
begin
6089
  begin
6158
  tlbrEdit.Visible := miEditToolbarVisible.Checked;
6090
    tlbrEdit.Visible := miEditToolbarVisible.Checked;
6159
  Settings.EditToolbarVisible := tlbrEdit.Visible;
6091
    Settings.EditToolbarVisible := tlbrEdit.Visible;
6160
end;
6092
  end;
6161
6093
6162
procedure TfrmMain.miExportToHTMLClick(Sender: TObject);
6094
  procedure TfrmMain.miExportToHTMLClick(Sender: TObject);
6163
const
6095
  const
6164
  HTMLHead = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">'#13#10 +
6096
    HTMLHead = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">'#13#10 + '<html>'#13#10 + '<head>'#13#10 + '  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">'#13#10 + '  <title>MyHomeLib HTML</title>'#13#10 + '</head>'#13#10 + '<body>'#13#10;
6165
    '<html>'#13#10 +
6097
    HTMLFoot = '</body>'#13#10 + '</html>' + #13#10;
6166
    '<head>'#13#10 +
6167
    '  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">'#13#10 +
6168
    '  <title>MyHomeLib HTML</title>'#13#10 +
6169
    '</head>'#13#10 +
6170
    '<body>'#13#10;
6171
  HTMLFoot = '</body>'#13#10 +
6172
    '</html>' + #13#10;
6173
6098
6174
  ext : array [351 .. 353 ] of string = ('html','txt','rtf');
6099
    Ext: array [351 .. 353] of string = ('html', 'txt', 'rtf');
6175
var
6100
  var
6176
  Tree : TVirtualStringTree;
6101
    Tree: TVirtualStringTree;
6177
  Fs: TFileStream;
6102
    FS: TFileStream;
6178
  Str: AnsiString;
6103
    Str: AnsiString;
6179
  Data: Pointer;
6104
    Data: Pointer;
6180
  FileName: string;
6105
    FileName: string;
6181
begin
6106
  begin
6182
  GetActiveTree(Tree);
6107
    GetActiveTree(Tree);
6183
  FileName := (Settings.TempPath + 'book_list.' + ext[(Sender as TMenuItem).Tag]);
6108
    FileName := (Settings.TempPath + 'book_list.' + Ext[(Sender as TMenuItem).tag]);
6184
  Fs := TFileStream.Create(FileName, fmCreate);
6109
    FS := TFileStream.Create(FileName, fmCreate);
6185
  try
6110
    try
6186
    case (Sender as TMenuItem).Tag of
6111
      case (Sender as TMenuItem).tag of
6187
      351:  Str := HTMLHead + Tree.ContentToHTML(tstAll) + HTMLFoot;
6112
        351:
6188
      352:  Str := Tree.ContentToUnicode(tstAll,chr(9));
6113
          Str := HTMLHead + Tree.ContentToHTML(tstAll) + HTMLFoot;
6189
      353:  Str := Tree.ContentToRTF(tstAll);
6114
        352:
6115
          Str := Tree.ContentToUnicode(tstAll, chr(9));
6116
        353:
6117
          Str := Tree.ContentToRTF(tstAll);
6118
      end;
6119
      Data := PChar(Str);
6120
      FS.WriteBuffer(Data^, Length(Str));
6121
    finally
6122
      FreeAndNil(FS);
6190
    end;
6123
    end;
6191
    Data := PChar(Str);
6124
    ShellExecute(Handle, 'open', PChar(FileName), nil, nil, SW_RESTORE);
6192
    Fs.WriteBuffer(Data^, Length(Str));
6193
  finally
6194
    FreeAndNil(fs);
6195
  end;
6125
  end;
6196
  ShellExecute(Handle, 'open', PChar(FileName), nil, nil, SW_RESTORE);
6197
end;
6198
6126
6199
procedure TfrmMain.miExportUserDataClick(Sender: TObject);
6127
  procedure TfrmMain.miExportUserDataClick(Sender: TObject);
6200
var
6128
  var
6201
  SL: TStringList;
6129
    SL: TStringList;
6202
  FN: string;
6130
    FN: string;
6203
  ID: integer;
6131
    ID: Integer;
6204
  S: String;
6132
    S: string;
6205
begin
6133
  begin
6206
  SL := TStringList.Create;
6134
    SL := TStringList.Create;
6207
  try
6135
    try
6208
6136
6209
    // Группы
6137
      // Группы
6210
    SL.Add('# Группы');
6138
      SL.Add('# Группы');
6211
    DMUser.tblGroupList.First;
6139
      DMUser.tblGroupList.First;
6212
    while not DMUser.tblGroupList.Eof do
6140
      while not DMUser.tblGroupList.Eof do
6213
    begin
6141
      begin
6214
      SL.Add(Format('%s',[DMUser.tblGroupListName.Value]));
6142
        SL.Add(Format('%s', [DMUser.tblGroupListName.Value]));
6215
      DMUser.tblGroupList.Next;
6143
        DMUser.tblGroupList.Next;
6216
    end;
6144
      end;
6217
6145
6218
    // Рейтинги
6146
      // Рейтинги
6219
6147
6220
    SL.Add('# Рейтинги');
6148
      SL.Add('# Рейтинги');
6221
    DMUser.tblRates.Filter := 'DataBaseID =' + QuotedStr(IntToStr(DMUser.ActiveCollection.ID));
6149
      DMUser.tblRates.Filter := 'DataBaseID =' + QuotedStr(IntToStr(DMUser.ActiveCollection.ID));
6222
    DMUser.tblRates.Filtered := True;
6150
      DMUser.tblRates.Filtered := True;
6223
    DMUser.tblRates.First;
6151
      DMUser.tblRates.First;
6224
    while not DMUser.tblRates.Eof do
6152
      while not DMUser.tblRates.Eof do
6225
    begin
6153
      begin
6226
      DMCollection.tblBooks.Locate('ID', DMUser.tblRatesBookID.Value, []);
6154
        dmCollection.tblBooks.Locate('ID', DMUser.tblRatesBookID.Value, []);
6227
      if DMCollection.tblBooksLibID.Value <> 0 then
6155
        if dmCollection.tblBooksLibID.Value <> 0 then
6228
        ID := DMCollection.tblBooksLibID.Value
6156
          ID := dmCollection.tblBooksLibID.Value
6229
      else
6157
        else
6230
        ID := DMCollection.tblBooksID.Value;
6158
          ID := dmCollection.tblBooksID.Value;
6231
6159
6232
      SL.Add(Format('%d %d',[ID, DMUser.tblRatesRate.Value]));
6160
        SL.Add(Format('%d %d', [ID, DMUser.tblRatesRate.Value]));
6233
      DMUser.tblRates.Next;
6161
        DMUser.tblRates.Next;
6234
    end;
6162
      end;
6235
    DMUser.tblRates.Filtered := False;
6163
      DMUser.tblRates.Filtered := False;
6236
6164
6237
    // Прочитанное
6165
      // Прочитанное
6238
6166
6239
    SL.Add('# Прочитанное');
6167
      SL.Add('# Прочитанное');
6240
    DMUser.tblFinished.Filter := 'DataBaseID =' + QuotedStr(IntToStr(DMUser.ActiveCollection.ID));
6168
      DMUser.tblFinished.Filter := 'DataBaseID =' + QuotedStr(IntToStr(DMUser.ActiveCollection.ID));
6241
    DMUser.tblFinished.Filtered := True;
6169
      DMUser.tblFinished.Filtered := True;
6242
    DMUser.tblFinished.First;
6170
      DMUser.tblFinished.First;
6243
    while not DMUser.tblFinished.Eof do
6171
      while not DMUser.tblFinished.Eof do
6244
    begin
6172
      begin
6245
      DMCollection.tblBooks.Locate('ID', DMUser.tblFinishedBookID.Value, []);
6173
        dmCollection.tblBooks.Locate('ID', DMUser.tblFinishedBookID.Value, []);
6246
      if DMCollection.tblBooksLibID.Value <> 0 then
6174
        if dmCollection.tblBooksLibID.Value <> 0 then
6247
        ID := DMCollection.tblBooksLibID.Value
6175
          ID := dmCollection.tblBooksLibID.Value
6248
      else
6176
        else
6249
        ID := DMCollection.tblBooksID.Value;
6177
          ID := dmCollection.tblBooksID.Value;
6250
6178
6251
      SL.Add(Format('%d %d',[ID, DMUser.tblFinishedProgress.Value]));
6179
        SL.Add(Format('%d %d', [ID, DMUser.tblFinishedProgress.Value]));
6252
      DMUser.tblFinished.Next;
6180
        DMUser.tblFinished.Next;
6253
    end;
6181
      end;
6254
    DMUser.tblFinished.Filtered := False;
6182
      DMUser.tblFinished.Filtered := False;
6255
6183
6256
6184
6257
    // избранное
6185
      // избранное
6258
6186
6259
    SL.Add('# Избранное');
6187
      SL.Add('# Избранное');
6260
6188
6261
    DMUser.tblGroupList.First;
6189
      DMUser.tblGroupList.First;
6262
    while not DMUser.tblGroupList.Eof do
6190
      while not DMUser.tblGroupList.Eof do
6263
    begin
6264
      DMUser.tblGrouppedBooks.Filter := 'DataBaseID =' + QuotedStr(IntToStr(DMUser.ActiveCollection.ID));
6265
      DMUser.tblGrouppedBooks.Filtered := True;
6266
      DMUser.tblGrouppedBooks.First;
6267
      while not DMUser.tblGrouppedBooks.Eof do
6268
      begin
6191
      begin
6269
        if DMUser.tblGrouppedBooksLibID.Value <> 0 then
6192
        DMUser.tblGrouppedBooks.Filter := 'DataBaseID =' + QuotedStr(IntToStr(DMUser.ActiveCollection.ID));
6270
           ID := DMUser.tblGrouppedBooksLibID.Value
6193
        DMUser.tblGrouppedBooks.Filtered := True;
6271
         else
6194
        DMUser.tblGrouppedBooks.First;
6272
           ID := DMUser.tblGrouppedBooksOuterID.Value;
6195
        while not DMUser.tblGrouppedBooks.Eof do
6273
        SL.Add(Format('%d %s',[ID, DMUser.tblGroupListName.AsWideString]));
6196
        begin
6274
        DMUser.tblGrouppedBooks.Next;
6197
          if DMUser.tblGrouppedBooksLibID.Value <> 0 then
6198
            ID := DMUser.tblGrouppedBooksLibID.Value
6199
          else
6200
            ID := DMUser.tblGrouppedBooksOuterId.Value;
6201
          SL.Add(Format('%d %s', [ID, DMUser.tblGroupListName.AsWideString]));
6202
          DMUser.tblGrouppedBooks.Next;
6203
        end;
6204
        DMUser.tblGroupList.Next;
6275
      end;
6205
      end;
6276
      DMUser.tblGroupList.Next;
6277
    end;
6278
6206
6279
    DMUser.tblGrouppedBooks.MasterSource := DMUser.dsGroupList;
6207
      DMUser.tblGrouppedBooks.MasterSource := DMUser.dsGroupList;
6280
6208
6281
    // избранное
6209
      // избранное
6282
6210
6283
    SL.Add('# Рецензии');
6211
      SL.Add('# Рецензии');
6284
6212
6285
    DMCollection.tblExtra.MasterSource := nil;
6213
      dmCollection.tblExtra.MasterSource := nil;
6286
    DMCollection.tblExtra.First;
6214
      dmCollection.tblExtra.First;
6287
    while not DMCollection.tblExtra.Eof do
6215
      while not dmCollection.tblExtra.Eof do
6288
    begin
6216
      begin
6289
      S := DMCollection.tblExtraE_Review.Value;
6217
        S := dmCollection.tblExtraE_Review.Value;
6290
      StrReplace(#13#10,'~',S);
6218
        StrReplace(#13#10, '~', S);
6291
      DMCollection.tblBooks.Locate('ID', DMCollection.tblExtraE_BookID.Value, []);
6219
        dmCollection.tblBooks.Locate('ID', dmCollection.tblExtraE_BookID.Value, []);
6292
      if DMCollection.tblBooksLibID.Value <> 0 then
6220
        if dmCollection.tblBooksLibID.Value <> 0 then
6293
        ID := DMCollection.tblBooksLibID.Value
6221
          ID := dmCollection.tblBooksLibID.Value
6294
      else
6222
        else
6295
        ID := DMCollection.tblBooksID.Value;
6223
          ID := dmCollection.tblBooksID.Value;
6296
6224
6297
      SL.Add(Format('%d %s',[ID, S]));
6225
        SL.Add(Format('%d %s', [ID, S]));
6298
      DMCollection.tblExtra.Next;
6226
        dmCollection.tblExtra.Next;
6299
    end;
6227
      end;
6300
    DMCollection.tblExtra.MasterSource := DMCollection.dsBooks;
6228
      dmCollection.tblExtra.MasterSource := dmCollection.dsBooks;
6301
6229
6302
    if GetFileName(fnSaveUserData,FN) = true then   //шутка
6230
      if GetFileName(fnSaveUserData, FN) = True then // шутка
6303
          SL.SaveToFile(FN, TEncoding.UTF8);
6231
        SL.SaveToFile(FN, TEncoding.UTF8);
6304
6232
6305
  finally
6233
    finally
6306
    SL.Free;
6234
      SL.Free;
6235
    end;
6307
  end;
6236
  end;
6308
end;
6309
6237
6310
procedure TfrmMain.HeaderPopupItemClick(Sender: TObject);
6238
  procedure TfrmMain.HeaderPopupItemClick(Sender: TObject);
6311
var
6239
  var
6312
  i: integer;
6240
    i: Integer;
6313
  Tree : TVirtualstringTree;
6241
    Tree: TVirtualStringTree;
6314
  Tag: integer;
6242
    tag: Integer;
6315
  Column: TVirtualTreeColumn;
6243
    Column: TVirtualTreeColumn;
6316
6244
6317
  S: string;
6245
    S: string;
6318
  MinWidth, MaxWidth : integer;
6246
    MinWidth, MaxWidth: Integer;
6319
  Options: TVTColumnOptions;
6247
    Options: TVTColumnOptions;
6320
  Alignment: TAlignment;
6248
    Alignment: TAlignment;
6321
6249
6322
begin
6250
  begin
6323
  GetActiveTree(Tree);
6251
    GetActiveTree(Tree);
6324
6252
6325
  Tag := (Sender as TMenuItem).Tag;
6253
    tag := (Sender as TMenuItem).tag;
6326
6254
6327
  if (Sender as TMenuItem).Checked then
6255
    if (Sender as TMenuItem).Checked then
6328
  begin           // удаляем
6256
    begin // удаляем
6329
    for I := 0 to Tree.Header.Columns.Count - 1 do
6257
      for i := 0 to Tree.Header.Columns.Count - 1 do
6330
      if Tree.Header.Columns[i].Tag = Tag then
6258
        if Tree.Header.Columns[i].tag = tag then
6331
      begin
6259
        begin
6332
        Tree.Header.Columns.Delete(i);
6260
          Tree.Header.Columns.Delete(i); (Sender as TMenuItem)
6333
        (Sender as TMenuItem).Checked := False;
6261
          .Checked := False;
6334
        Break;
6262
          Break;
6335
      end;
6263
        end;
6336
  end
6264
    end
6337
  else
6265
    else
6338
  begin           // добавляем
6266
    begin // добавляем
6339
    Column := TVirtualTreeColumn.Create(Tree.Header.Columns);
6267
      Column := TVirtualTreeColumn.Create(Tree.Header.Columns);
6340
6268
6341
    GetDefaultColumnProperties(Settings.TreeModes[Tree.Tag],Tag,
6269
      GetDefaultColumnProperties(Settings.TreeModes[Tree.tag], tag, S, MinWidth, MaxWidth, Alignment, Options);
6342
                         S,
6270
      Column.tag := tag;
6343
                         MinWidth,
6271
      Column.text := S;
6344
                         MaxWidth,
6272
      Column.MinWidth := MinWidth;
6345
                         Alignment,
6273
      Column.MaxWidth := MaxWidth;
6346
                         Options
6274
      Column.Alignment := Alignment;
6347
                         );
6275
      Column.Options := Options; (Sender as TMenuItem)
6348
    Column.Tag := Tag;
6276
      .Checked := True;
6349
    Column.Text := S;
6277
    end;
6350
    Column.MinWidth := MinWidth;
6278
    SaveColumns;
6351
    Column.MaxWidth := MaxWidth;
6352
    Column.Alignment:= Alignment;
6353
    Column.Options  := Options;
6354
    (Sender as TMenuItem).Checked := True;
6355
  end;
6279
  end;
6356
  SaveColumns;
6357
end;
6358
6280
6359
function TfrmMain.HH(Command: Word; Data: Integer;
6281
  function TfrmMain.HH(Command: Word; Data: Integer; var CallHelp: Boolean): Boolean;
6360
  var CallHelp: Boolean): Boolean;
6282
  begin
6361
begin
6283
    if Data = 0 then
6362
  if Data = 0 then
6284
      HtmlHelp(Application.Handle, PChar(Settings.SystemFileName[sfAppHelp]), HH_DISPLAY_TOC, 0)
6363
      HtmlHelp(Application.Handle,
6285
    else
6364
        PChar(Settings.SystemFileName[sfAppHelp]),
6286
      HtmlHelp(Application.Handle, PChar(Settings.SystemFileName[sfAppHelp]), HH_HELP_CONTEXT, Data);
6365
        HH_DISPLAY_TOC, 0)
6366
  else
6367
      HtmlHelp(Application.Handle,
6368
        PChar(Settings.SystemFileName[sfAppHelp]),
6369
        HH_HELP_CONTEXT, Data);
6370
6287
6371
  CallHelp := False;
6288
    CallHelp := False;
6372
end;
6289
  end;
6373
6290
6374
procedure TfrmMain.miCollectionExportClick(Sender: TObject);
6291
  procedure TfrmMain.miCollectionExportClick(Sender: TObject);
6375
begin
6292
  begin
6376
  if MessageDlg('Экспорт в xml работает в режиме совместимости со старыми версиями.'+#10#13 +
6293
    if MessageDlg('Экспорт в xml работает в режиме совместимости со старыми версиями.' + #10#13 + 'Не все данные будут сохранены. Рекомендуется использовать экспорт в inpx.' + #10#13 + 'Продолжить?', mtWarning, [mbYes, mbNo], 0) = mrNo then
6377
                'Не все данные будут сохранены. Рекомендуется использовать экспорт в inpx.'+#10#13 +
6294
      Exit;
6378
                'Продолжить?'
6379
                ,mtWarning,[mbYes,mbNo],0)=mrNo then Exit;
6380
6295
6381
  DMUser.ActivateCollection(Settings.ActiveCollection);
6296
    DMUser.ActivateCollection(Settings.ActiveCollection);
6382
  unit_Export.Export2XML;
6297
    unit_Export.Export2XML;
6383
end;
6298
  end;
6384
6299
6385
procedure TfrmMain.miCollectionImportClick(Sender: TObject);
6300
  procedure TfrmMain.miCollectionImportClick(Sender: TObject);
6386
begin
6301
  begin
6387
  DMUser.ActivateCollection(Settings.ActiveCollection);
6302
    DMUser.ActivateCollection(Settings.ActiveCollection);
6388
  dmCollection.DBCollection.Connected := False;
6303
    dmCollection.DBCollection.Connected := False;
6389
6304
6390
  unit_Import.ImportXML(DMUser.ActiveCollection);
6305
    unit_Import.ImportXML(DMUser.ActiveCollection);
6391
6306
6392
  InitCollection(True);
6307
    InitCollection(True);
6393
end;
6308
  end;
6394
6309
6395
procedure TfrmMain.miCollsettingsClick(Sender: TObject);
6310
  procedure TfrmMain.miCollsettingsClick(Sender: TObject);
6396
var
6311
  var
6397
  frmBases: TfrmBases;
6312
    frmBases: TfrmBases;
6398
begin
6313
  begin
6399
  DMUser.ActivateCollection(Settings.ActiveCollection);
6314
    DMUser.ActivateCollection(Settings.ActiveCollection);
6400
6315
6401
  frmBases := TfrmBases.Create(Application);
6316
    frmBases := TfrmBases.Create(Application);
6402
  try
6317
    try
6403
    frmBases.tsConnectionInfo.TabVisible := isOnline;
6318
      frmBases.tsConnectionInfo.TabVisible := IsOnline;
6404
    if frmBases.ShowModal = mrOk then
6319
      if frmBases.ShowModal = mrOk then
6405
    begin
6320
      begin
6406
      Assert(Settings.ActiveCollection = DMUser.ActiveCollection.ID);
6321
        Assert(Settings.ActiveCollection = DMUser.ActiveCollection.ID);
6407
      CreateCollectionMenu;
6322
        CreateCollectionMenu;
6408
      InitCollection(True);
6323
        InitCollection(True);
6324
      end;
6325
    finally
6326
      frmBases.Free;
6409
    end;
6327
    end;
6410
  finally
6411
    frmBases.Free;
6412
  end;
6328
  end;
6413
end;
6414
6329
6415
procedure TfrmMain.miReadedClick(Sender: TObject);
6330
  procedure TfrmMain.miReadedClick(Sender: TObject);
6416
var
6331
  var
6417
  Tree: TVirtualStringTree;
6332
    Tree: TVirtualStringTree;
6418
  Data: PBookData;
6333
    Data: PBookData;
6419
  Node: PVirtualNode;
6334
    Node: PVirtualNode;
6420
begin
6421
  GetActiveTree(Tree);
6422
  Node := Tree.GetFirstSelected;
6423
  while Node <> nil do
6424
  begin
6335
  begin
6425
    Data := Tree.GetNodeData(Node);
6336
    GetActiveTree(Tree);
6426
    if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
6337
    Node := Tree.GetFirstSelected;
6338
    while Node <> nil do
6427
    begin
6339
    begin
6428
      Node := Tree.GetNextSelected(Node);
6340
      Data := Tree.GetNodeData(Node);
6429
      Continue;
6341
      if not Assigned(Data) or (Data.nodeType <> ntBookInfo) then
6430
    end;
6342
      begin
6343
        Node := Tree.GetNextSelected(Node);
6344
        Continue;
6345
      end;
6431
6346
6432
    // заглушка
6347
      // заглушка
6433
    if Data.Progress = 100 then
6348
      if Data.Progress = 100 then
6434
        Data.Progress := 0
6349
        Data.Progress := 0
6435
    else
6350
      else
6436
        Data.Progress := 100;
6351
        Data.Progress := 100;
6437
6352
6438
    BookTreeStatus := bsBusy;
6353
      BookTreeStatus := bsBusy;
6439
    if GetActiveView <> FavoritesView then
6354
      if GetActiveView <> FavoritesView then
6440
    begin
6355
      begin
6441
6356
6442
      if Data.Progress <> 0 then
6357
        if Data.Progress <> 0 then
6443
          DMUser.SetFinished(Data.ID, Data.Progress)
6358
          DMUser.SetFinished(Data.ID, Data.Progress)
6444
        else
6359
        else
6445
          DMUser.DeleteFinished(Data.ID);
6360
          DMUser.DeleteFinished(Data.ID);
6446
      //
6361
        //
6447
      // Синхронизация с избранным
      //
6362
        // Синхронизация с избранным
        //
6448
      if (DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;',
6363
        if (DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;', VarArrayOf([DMUser.ActiveCollection.ID, Data.ID]), [])) then
6449
                                  VarArrayOf([DMUser.ActiveCollection.ID,Data.ID]),[]))
6364
        begin
6450
      then
6365
          DMUser.tblGrouppedBooks.Edit;
6366
          DMUser.tblGrouppedBooksProgress.Value := Data.Progress;
6367
          DMUser.tblGrouppedBooks.Post;
6368
          FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
6369
        end;
6370
      end
6371
      else // активная вкладка - избранное
6451
      begin
6372
      begin
6373
        DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;', VarArrayOf([DMUser.ActiveCollection.ID, Data.ID]), []);
6452
        DMUser.tblGrouppedBooks.Edit;
6374
        DMUser.tblGrouppedBooks.Edit;
6453
        DMUser.tblGrouppedBooksProgress.Value := Data.Progress;
6375
        DMUser.tblGrouppedBooksProgress.Value := Data.Progress;
6454
        DMUser.tblGrouppedBooks.Post;
6376
        DMUser.tblGrouppedBooks.Post;
6455
        FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True); // избранное
6456
      end;
6457
    end
6458
    else // активная вкладка - избранное
6459
    begin
6460
      DMUser.tblGrouppedBooks.Locate('DataBaseID;OuterID;',
6461
                                    VarArrayOf([DMUser.ActiveCollection.ID,Data.ID]),[]);
6462
      DMUser.tblGrouppedBooks.Edit;
6463
      DMUser.tblGrouppedBooksProgress.Value := Data.Progress;
6464
      DMUser.tblGrouppedBooks.Post;
6465
6377
6466
      //
6378
        //
6467
      // Синхронизация с таблицей рейтингов
6379
        // Синхронизация с таблицей рейтингов
6468
      //
6380
        //
6469
6381
6470
      if Data.Progress <> 0 then
6382
        if Data.Progress <> 0 then
6471
          DMUser.SetFinished(DMUser.tblGrouppedBooksOuterID.Value, Data.Progress, DMUser.tblGrouppedBooksDatabaseID.Value)
6383
          DMUser.SetFinished(DMUser.tblGrouppedBooksOuterId.Value, Data.Progress, DMUser.tblGrouppedBooksDatabaseID.Value)
6472
        else
6384
        else
6473
          DMUser.DeleteFinished(DMUser.tblGrouppedBooksOuterID.Value, DMUser.tblGrouppedBooksDatabaseID.Value);
6385
          DMUser.DeleteFinished(DMUser.tblGrouppedBooksOuterId.Value, DMUser.tblGrouppedBooksDatabaseID.Value);
6474
6386
6475
      FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
6387
        FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
      end;
6476
      FillBooksTree(0, tvBooksS, nil, dmCollection.tblBooksS, False, False); // серии
        FillBooksTree(0, tvBooksA, dmCollection.tblAuthor_List, dmCollection.tblBooksA, False, True); // авторы
6388
      Tree.RepaintNode(Node);
6389
6390
      Node := Tree.GetNextSelected(Node);
6477
    end;
6391
    end;
6478
    Tree.RepaintNode(Node);
6479
6392
6480
    Node := Tree.GetNextSelected(Node);
6393
    BookTreeStatus := bsFree;
6481
  end;
6394
  end;
6482
6395
6483
  BookTreeStatus := bsFree;
6396
  procedure TfrmMain.miRefreshClick(Sender: TObject);
6484
end;
6397
  begin
6398
    InitCollection(True);
6399
  end;
6485
6400
6486
procedure TfrmMain.miRefreshClick(Sender: TObject);
6401
  procedure TfrmMain.miRefreshGenresClick(Sender: TObject);
6487
begin
6402
  var
6488
  InitCollection(True);
6403
    ALibrary: TMHLLibrary;
6489
end;
6404
    AFileName: string;
6405
  begin
6406
    dmCollection.DBCollection.Connected := False;
6407
    ALibrary := TMHLLibrary.Create(nil);
6408
    try
6409
      ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
6410
      ALibrary.Active := True;
6490
6411
6491
procedure TfrmMain.miRefreshGenresClick(Sender: TObject);
6412
      if isFB2Collection(DMUser.ActiveCollection.CollectionType) then
6492
var
6413
        ALibrary.ReloadDefaultGenres(Settings.SystemFileName[sfGenresFB2])
6493
  ALibrary: TMHLLibrary;
6414
      else if unit_Helpers.GetFileName(fnGenreList, AFileName) then
6494
  AFileName: string;
6415
        ALibrary.ReloadDefaultGenres(AFileName);
6495
begin
6416
    finally
6496
  dmCollection.DBCollection.Connected := False;
6417
      ALibrary.Free;
6497
  ALibrary := TMHLLibrary.Create(nil);
6418
    end;
6498
  try
6419
    InitCollection(True);
6499
    ALibrary.DatabaseFileName := DMUser.ActiveCollection.DBFileName;
6500
    ALibrary.Active := True;
6501
6502
    if isFB2Collection(DMUser.ActiveCollection.CollectionType) then
6503
      ALibrary.ReloadDefaultGenres(Settings.SystemFileName[sfGenresFB2])
6504
    else if unit_Helpers.GetFileName(fnGenreList, AFileName) then
6505
      ALibrary.ReloadDefaultGenres(AFileName);
6506
  finally
6507
    ALibrary.Free;
6508
  end;
6420
  end;
6509
  InitCollection(True);
6510
end;
6511
6421
6512
procedure TfrmMain.miRepairDataBaseClick(Sender: TObject);
6422
  procedure TfrmMain.miRepairDataBaseClick(Sender: TObject);
6513
begin
6423
  begin
6514
  dmCollection.DBCollection.Close;
6424
    dmCollection.DBCollection.Close;
6515
  dmCollection.DBCollection.RepairDatabase;
6425
    dmCollection.DBCollection.RepairDatabase;
6516
  dmCollection.DBCollection.Open;
6426
    dmCollection.DBCollection.Open;
6517
6427
6518
  dmUser.SetTableState(True);
6428
    DMUser.SetTableState(True);
6519
  dmCollection.SetTableState(True);
6429
    dmCollection.SetTableState(True);
6520
end;
6430
  end;
6521
6431
6522
procedure TfrmMain.miSettingsClick(Sender: TObject);
6432
  procedure TfrmMain.miSettingsClick(Sender: TObject);
6523
var
6433
  var
6524
  frmSettings: TfrmSettings;
6434
    frmSettings: TfrmSettings;
6525
begin
6435
  begin
6526
  SaveMainFormSettings;
6436
    SaveMainFormSettings;
6527
6437
6528
  frmSettings := TfrmSettings.Create(Application);
6438
    frmSettings := TfrmSettings.Create(Application);
6529
  try
6439
    try
6530
    frmSettings.LoadSetting;
6440
      frmSettings.LoadSetting;
6531
    frmSettings.ShowModal;
6441
      frmSettings.ShowModal;
6532
6442
6533
    Settings.SaveSettings;
6443
      Settings.SaveSettings;
6534
    FreeSettings;
6444
      FreeSettings;
6535
  finally
6445
    finally
6536
    frmSettings.Free;
6446
      frmSettings.Free;
6447
    end;
6448
    ReadINIData;
6537
  end;
6449
  end;
6538
  ReadINIData;
6539
end;
6540
6450
6541
procedure TfrmMain.SetHeaderPopUp;
6451
  procedure TfrmMain.SetHeaderPopUp;
6542
var
6452
  var
6543
  Tree: TVirtualStringTree;
6453
    Tree: TVirtualStringTree;
6544
  i: integer;
6454
    i: Integer;
6545
begin
6455
  begin
6546
  if ActiveView = DownloadView then Exit;
6456
    if ActiveView = DownloadView then
6457
      Exit;
6547
6458
6548
  GetActiveTree(Tree);
6459
    GetActiveTree(Tree);
6549
6460
6550
  for I := 0 to pmHeaders.Items.Count - 1 do
6461
    for i := 0 to pmHeaders.Items.Count - 1 do
6551
  begin
6462
    begin
6552
    pmHeaders.Items[i].Checked := False;
6463
      pmHeaders.Items[i].Checked := False;
6553
    pmHeaders.Items[i].Tag := ColumnTags[i];
6464
      pmHeaders.Items[i].tag := ColumnTags[i];
6554
  end;
6465
    end;
6555
6466
6556
  for I := 0 to Tree.Header.Columns.Count - 1 do
6467
    for i := 0 to Tree.Header.Columns.Count - 1 do
6557
  begin
6468
    begin
6558
    case Tree.Header.Columns[i].Tag of
6469
      case Tree.Header.Columns[i].tag of
6559
      COL_AUTHOR:      pmHeaders.Items[0].Checked := True;
6470
        COL_AUTHOR:
6560
      COL_TITLE:       pmHeaders.Items[1].Checked := True;
6471
          pmHeaders.Items[0].Checked := True;
6561
      COL_SERIES:      pmHeaders.Items[2].Checked := True;
6472
        COL_TITLE:
6562
      COL_NO:          pmHeaders.Items[3].Checked := True;
6473
          pmHeaders.Items[1].Checked := True;
6563
      COL_GENRE:       pmHeaders.Items[4].Checked := True;
6474
        COL_SERIES:
6564
      COL_SIZE :       pmHeaders.Items[5].Checked := True;
6475
          pmHeaders.Items[2].Checked := True;
6565
      COL_RATE :       pmHeaders.Items[6].Checked := True;
6476
        COL_NO:
6566
      COL_DATE :       pmHeaders.Items[7].Checked := True;
6477
          pmHeaders.Items[3].Checked := True;
6567
      COL_TYPE :       pmHeaders.Items[8].Checked := True;
6478
        COL_GENRE:
6568
      COL_COLLECTION:  pmHeaders.Items[9].Checked := True;
6479
          pmHeaders.Items[4].Checked := True;
6569
      COL_LANG :       pmHeaders.Items[10].Checked := True;
6480
        COL_SIZE:
6570
      COL_LIBRATE:     pmHeaders.Items[11].Checked := True;
6481
          pmHeaders.Items[5].Checked := True;
6482
        COL_RATE:
6483
          pmHeaders.Items[6].Checked := True;
6484
        COL_DATE:
6485
          pmHeaders.Items[7].Checked := True;
6486
        COL_TYPE:
6487
          pmHeaders.Items[8].Checked := True;
6488
        COL_COLLECTION:
6489
          pmHeaders.Items[9].Checked := True;
6490
        COL_LANG:
6491
          pmHeaders.Items[10].Checked := True;
6492
        COL_LibRate:
6493
          pmHeaders.Items[11].Checked := True;
6494
      end;
6571
    end;
6495
    end;
6496
    pmHeaders.Items[9].Visible := (Tree.tag = PAGE_FAVORITES);
6572
  end;
6497
  end;
6573
  pmHeaders.Items[9].Visible := (Tree.Tag = PAGE_FAVORITES);
6574
end;
6575
6498
6576
procedure TfrmMain.pgControlChange(Sender: TObject);
6499
  procedure TfrmMain.pgControlChange(Sender: TObject);
6577
var
6500
  var
6578
  ToolBuutonVisible: boolean;
6501
    ToolBuutonVisible: Boolean;
6579
begin
6502
  begin
6580
  // сбрасываем закладки быстрого поиска
6503
    // сбрасываем закладки быстрого поиска
6581
  FLastFoundBook := Nil;
6504
    FLastFoundBook := nil;
6582
  FFirstFoundBook := Nil;
6505
    FFirstFoundBook := nil;
6583
6506
6584
  // tbtnDownloadList_Add.Enabled := (ActiveView <> FavoritesView);
6507
    // tbtnDownloadList_Add.Enabled := (ActiveView <> FavoritesView);
6585
  ToolBuutonVisible := (ActiveView <> DownloadView);
6508
    ToolBuutonVisible := (ActiveView <> DownloadView);
6586
6509
6587
  btnFav_add.Enabled := ToolBuutonVisible;
6510
    BtnFav_add.Enabled := ToolBuutonVisible;
6588
  tbSelectAll.Enabled := ToolBuutonVisible;
6511
    tbSelectAll.Enabled := ToolBuutonVisible;
6589
  tbCollapse.Enabled := ToolBuutonVisible;
6512
    tbCollapse.Enabled := ToolBuutonVisible;
6590
  tbtnShowCover.Enabled := ToolBuutonVisible;
6513
    tbtnShowCover.Enabled := ToolBuutonVisible;
6591
  tbtnRead.Enabled := ToolBuutonVisible;
6514
    tbtnRead.Enabled := ToolBuutonVisible;
6592
  tbtnRus.Enabled := ToolBuutonVisible;
6515
    tbtnRus.Enabled := ToolBuutonVisible;
6593
  tbtnEng.Enabled := ToolBuutonVisible;
6516
    tbtnEng.Enabled := ToolBuutonVisible;
6594
  btnRefreshCollection.Enabled := ToolBuutonVisible;
6517
    btnRefreshCollection.Enabled := ToolBuutonVisible;
6595
  tbtnShowDeleted.Enabled := ToolBuutonVisible;
6518
    tbtnShowDeleted.Enabled := ToolBuutonVisible;
6596
  tbtnShowLocalOnly.Enabled := ToolBuutonVisible;
6519
    tbtnShowLocalOnly.Enabled := ToolBuutonVisible;
6597
6520
6598
  tbSendToDevice.Enabled := ToolBuutonVisible;
6521
    tbSendToDevice.Enabled := ToolBuutonVisible;
6599
  btnSwitchTreeMode.Enabled :=  not ((ActiveView = BySeriesView) or
6522
    btnSwitchTreeMode.Enabled := not((ActiveView = BySeriesView) or (ActiveView = DownloadView));
6600
                                     (ActiveView = DownloadView));
6601
6523
6602
  case ActiveView  of
6524
    case ActiveView of
6603
    ByAuthorView:begin
6525
      ByAuthorView:
6604
                   FLastLetterA.Down := True;
6526
        begin
6605
                   if FLastLetterA = FLastLetterS then
6527
          FLastLetterA.Down := True;
6606
                     FLastLetterS.Down := True
6528
          if FLastLetterA = FLastLetterS then
6607
                   else
6529
            FLastLetterS.Down := True
6608
                     FLastLetterS.Down := False;
6530
          else
6609
                 end;
6531
            FLastLetterS.Down := False;
6610
    BySeriesView :begin
6532
        end;
6611
                   FLastLetterS.Down := True;
6533
      BySeriesView:
6612
                   if FLastLetterA = FLastLetterS then
6534
        begin
6613
                     FLastLetterA.Down := True
6535
          FLastLetterS.Down := True;
6614
                   else
6536
          if FLastLetterA = FLastLetterS then
6615
                     FLastLetterA.Down := False;
6537
            FLastLetterA.Down := True
6616
                 end;
6538
          else
6617
    else begin
6539
            FLastLetterA.Down := False;
6618
                   FLastLetterA.Down := False;
6540
        end;
6619
                   FLastLetterS.Down := False;
6541
    else
6620
                 end;
6542
      begin
6621
  end;
6543
        FLastLetterA.Down := False;
6544
        FLastLetterS.Down := False;
6545
      end;
6546
    end;
6622
6547
6623
  case ActiveView of
6548
    case ActiveView of
6624
    FavoritesView:begin
6549
      FavoritesView:
6625
                    miGotoAuthor.Visible := True;
6550
        begin
6626
                    miDelFavorites.Visible := True;
6551
          miGoToAuthor.Visible := True;
6627
                    miAddFavorites.Visible := False;
6552
          miDelFavorites.Visible := True;
6628
                    btnFav_add.Hint := 'Удалить из группы';
                    btnFav_add.DropdownMenu := Nil;
6553
          miAddFavorites.Visible := False;
6629
                    btnFav_add.ImageIndex := 16;
6554
          BtnFav_add.Hint := 'Удалить из группы';
          BtnFav_add.DropdownMenu := nil;
6630
                    pmiGroups.Visible := False;
6555
          BtnFav_add.ImageIndex := 16;
6631
                    miDeleteFiles.Visible := False;
6556
          pmiGroups.Visible := False;
6632
                  end;
6557
          miDeleteFiles.Visible := False;
6633
    DownloadView: begin
6558
        end;
6634
                    tbtnDownloadList_Add.ImageIndex := 23;
6559
      DownloadView:
6635
                    tbtnDownloadList_Add.Hint := 'Удалить из списка'+#13+'закачек';
6560
        begin
6636
                    btnSwitchTreeMode.Enabled := False;
6561
          tbtnDownloadList_Add.ImageIndex := 23;
6637
                    Exit;
6562
          tbtnDownloadList_Add.Hint := 'Удалить из списка' + #13 + 'закачек';
6638
                  end;
6563
          btnSwitchTreeMode.Enabled := False;
6564
          Exit;
6565
        end;
6639
    else
6566
    else
6640
                 begin
6567
      begin
6641
                    miGotoAuthor.Visible := False;
6568
        miGoToAuthor.Visible := False;
6642
                    miDelFavorites.Visible := False;
6569
        miDelFavorites.Visible := False;
6643
                    miAddFavorites.Visible := True;
6570
        miAddFavorites.Visible := True;
6644
                    btnFav_add.Hint := 'Добавить в избранное';
6571
        BtnFav_add.Hint := 'Добавить в избранное';
6645
                    btnFav_add.DropdownMenu := pmGroups;
6572
        BtnFav_add.DropdownMenu := pmGroups;
6646
                    btnFav_add.ImageIndex := 15;
6573
        BtnFav_add.ImageIndex := 15;
6647
                    pmiGroups.Visible := True;
6574
        pmiGroups.Visible := True;
6648
                    miDeleteFiles.Visible := isOnlineCollection(dmUser.ActiveCollection.CollectionType);
6575
        miDeleteFiles.Visible := isOnlineCollection(DMUser.ActiveCollection.CollectionType);
6649
                  end;
6576
      end;
6650
6577
6651
  end;
6578
    end;
6652
6579
6653
  tbtnDownloadList_Add.ImageIndex := 2;
6580
    tbtnDownloadList_Add.ImageIndex := 2;
6654
  tbtnDownloadList_Add.Hint := 'Добавить в список'+#13+'закачек';
6581
    tbtnDownloadList_Add.Hint := 'Добавить в список' + #13 + 'закачек';
6655
6582
6656
  dmCollection.SetActiveTable(ord(ActiveView));
6583
    dmCollection.SetActiveTable(ord(ActiveView));
6657
6584
6658
  miEditAuthor.Enabled := (ActiveView = ByAuthorView);
6585
    miEditAuthor.Enabled := (ActiveView = ByAuthorView);
6659
  miEditSeries.Enabled := (ActiveView = ByAuthorView);
6586
    miEditSeries.Enabled := (ActiveView = ByAuthorView);
6660
6587
6661
  tbtnEditSeries.Enabled := (ActiveView = ByAuthorView);
6588
    tbtnEditSeries.Enabled := (ActiveView = ByAuthorView);
6662
  tbtnEditAuthor.Enabled := (ActiveView = ByAuthorView);
6589
    tbtnEditAuthor.Enabled := (ActiveView = ByAuthorView);
6663
  tlbrEdit.Enabled := (ActiveView <> FavoritesView);
6590
    tlbrEdit.Enabled := (ActiveView <> FavoritesView);
6664
6591
6665
  miGotoAuthor.Visible := (ActiveView <> ByAuthorView);
6592
    miGoToAuthor.Visible := (ActiveView <> ByAuthorView);
6666
6593
6667
  SetHeaderPopUp;
6594
    SetHeaderPopUp;
6668
6595
6669
  tvBooksTreeChange(Nil,Nil);
6596
    tvBooksTreeChange(nil, nil);
6670
6597
6671
  btnSwitchTreeMode.ImageIndex := TreeIcons[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
6598
    btnSwitchTreeMode.ImageIndex := TreeIcons[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
6672
  btnSwitchTreeMode.Hint := TreeHints[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
6599
    btnSwitchTreeMode.Hint := TreeHints[ord(Settings.TreeModes[pgControl.ActivePageIndex])];
6673
6600
6674
  Settings.ActivePage := pgControl.ActivePageIndex;
6601
    Settings.ActivePage := pgControl.ActivePageIndex;
6675
end;
6602
  end;
6676
6603
6677
procedure TfrmMain.miShowHelpClick(Sender: TObject);
6604
  procedure TfrmMain.miShowHelpClick(Sender: TObject);
6678
var
6605
  var
6679
  dummy : boolean;
6606
    dummy: Boolean;
6680
begin
6607
  begin
6681
  HH(0,0, dummy);
6608
    HH(0, 0, dummy);
6682
end;
6609
  end;
6683
6610
6684
procedure TfrmMain.miPdfdjvuClick(Sender: TObject);
6611
  procedure TfrmMain.miPdfdjvuClick(Sender: TObject);
6685
begin
6612
  begin
6686
  frmAddNonFb2.ShowModal;
6613
    frmAddNonFb2.ShowModal;
6687
  InitCollection(True);
6614
    InitCollection(True);
6688
end;
6615
  end;
6689
6616
6690
procedure TfrmMain.OnBookDownloadComplete(var Message: TDownloadCompleteMessage);
6617
  procedure TfrmMain.OnBookDownloadComplete(var message: TDownloadCompleteMessage);
6691
var
6618
  var
6692
  Tree: TVirtualStringTree;
6619
    Tree: TVirtualStringTree;
6693
  Node: PVirtualNode;
6620
    Node: PVirtualNode;
6694
  Data: PBookData;
6621
    Data: PBookData;
6695
  i: TView;
6622
    i: TView;
6696
begin
6697
  if Message.Downloaded then
6698
  begin
6623
  begin
6699
    for i := ByAuthorView to FavoritesView do
6624
    if message.Downloaded then
6700
    begin
6625
    begin
6701
      Tree := GetViewTree(i);
6626
      for i := ByAuthorView to FavoritesView do
6702
      Assert(Assigned(Tree));
6703
6704
      Node := GetBookNode(Tree, Message.BookID);
6705
      if Assigned(Node) then
6706
      begin
6627
      begin
6707
        Data := Tree.GetNodeData(Node);
6628
        Tree := GetViewTree(i);
6708
        Assert(Assigned(Data));
6629
        Assert(Assigned(Tree));
6709
        if Assigned(Data) then
6630
6631
        Node := GetBookNode(Tree, message.bookID);
6632
        if Assigned(Node) then
6710
        begin
6633
        begin
6711
          Data^.Locale := True;
6634
          Data := Tree.GetNodeData(Node);
6712
          Tree.RepaintNode(Node);
6635
          Assert(Assigned(Data));
6636
          if Assigned(Data) then
6637
          begin
6638
            Data^.Locale := True;
6639
            Tree.RepaintNode(Node);
6640
          end;
6713
        end;
6641
        end;
6714
      end;
6642
      end;
6715
    end;
6643
    end;
6716
  end;
6644
  end;
6717
end;
6718
6645
6719
function TfrmMain.GetBookNode(const Tree: TVirtualStringTree; bookID: Integer): PVirtualNode;
6646
  function TfrmMain.GetBookNode(const Tree: TVirtualStringTree; bookID: Integer): PVirtualNode;
6720
var
6647
  var
6721
  Data: PBookData;
6648
    Data: PBookData;
6722
  Node: PVirtualNode;
6649
    Node: PVirtualNode;
6723
begin
6650
  begin
6724
  Assert(Assigned(Tree));
6651
    Assert(Assigned(Tree));
6725
6652
6726
  Result := nil;
6653
    Result := nil;
6727
6654
6728
  Node := Tree.GetFirst;
6655
    Node := Tree.GetFirst;
6729
  while Assigned(Node) do
6656
    while Assigned(Node) do
6730
  begin
6731
    Data := Tree.GetNodeData(Node);
6732
    Assert(Assigned(Data));
6733
    if (Data.nodeType = ntBookInfo) and (Data.ID = bookID) then
6734
    begin
6657
    begin
6735
      Result := Node;
6658
      Data := Tree.GetNodeData(Node);
6736
      Exit;
6659
      Assert(Assigned(Data));
6660
      if (Data.nodeType = ntBookInfo) and (Data.ID = bookID) then
6661
      begin
6662
        Result := Node;
6663
        Exit;
6664
      end;
6665
      Node := Tree.GetNext(Node);
6737
    end;
6666
    end;
6738
    Node := Tree.GetNext(Node);
6739
  end;
6667
  end;
6740
end;
6741
6668
6742
procedure TfrmMain.miImportUserDataClick(Sender: TObject);
6669
  procedure TfrmMain.miImportUserDataClick(Sender: TObject);
6743
var
6670
  var
6744
  SL: TStringList;
6671
    SL: TStringList;
6745
  FN: string;
6672
    FN: string;
6746
   I: integer;
6673
    i: Integer;
6747
   p: integer;
6674
    p: Integer;
6748
6675
6749
6676
  begin
6750
begin
6677
    if not GetFileName(fnOpenUserData, FN) then
6751
  if not GetFileName(fnOpenUserData, FN) then Exit;
6678
      Exit;
6752
  Screen.Cursor := crHourGlass;
6679
    Screen.Cursor := crHourGlass;
6753
  try
6680
    try
6754
    SL := TStringList.Create;
6681
      SL := TStringList.Create;
6755
    SL.LoadFromFile(FN);
6682
      SL.LoadFromFile(FN);
6756
    i:= 0;
6683
      i := 0;
6757
    while (i < SL.Count) do
6684
      while (i < SL.Count) do
6758
    begin
6759
      if pos('#',SL[i]) <> 0 then
6760
      begin
6685
      begin
6761
        if SL[i] = '# Группы' then DMUser.LoadGroups(SL,i)
6686
        if Pos('#', SL[i]) <> 0 then
6762
        else
6687
        begin
6763
          if SL[i] = '# Рейтинги' then DMUser.LoadRates(SL,i)
6688
          if SL[i] = '# Группы' then
6689
            DMUser.LoadGroups(SL, i)
6690
          else if SL[i] = '# Рейтинги' then
6691
            DMUser.LoadRates(SL, i)
6692
          else if SL[i] = '# Прочитанное' then
6693
            DMUser.LoadFinished(SL, i)
6694
          else if SL[i] = '# Рецензии' then
6695
            DMUser.LoadReviews(SL, i)
6696
          else if SL[i] = '# Избранное' then
6697
            DMUser.LoadGroupedBooks(SL, i)
6764
          else
6698
          else
6765
            if SL[i] = '# Прочитанное' then DMUser.LoadFinished(SL,i)
6699
            inc(i);
6766
            else
6700
        end;
6767
              if SL[i] = '# Рецензии' then DMUser.LoadReviews(SL,i)
6768
              else
6769
                if SL[i] = '# Избранное' then DMUser.LoadGroupedBooks(SL,i)
6770
                else
6771
                  inc(i);
6772
      end;
6701
      end;
6702
      FillGroupsList;
6703
      CreateGroupsMenu;
6704
    finally
6705
      SL.Free;
6706
      Screen.Cursor := crDefault;
6773
    end;
6707
    end;
6774
    FillGroupsList;
6775
    CreateGroupsMenu;
6776
  finally
6777
    SL.Free;
6778
     Screen.Cursor := crDefault;
6779
  end;
6708
  end;
6780
end;
6781
6709
6782
procedure TfrmMain.miINPXCollectionExportClick(Sender: TObject);
6710
  procedure TfrmMain.miINPXCollectionExportClick(Sender: TObject);
6783
begin
6711
  begin
6784
  DMUser.ActivateCollection(Settings.ActiveCollection);
6712
    DMUser.ActivateCollection(Settings.ActiveCollection);
6785
  unit_Export.Export2INPX;
6713
    unit_Export.Export2INPX;
6786
  InitCollection(True);
6714
    InitCollection(True);
6787
end;
6715
  end;
6788
6716
6789
procedure TfrmMain.btnAddGroupClick(Sender: TObject);
6717
  procedure TfrmMain.btnAddGroupClick(Sender: TObject);
6790
var
6718
  var
6791
  Name : string;
6719
    name: string;
6792
begin
6793
  Name := InputBox('Добавление группы','Название группы','');
6794
  if Name <> '' then
6795
  begin
6720
  begin
6796
    DMUser.AddGroup(Name);
6721
    name := InputBox('Добавление группы', 'Название группы', '');
6722
    if name <> '' then
6723
    begin
6724
      DMUser.AddGroup(name);
6797
6725
6798
    FillGroupsList;
6726
      FillGroupsList;
6799
    CreateGroupsMenu;
6727
      CreateGroupsMenu;
6800
    FillBooksTree(0,tvBooksF,Nil,DMUser.tblGrouppedBooks,true, true);
6728
      FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
6729
    end;
6801
  end;
6730
  end;
6802
end;
6803
6731
6804
procedure TfrmMain.btnDeleteGroupClick(Sender: TObject);
6732
  procedure TfrmMain.btnDeleteGroupClick(Sender: TObject);
6805
var
6733
  var
6806
  Data: PGroupData;
6734
    Data: PGroupData;
6807
begin
6808
  Data := tvGroups.GetNodeData(tvGroups.FocusedNode);
6809
  if Data = Nil then Exit;
6810
  if DMUser.ActivateGroup(Data.ID) and
6811
     DMUser.tblGroupListAllowDelete.Value then
6812
  begin
6735
  begin
6813
    btnClearFavoritesClick(Sender);
6736
    Data := tvGroups.GetNodeData(tvGroups.FocusedNode);
6814
    DMUser.tblGroupList.Delete;
6737
    if Data = nil then
6738
      Exit;
6739
    if DMUser.ActivateGroup(Data.ID) and DMUser.tblGroupListAllowDelete.Value then
6740
    begin
6741
      btnClearFavoritesClick(Sender);
6742
      DMUser.tblGroupList.Delete;
6815
6743
6816
    FillGroupsList;
6744
      FillGroupsList;
6817
    CreateGroupsMenu;
6745
      CreateGroupsMenu;
6818
    FillBooksTree(0,tvBooksF,Nil,DMUser.tblGrouppedBooks,true, true);
6746
      FillBooksTree(0, tvBooksF, nil, DMUser.tblGrouppedBooks, True, True);
6819
  end
6747
    end
6820
  else
6748
    else
6821
    ShowMessage('Нельзя удалить встроенную группу!');
6749
      ShowMessage('Нельзя удалить встроенную группу!');
6822
end;
6750
  end;
6823
6751
6824
procedure TfrmMain.cbPresetNameChange(Sender: TObject);
6752
  procedure TfrmMain.cbPresetNameChange(Sender: TObject);
6825
begin
6753
  begin
6826
  btnSavePreset.Enabled  := ( cbPresetName.Text <> '' );
6754
    btnSavePreset.Enabled := (cbPresetName.text <> '');
6827
end;
6755
  end;
6828
6756
6829
procedure TfrmMain.cbPresetNameSelect(Sender: TObject);
6757
  procedure TfrmMain.cbPresetNameSelect(Sender: TObject);
6830
begin
6758
  begin
6831
  btnDeletePreset.Enabled := cbPresetName.ItemIndex >= 0;
6759
    btnDeletePreset.Enabled := cbPresetName.ItemIndex >= 0;
6832
  btnSavePreset.Enabled := True;
6760
    btnSavePreset.Enabled := True;
6833
  LoadSearchPreset(cbPresetName.Text);
6761
    LoadSearchPreset(cbPresetName.text);
6834
end;
6762
  end;
6835
6763
6836
procedure TfrmMain.btnStartDownloadClick(Sender: TObject);
6764
  procedure TfrmMain.btnStartDownloadClick(Sender: TObject);
6837
begin
6765
  begin
6838
  if tvDownloadList.GetFirst = nil then Exit;
6766
    if tvDownloadList.GetFirst = nil then
6767
      Exit;
6839
6768
6840
  btnPauseDownload.Enabled := True;
6769
    btnPauseDownload.Enabled := True;
6841
  btnStartDownload.Enabled := False;
6770
    btnStartDownload.Enabled := False;
6842
6771
6843
  FDMThread := TDownloadManagerThread.Create(False);
6772
    FDMThread := TDownloadManagerThread.Create(False);
6844
end;
6773
  end;
6845
6774
6846
procedure TfrmMain.btnPauseDownloadClick(Sender: TObject);
6775
  procedure TfrmMain.btnPauseDownloadClick(Sender: TObject);
6847
begin
6776
  begin
6848
  btnPauseDownload.Enabled := False;
6777
    btnPauseDownload.Enabled := False;
6849
  btnStartDownload.Enabled := True;
6778
    btnStartDownload.Enabled := True;
6850
  if Assigned(FDMThread) then FDMThread.Stop;
6779
    if Assigned(FDMThread) then
6851
end;
6780
      FDMThread.Stop;
6781
  end;
6852
6782
6853
procedure TfrmMain.BtnSaveClick(Sender: TObject);
6783
  procedure TfrmMain.BtnSaveClick(Sender: TObject);
6854
begin
6784
  begin
6855
  tvDownloadList.SaveToFile(Settings.SystemFileName[sfDownloadsStore]);
6785
    tvDownloadList.SaveToFile(Settings.SystemFileName[sfDownloadsStore]);
6856
end;
6786
  end;
6857
6787
6858
procedure TfrmMain.btnDeleteDownloadClick(Sender: TObject);
6788
  procedure TfrmMain.btnDeleteDownloadClick(Sender: TObject);
6859
var
6789
  var
6860
  Data: PDownloadData;
6790
    Data: PDownloadData;
6861
  i: integer;
6791
    i: Integer;
6862
  List: TSelectionList;
6792
    List: TSelectionList;
6863
begin
6864
  GetSeelections(tvDownloadList,List);
6865
  for I := 0 to tvDownloadList.SelectedCount - 1 do
6866
  begin
6793
  begin
6867
    Data := tvDownloadList.GetNodeData(List[i]);
6794
    GetSeelections(tvDownloadList, List);
6868
    if Data.State <> dsRun then
6795
    for i := 0 to tvDownloadList.SelectedCount - 1 do
6869
      tvDownloadList.DeleteNode(List[i],True);
6796
    begin
6797
      Data := tvDownloadList.GetNodeData(List[i]);
6798
      if Data.State <> dsRun then
6799
        tvDownloadList.DeleteNode(List[i], True);
6800
    end;
6870
  end;
6801
  end;
6871
end;
6872
6802
6873
procedure TfrmMain.btnDeletePresetClick(Sender: TObject);
6803
  procedure TfrmMain.btnDeletePresetClick(Sender: TObject);
6874
begin
6875
  with cbPresetName do
6876
  begin
6804
  begin
6877
    if Text = Items[ItemIndex] then
6805
    with cbPresetName do
6878
    begin
6806
    begin
6879
      DeleteFile(Settings.PresetPath + Text + '.mhlf');
6807
      if text = Items[ItemIndex] then
6880
      Delete(ItemIndex);
6808
      begin
6881
      Text := '';
6809
        DeleteFile(Settings.PresetPath + text + '.mhlf');
6810
        Delete(ItemIndex);
6811
        text := '';
6812
      end;
6882
    end;
6813
    end;
6814
    btnDeletePreset.Enabled := cbPresetName.ItemIndex >= 0;
6815
    btnSavePreset.Enabled := cbPresetName.ItemIndex >= 0;
6883
  end;
6816
  end;
6884
  btnDeletePreset.Enabled := cbPresetName.ItemIndex >= 0;
6885
  btnSavePreset.Enabled := cbPresetName.ItemIndex >= 0;
6886
end;
6887
6817
6888
procedure TfrmMain.BtnFav_addClick(Sender: TObject);
6818
  procedure TfrmMain.BtnFav_addClick(Sender: TObject);
6889
begin
6819
  begin
6890
 if ActiveView = FavoritesView then
6820
    if ActiveView = FavoritesView then
6891
    miDelFavoritesClick(Sender)
6821
      miDelFavoritesClick(Sender)
6892
  else
6822
    else
6893
    begin
6823
    begin
6894
      if DMUser.ActivateGroup(1) then
6824
      if DMUser.ActivateGroup(1) then
6895
          miAddFavoritesClick(Sender);
6825
        miAddFavoritesClick(Sender);
6896
    end;
6826
    end;
6897
end;
6827
  end;
6898
6828
6899
end.
6829
end.