summaryrefslogtreecommitdiff
path: root/plugins/Actman30/inoutxml.pas
blob: 3a7aea25d4e88323594b80ebb2f78c87c941cdfc (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
146
147
148
149
150
151
152
153
154
155
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;
  with xmlparser do
  begin
    pa:=GetLinkByName(FastWideToAnsiBuf(getAttrValue(actnode,ioClass),buf));
    if pa<>nil then
    begin
      result:=pa.Create;
      result.Load(pointer(actnode),1);
    end
    else
      result:=tBaseAction(1);
  end;
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);

//MessageBoxW(0,res,'SRC',0);
  xmlparser.cbSize:=SizeOf(XML_API_W);
  CallService(MS_SYSTEM_GET_XI,0,lparam(@xmlparser));
  with xmlparser do
  begin
    root:=parseString(ChangeUnicode(res),@i,nil);
    nodenum:=0;
    impact:=imp_yes;
    repeat
      actnode:=getNthChild(root,ioAction,nodenum);
      if actnode=0 then break;
//??      if StrCmpW(getName(actnode),ioAction)<>0 then break;
      tmp:=getAttrValue(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(getAttrValue(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(getChild(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;
    destroyNode(root);
  end;
  mFreeMem(res);
end;

end.