Browse Source

ADD: Mark files by search template

Alexander Koblov 15 years ago
parent
commit
f156fb529d
6 changed files with 282 additions and 13 deletions
  1. 10 1
      src/doublecmd.lpi
  2. 122 0
      src/fmaskinputdlg.lfm
  3. 3 0
      src/fmaskinputdlg.lrt
  4. 87 0
      src/fmaskinputdlg.pas
  5. 23 10
      src/newdesign/ucolumnsfileview.pas
  6. 37 2
      src/usearchtemplate.pas

+ 10 - 1
src/doublecmd.lpi

@@ -60,7 +60,7 @@
         <PackageName Value="viewerpackage"/>
       </Item5>
     </RequiredPackages>
-    <Units Count="97">
+    <Units Count="98">
       <Unit0>
         <Filename Value="doublecmd.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -145,6 +145,7 @@
         <IsPartOfProject Value="True"/>
         <ComponentName Value="frmAbout"/>
         <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
         <UnitName Value="fAbout"/>
       </Unit11>
       <Unit12>
@@ -647,6 +648,14 @@
         <IsPartOfProject Value="True"/>
         <UnitName Value="uQuickViewPanel"/>
       </Unit96>
+      <Unit97>
+        <Filename Value="fmaskinputdlg.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="frmMaskInputDlg"/>
+        <HasResources Value="True"/>
+        <ResourceBaseClass Value="Form"/>
+        <UnitName Value="fMaskInputDlg"/>
+      </Unit97>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

+ 122 - 0
src/fmaskinputdlg.lfm

@@ -0,0 +1,122 @@
+object frmMaskInputDlg: TfrmMaskInputDlg
+  Left = 404
+  Height = 231
+  Top = 176
+  Width = 339
+  AutoSize = True
+  BorderIcons = [biSystemMenu]
+  BorderStyle = bsDialog
+  ChildSizing.LeftRightSpacing = 10
+  ChildSizing.TopBottomSpacing = 10
+  ClientHeight = 231
+  ClientWidth = 339
+  OnCreate = FormCreate
+  Position = poScreenCenter
+  LCLVersion = '0.9.29'
+  object lblPrompt: TLabel
+    AnchorSideLeft.Control = Owner
+    AnchorSideTop.Control = Owner
+    AnchorSideRight.Control = Owner
+    AnchorSideRight.Side = asrBottom
+    Left = 10
+    Height = 28
+    Top = 10
+    Width = 319
+    Anchors = [akTop, akLeft, akRight]
+    AutoSize = False
+    BorderSpacing.Left = 10
+    BorderSpacing.Right = 10
+    ParentColor = False
+    WordWrap = True
+  end
+  object lblSearchTemplate: TLabel
+    AnchorSideLeft.Control = cmbMask
+    AnchorSideTop.Control = cmbMask
+    AnchorSideTop.Side = asrBottom
+    AnchorSideRight.Control = cmbMask
+    AnchorSideRight.Side = asrBottom
+    Left = 10
+    Height = 16
+    Top = 71
+    Width = 319
+    Anchors = [akTop, akLeft, akRight]
+    AutoSize = False
+    BorderSpacing.Top = 6
+    Caption = 'Or select predefined selection type:'
+    ParentColor = False
+    WordWrap = True
+  end
+  object cmbMask: TComboBox
+    AnchorSideLeft.Control = Owner
+    AnchorSideTop.Control = lblPrompt
+    AnchorSideTop.Side = asrBottom
+    AnchorSideRight.Control = Owner
+    AnchorSideRight.Side = asrBottom
+    Left = 10
+    Height = 21
+    Top = 44
+    Width = 319
+    Anchors = [akTop, akLeft, akRight]
+    BorderSpacing.Left = 10
+    BorderSpacing.Top = 6
+    BorderSpacing.Right = 10
+    DropDownCount = 10
+    ItemHeight = 13
+    TabOrder = 0
+  end
+  object btnOK: TBitBtn
+    AnchorSideTop.Control = lbxSearchTemplate
+    AnchorSideTop.Side = asrBottom
+    AnchorSideRight.Control = btnCancel
+    Left = 163
+    Height = 32
+    Top = 192
+    Width = 80
+    Anchors = [akTop, akRight]
+    BorderSpacing.Top = 6
+    BorderSpacing.Right = 6
+    Caption = '&OK'
+    Default = True
+    Kind = bkOK
+    ModalResult = 1
+    TabOrder = 3
+  end
+  object btnCancel: TBitBtn
+    AnchorSideTop.Control = lbxSearchTemplate
+    AnchorSideTop.Side = asrBottom
+    AnchorSideRight.Control = Owner
+    AnchorSideRight.Side = asrBottom
+    Left = 249
+    Height = 32
+    Top = 192
+    Width = 80
+    Anchors = [akTop, akRight]
+    BorderSpacing.Top = 6
+    BorderSpacing.Right = 10
+    Cancel = True
+    Caption = 'Cancel'
+    Kind = bkCancel
+    ModalResult = 2
+    TabOrder = 2
+  end
+  object lbxSearchTemplate: TListBox
+    AnchorSideLeft.Control = Owner
+    AnchorSideTop.Control = lblSearchTemplate
+    AnchorSideTop.Side = asrBottom
+    AnchorSideRight.Control = Owner
+    AnchorSideRight.Side = asrBottom
+    Left = 10
+    Height = 93
+    Top = 93
+    Width = 319
+    Anchors = [akTop, akLeft, akRight]
+    BorderSpacing.Left = 10
+    BorderSpacing.Top = 6
+    BorderSpacing.Right = 10
+    ItemHeight = 0
+    OnClick = lbxSearchTemplateClick
+    OnDblClick = lbxSearchTemplateDblClick
+    Sorted = True
+    TabOrder = 1
+  end
+end

+ 3 - 0
src/fmaskinputdlg.lrt

@@ -0,0 +1,3 @@
+TFRMMASKINPUTDLG.LBLSEARCHTEMPLATE.CAPTION=Or select predefined selection type:
+TFRMMASKINPUTDLG.BTNOK.CAPTION=&OK
+TFRMMASKINPUTDLG.BTNCANCEL.CAPTION=Cancel

+ 87 - 0
src/fmaskinputdlg.pas

@@ -0,0 +1,87 @@
+unit fMaskInputDlg;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
+  StdCtrls, Buttons;
+
+type
+
+  { TfrmMaskInputDlg }
+
+  TfrmMaskInputDlg = class(TForm)
+    lblPrompt: TLabel;
+    lblSearchTemplate: TLabel;
+    cmbMask: TComboBox;
+    btnOK: TBitBtn;
+    btnCancel: TBitBtn;
+    lbxSearchTemplate: TListBox;
+    procedure FormCreate(Sender: TObject);
+    procedure lbxSearchTemplateClick(Sender: TObject);
+    procedure lbxSearchTemplateDblClick(Sender: TObject);
+  private
+    { private declarations }
+  public
+    { public declarations }
+  end; 
+
+function ShowMaskInputDlg(const sCaption, sPrompt: UTF8String; slValueList: TStringList; var sValue: UTF8String): Boolean;
+
+implementation
+
+uses
+  uGlobs, uSearchTemplate;
+
+function ShowMaskInputDlg(const sCaption, sPrompt: UTF8String;
+  slValueList: TStringList; var sValue: UTF8String): Boolean;
+begin
+  Result:= False;
+  with TfrmMaskInputDlg.Create(Application) do
+  try
+    Caption:= sCaption;
+    lblPrompt.Caption:= sCaption;
+    cmbMask.Items.Assign(slValueList);
+    cmbMask.Text := sValue;
+    if ShowModal = mrOK then
+      begin
+        if not IsMaskSearchTemplate(cmbMask.Text) then
+          if slValueList.IndexOf(cmbMask.Text) < 0 then
+            slValueList.Add(cmbMask.Text);
+        sValue:= cmbMask.Text;
+        Result:= True;
+      end;
+  finally
+    Free;
+  end;
+end;
+
+{ TfrmMaskInputDlg }
+
+procedure TfrmMaskInputDlg.lbxSearchTemplateClick(Sender: TObject);
+begin
+  cmbMask.Text:= cTemplateSign + lbxSearchTemplate.Items[lbxSearchTemplate.ItemIndex];
+end;
+
+procedure TfrmMaskInputDlg.lbxSearchTemplateDblClick(Sender: TObject);
+begin
+  cmbMask.Text:= cTemplateSign + lbxSearchTemplate.Items[lbxSearchTemplate.ItemIndex];
+  Close;
+  ModalResult:= mrOK;
+end;
+
+procedure TfrmMaskInputDlg.FormCreate(Sender: TObject);
+var
+  I: Integer;
+begin
+  for I:= 0 to gSearchTemplateList.Count - 1 do
+    lbxSearchTemplate.Items.Add(gSearchTemplateList.Templates[I].TemplateName);
+end;
+
+initialization
+  {$I fmaskinputdlg.lrs}
+
+end.
+

+ 23 - 10
src/newdesign/ucolumnsfileview.pas

@@ -500,7 +500,7 @@ implementation
 
 uses
   LCLProc, Masks, Dialogs, uLng, uShowMsg, uGlobs, uPixmapManager,
-  uDCUtils, uOSUtils, math, fMain,
+  uDCUtils, uOSUtils, math, fMain, fMaskInputDlg, uSearchTemplate,
   uFileProperty,
   uFileSourceProperty,
   uFileSourceOperation,
@@ -1722,7 +1722,7 @@ var
 begin
   if IsEmpty then Exit;
   s := FLastMark;
-  if not ShowInputComboBox(rsMarkPlus, rsMaskInput, glsMaskHistory, s) then Exit;
+  if not ShowMaskInputDlg(rsMarkPlus, rsMaskInput, glsMaskHistory, s) then Exit;
   FLastMark := s;
   MarkGroup(s, True);
   UpdateInfoPanel;
@@ -1765,7 +1765,7 @@ var
 begin
   if IsEmpty then Exit;
   s := FLastMark;
-  if not ShowInputComboBox(rsMarkMinus, rsMaskInput, glsMaskHistory, s) then Exit;
+  if not ShowMaskInputDlg(rsMarkMinus, rsMaskInput, glsMaskHistory, s) then Exit;
   FLastMark := s;
   MarkGroup(s, False);
   UpdateInfoPanel;
@@ -1781,14 +1781,27 @@ end;
 
 procedure TColumnsFileView.MarkGroup(const sMask: String; bSelect: Boolean);
 var
-  i: Integer;
+  I: Integer;
+  SearchTemplate: TSearchTemplate = nil;
 begin
-  for i := 0 to FFiles.Count - 1 do
-  begin
-    if FFiles[i].TheFile.Name = '..' then Continue;
-    if MatchesMaskList(FFiles[i].TheFile.Name, sMask) then
-      FFiles[i].Selected := bSelect;
-  end;
+  if IsMaskSearchTemplate(sMask) then
+    begin
+      SearchTemplate:= gSearchTemplateList.TemplateByName[sMask];
+      if Assigned(SearchTemplate) then
+        for I := 0 to FFiles.Count - 1 do
+          begin
+            if FFiles[I].TheFile.Name = '..' then Continue;
+            if SearchTemplate.CheckFile(FFiles[I].TheFile) then
+              FFiles[I].Selected := bSelect;
+          end;
+    end
+  else
+    for I := 0 to FFiles.Count - 1 do
+      begin
+        if FFiles[I].TheFile.Name = '..' then Continue;
+        if MatchesMaskList(FFiles[I].TheFile.Name, sMask) then
+          FFiles[I].Selected := bSelect;
+      end;
 end;
 
 procedure TColumnsFileView.edtPathKeyDown(Sender: TObject; var Key: Word;

+ 37 - 2
src/usearchtemplate.pas

@@ -3,7 +3,7 @@
    -------------------------------------------------------------------------
    Load/Save search templates
 
-   Copyright (C) 2009  Koblov Alexander ([email protected])
+   Copyright (C) 2009-2010  Koblov Alexander ([email protected])
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -57,19 +57,31 @@ type
   TSearchTemplateList = class(TList)
   private
     function GetTemplate(Index: Integer): TSearchTemplate;
+    function GetTemplate(const AName: UTF8String): TSearchTemplate;
   public
     function Add(SearchTemplate: TSearchTemplate): Integer;
     procedure DeleteTemplate(Index: Integer);
     procedure LoadToStringList(StringList: TStrings);
     procedure LoadFromIni(IniFile: TIniFileEx);
     procedure SaveToIni(IniFile: TIniFileEx);
+    property TemplateByName[const AName: UTF8String]: TSearchTemplate read GetTemplate;
     property Templates[Index: Integer]: TSearchTemplate read GetTemplate;
   end;
 
+const
+  cTemplateSign = '>';
+
+function IsMaskSearchTemplate(const sMask: UTF8String): Boolean; inline;
+
 implementation
 
 uses
-  DateUtils, uFileProperty;
+  DateUtils, Masks, uFileProperty;
+
+function IsMaskSearchTemplate(const sMask: UTF8String): Boolean; inline;
+begin
+  Result:= (Length(sMask) > 0) and (sMask[1] = cTemplateSign);
+end;
 
 { TSearchTemplate }
 
@@ -171,6 +183,9 @@ begin
   Result:= True;
   with SearchRecord do
   begin
+    if (fpName in AFile.GetSupportedProperties) then
+      Result:= MatchesMaskList(AFile.Name, SearchRecord.rFileMask);
+
     if (fpModificationTime in AFile.GetSupportedProperties) then
       if (rIsDateFrom or rIsDateTo or rIsTimeFrom or rIsTimeTo or FIsNotOlderThan) then
         Result:= CheckFileDate((AFile.Properties[fpModificationTime] as TFileDateTimeProperty).Value);
@@ -188,6 +203,26 @@ begin
   Result:= TSearchTemplate(Items[Index]);
 end;
 
+function TSearchTemplateList.GetTemplate(const AName: UTF8String): TSearchTemplate;
+var
+  I: Integer;
+  sName: UTF8String;
+begin
+  Result:= nil;
+
+  if IsMaskSearchTemplate(AName) then
+    sName:= PChar(AName) + 1 // skip template sign
+  else
+    sName:= AName;
+
+  for I:= 0 to Count - 1 do
+    if SameText(TSearchTemplate(Items[I]).TemplateName, sName) then
+      begin
+        Result:= TSearchTemplate(Items[I]);
+        Exit;
+      end;
+end;
+
 function TSearchTemplateList.Add(SearchTemplate: TSearchTemplate): Integer;
 begin
   Result:= inherited Add(SearchTemplate);