summaryrefslogtreecommitdiff
path: root/plugins/Actman/inoutxml.pas
blob: bcf91222bfd659e7bcf7dcc995917c4d2fced43c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
unit inoutxml;

interface

uses windows, lowlevelc;

function Import(list:tMacroList;fname:PWideChar;aflags:dword):integer;

implementation

uses
  io, common, m_api, question,
  iac_global, global;

const
  ioAction = 'Action';
  ioClass  = 'class';
  ioName   = 'name';
  ioVolatile = 'volatile';
const
  imp_yes    = 1;
  imp_yesall = 2;
  imp_no     = 3;
  imp_noall  = 4;
  imp_append = 5;

function ImportAction(actnode:HXML):tBaseAction;
var
  pa:pActModule;
  buf:array [0..127] of AnsiChar;
begin
  result:=nil;
  if actnode=0 then exit;
  pa:=GetLinkByName(FastWideToAnsiBuf(xmlGetAttrValue(actnode,ioClass),buf));
  if pa<>nil then
  begin
    result:=pa.Create;
    result.Load(pointer(actnode),1);
  end
  else
    result:=tBaseAction(1);
end;

function Import(list:tMacroList;fname:PWideChar;aflags:dword):integer;
var
  f:THANDLE;
  i,nodenum,actcnt:integer;
  tmp,res:pWideChar;
  root,actnode:HXML;
  impact:integer;
  buf:array [0..511] of WideChar;
  oldid:dword;
  arr:array [0..63] of tBaseAction;
  act:tBaseAction;
  p:pMacroRecord;
begin
  result:=0;

  for i:=0 to list.Count-1 do
    with list[i]^ do
      if (flags and (ACF_IMPORT or ACF_ASSIGNED))=
                    (ACF_IMPORT or ACF_ASSIGNED) then
        flags:=flags and not (ACF_IMPORT or ACF_OVERLOAD);

  if (fname=nil) or (fname^=#0) then
    exit;
  i:=GetFSize(fname);
  if i=0 then
    exit;
  mGetMem (res ,i+SizeOf(WideChar));
  FillChar(res^,i+SizeOf(WideChar),0);
  f:=Reset(fname);
  BlockRead(f,res^,i);
  CloseHandle(f);

  root:=xmlParseString(ChangeUnicode(res),@i,nil);
  nodenum:=0;
  impact:=imp_yes;
  repeat
    actnode:=xmlGetNthChild(root,ioAction,nodenum);
    if actnode=0 then break;
    tmp:=xmlGetAttrValue(actnode,ioName);
    if tmp<>nil then //!!
    begin
      p:=list.GetMacro(tmp);
      oldid:=$FFFFFFFF;
      if p<>nil then
      begin
        if (impact<>imp_yesall) and (impact<>imp_noall) then
        begin
          StrCopyW(buf,TranslateW('Action "$" exists, do you want to rewrite it?'));
          impact:=ShowQuestion(StrReplaceW(buf,'$',tmp));
        end;
        if (impact=imp_yesall) or (impact=imp_yes) then
        begin
          oldid:=p^.id;
          FreeMacro(p);
        end;
      end;
      // if new or overwriting then read macro details/actions
      if (p=nil) or (impact=imp_yesall) or (impact=imp_yes) or (impact=imp_append) then
      begin
        with List[list.NewMacro()]^ do
        begin
          if (p<>nil) and (oldid<>$FFFFFFFF) then // set old id to keep UseAction setting
          begin
            flags:=flags or ACF_IMPORT or ACF_OVERLOAD;
            id:=oldid;
          end
          else
            flags:=flags or ACF_IMPORT;
          if StrToInt(xmlGetAttrValue(actnode,ioVolatile))=1 then flags:=flags or ACF_VOLATILE;
          StrCopyW(descr,tmp,MacroNameLen-1);

          // reading actions
          actcnt:=0; // count in file 
          ActionCount:=0;      // amount of loaded
          repeat
            act:=ImportAction(xmlGetChild(actnode,actcnt));
            if act=nil then
              break;
            if uint_ptr(act)<>1 then
            begin
              arr[ActionCount]:=act;
              inc(ActionCount);
            end;
            inc(actcnt);
          until false;
          // moving actions to their place
          if Actioncount>0 then
          begin
            GetMem(ActionList,SizeOf(tBaseAction)*ActionCount);
            move(arr,ActionList^,SizeOf(tBaseAction)*ActionCount);
          end;
          inc(result);
        end;
      end;
    end;
    inc(nodenum);
  until false;
  xmlDestroyNode(root);
  mFreeMem(res);
end;

end.