diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-05-15 10:38:20 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-05-15 10:38:20 +0000 |
commit | 48540940b6c28bb4378abfeb500ec45a625b37b6 (patch) | |
tree | 2ef294c0763e802f91d868bdef4229b6868527de /plugins/ImportTXT/General.pas | |
parent | 5c350913f011e119127baeb32a6aedeb4f0d33bc (diff) |
initial commit
git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/ImportTXT/General.pas')
-rw-r--r-- | plugins/ImportTXT/General.pas | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/plugins/ImportTXT/General.pas b/plugins/ImportTXT/General.pas new file mode 100644 index 0000000000..d263dde816 --- /dev/null +++ b/plugins/ImportTXT/General.pas @@ -0,0 +1,562 @@ +unit general;
+
+interface
+
+uses Windows,Messages,SysUtils,IniFiles,
+ m_api,
+ ImportT,
+ ImportTU;
+
+var MirVers:DWORD;
+ IsMirandaUnicode:boolean;
+ cp:cardinal;
+
+var
+ AppPath:array[0..MAX_PATH] of char;
+ TxtPatterns: array of RTxtPattern;
+ PatternNames: array of PChar;
+ PatternsCount:integer;
+ Protocols:array of TDestProto;
+ ProtoCount: integer;
+ CheckForDuplicates:boolean;
+ ShowDuplicates:boolean;
+
+const
+ BIN_PROCEDURE_COUNT=6; //количество реализованых процедур бинарного импорта
+
+const
+ {$EXTERNALSYM PBM_SETRANGE}
+ PBM_SETRANGE = WM_USER+1;
+ {$EXTERNALSYM PBM_SETPOS}
+ PBM_SETPOS = WM_USER+2;
+
+const
+ IMPORT_TXT_MODULE= 'ImportTXT';
+ IMPORT_TXT_SERVICE= IMPORT_TXT_MODULE+'/Import';
+ IMPORT_WIZ_SERVICE= IMPORT_TXT_MODULE+'/Wizard';
+
+ //keys
+ IMPORT_TXT_AS= 'AutoStart';
+ IMPORT_TXT_LP= 'LastPattern';
+
+type TOnAccountListChange = procedure ();
+
+var
+ OnAccountListChange:TOnAccountListChange;
+
+function ReadPattern(FileName: string):boolean;
+procedure ReadPatterns;
+procedure ExtractFilePath(fName:PChar);
+function fIsMirandaUnicode:boolean;
+function GetContactProto(hContact: THandle): String;
+function GetContactByUID(proto:string;id:string):THandle;
+function GetContactByNick(Proto:string;Nick:string):THandle;
+procedure EnumProtocols;
+function GetContactID(hContact: THandle; Proto: String = ''; Contact: boolean = false): String;
+function GetContactNick(hContact: THandle; Proto: String = ''; Contact: boolean = false): String;
+function DBReadByte (hContact:THANDLE;szModule:PChar;szSetting:PChar;default:byte =0):byte;
+function DBWriteByte (hContact:THANDLE;szModule:PChar;szSetting:PChar;val:Byte ):Integer;
+procedure SetLastPattern(lp:byte);
+function GetLastPattern:byte;
+function TimeStampToWStr(ts:dword):WideString;
+function StrToTimeStamp(STime:PChar;len:integer):dword;
+
+function RLWord(adr:integer):word;
+function RLInteger(adr:integer):integer;
+
+implementation
+
+
+procedure ExtractFilePath(fName:PChar);
+var p:PChar;
+begin
+ p:=fName;
+ if p<>nil then
+ begin
+ while p^<>#0 do inc(p);
+ while p^<>'\' do dec(p);
+ inc(p);
+ p^:=#0;
+ end;
+end;
+
+function ReadPattern(FileName: string):boolean;
+var TI: TIniFile;
+ h:integer;
+ Err:boolean;
+ tempstr:string;
+begin
+ err:=false;
+ TI:=TIniFile.Create(FileName);
+ try
+ h:=High(TxtPatterns);
+ if not TI.SectionExists('General') then begin result:=true; exit; end;
+ //if "General" exists
+ if TI.ValueExists('General','Name') then TxtPatterns[h].Name:=TI.ReadString('General','Name','')
+ else err:=true;
+ if TI.ValueExists('General','Type') then TxtPatterns[h].IType:=TI.ReadInteger('General','Type',1)
+ else err:=true;
+ case TxtPatterns[h].IType of
+ 1:
+ begin
+ if TI.ValueExists('General','Charset') then
+ begin
+ tempstr:=TI.ReadString('General','Charset','UTF8');
+ if tempstr='ANSI' then TxtPatterns[h].Charset:=inANSI
+ else
+ if tempstr='UTF8' then TxtPatterns[h].Charset:=inUTF8
+ else
+ if tempstr='UCS2' then TxtPatterns[h].Charset:=inUCS2
+ else err:=true;
+ end
+ else err:=true;
+ if TxtPatterns[h].Charset=inANSI then
+ begin
+ TxtPatterns[h].Codepage:= TI.ReadInteger('General','Codepage',0);
+ if not IsValidCodePage(TxtPatterns[h].Codepage) then TxtPatterns[h].Codepage:=0;
+ end;
+ TxtPatterns[h].UseHeader:=TI.ReadInteger('General','UseHeader',0);
+ TxtPatterns[h].UsePreMsg:=TI.ReadBool('General','UsePreMsg',false);
+ // Read message section
+ if TI.SectionExists('Message') then
+ begin
+ if TI.ValueExists('Message','Pattern') then TxtPatterns[h].Msg.Pattern:=TI.ReadString('Message','Pattern','')
+ else err:=true;
+ TxtPatterns[h].Msg.Incoming:=TI.ReadString('Message','In','');
+ TxtPatterns[h].Msg.Outgoing:=TI.ReadString('Message','Out','');
+ if TI.ValueExists('Message','Direction') then TxtPatterns[h].Msg.Direction:=TI.ReadInteger('Message','Direction',0)
+ else err:=true;
+ if TI.ValueExists('Message','Day') then TxtPatterns[h].Msg.Day:=TI.ReadInteger('Message','Day',0)
+ else err:=true;
+ if TI.ValueExists('Message','Month') then TxtPatterns[h].Msg.Month:=TI.ReadInteger('Message','Month',0)
+ else err:=true;
+ if TI.ValueExists('Message','Year') then TxtPatterns[h].Msg.Year:=TI.ReadInteger('Message','Year',0)
+ else err:=true;
+ if TI.ValueExists('Message','Hours') then TxtPatterns[h].Msg.Hours:=TI.ReadInteger('Message','Hours',0)
+ else err:=true;
+ if TI.ValueExists('Message','Minutes') then TxtPatterns[h].Msg.Minutes:=TI.ReadInteger('Message','Minutes',0)
+ else err:=true;
+ TxtPatterns[h].Msg.Seconds:=TI.ReadInteger('Message','Seconds',0)
+ end
+ else err:=true;
+ // if need read header section
+ if (TxtPatterns[h].UseHeader>0) then
+ if TI.SectionExists('Header') then
+ begin
+ if TI.ValueExists('Header','Pattern') then TxtPatterns[h].Header.Pattern:=TI.ReadString('Header','Pattern','')
+ else err:=true;
+ if (not TI.ValueExists('Header','In')) and ((TxtPatterns[h].UseHeader and 1)=1) then err:=true;
+ TxtPatterns[h].Header.Incoming:=TI.ReadInteger('Header','In',0);
+ TxtPatterns[h].Header.Outgoing:=TI.ReadInteger('Header','Out',0);
+ TxtPatterns[h].Header.InNick:=TI.ReadInteger('Header','InNick',0);
+ TxtPatterns[h].Header.OutNick:=TI.ReadInteger('Header','OutNick',0);
+ TxtPatterns[h].Header.InUID:=TI.ReadInteger('Header','InUID',0);
+ TxtPatterns[h].Header.OutUID:=TI.ReadInteger('Header','OutUID',0);
+ if ((TxtPatterns[h].UseHeader and 2)=2) then
+ if (TxtPatterns[h].Header.InNick=0) and (TxtPatterns[h].Header.InUID=0) then err:=true;
+ end
+ else err:=true;
+ // if nead read PreMessage section
+ if TxtPatterns[h].UsePreMsg then
+ if TI.SectionExists('PreMessage') then
+ begin
+ TxtPatterns[h].PreMsg.PreRN:=TI.ReadInteger('PreMessage','PreRN',-1);
+ TxtPatterns[h].PreMsg.AfterRN:=TI.ReadInteger('PreMessage','AfterRN',-1);
+ TxtPatterns[h].PreMsg.PreSP:=TI.ReadInteger('PreMessage','PreSP',0);
+ TxtPatterns[h].PreMsg.AfterSP:=TI.ReadInteger('PreMessage','AfterSP',0);
+ end
+ else err:=true;
+ end; //1
+ 2:
+ begin
+ TxtPatterns[h].BinProc:= TI.ReadInteger('General','BinProcedure',0);
+ if (TxtPatterns[h].BinProc>BIN_PROCEDURE_COUNT) then err:=true;
+ end;
+ end; //case
+ TxtPatterns[h].DefExtension:=TI.ReadString('General','DefaultExtension','txt');
+ TxtPatterns[h].UseFileName:=TI.ReadBool('General','UseFileName',false);
+ // if nead read FileName section
+ if TxtPatterns[h].UseFileName then
+ if TI.SectionExists('FileName') then
+ begin
+ if TI.ValueExists('FileName','Pattern') then TxtPatterns[h].FName.Pattern:=TI.ReadString('FileName','Pattern','')
+ else err:=true;
+ TxtPatterns[h].FName.InNick:=TI.ReadInteger('FileName','InNick',0);
+ TxtPatterns[h].FName.InUID:=TI.ReadInteger('FileName','InUID',0);
+ if (TxtPatterns[h].FName.InNick=0) and (TxtPatterns[h].FName.InUID=0) then err:=true;
+ TxtPatterns[h].FName.OutNick:=TI.ReadInteger('FileName','OutNick',0);
+ TxtPatterns[h].FName.OutUID:=TI.ReadInteger('FileName','OutUID',0);
+ end
+ else err:=true;
+ finally
+ TI.Free;
+ end;
+ Result:=err;
+end;
+
+procedure ReadPatterns;
+var
+ SR: TSearchRec;
+ FileAttrs: Integer;
+ i:integer;
+begin
+ FileAttrs:=faAnyFile;
+ i:=0;
+ if FindFirst(AppPath+'\importtxt\*.ini',FileAttrs,SR)=0 then
+ begin
+ repeat
+ SetLength(TxtPatterns,i+1);
+ SetLength(PatternNames,i+1);
+ if not ReadPattern(AppPath+'\importtxt\'+SR.Name) then
+ begin
+ PatternNames[i]:= PChar(TxtPatterns[i].Name);
+ inc(i);
+ end;
+ until FindNext(SR) <> 0 ;
+ FindClose(SR);
+ end;
+ PatternsCount:=i;
+end;
+
+
+function GetContactByUID(proto:string;id:string):THandle;
+var
+ contact:THandle;
+ otherproto:string;
+ ci:TCONTACTINFO;
+ idnum:integer;
+ tempwstr:PWideChar;
+ ws:WideString;
+begin
+ if not TryStrToInt(id,idnum) then idnum:=0;
+ if IsMirandaUnicode then
+ begin
+ tempwstr:=UTF8ToWide(PChar(id),tempwstr);
+ ws :=tempwstr;
+ FreeMem(tempwstr);
+ end;
+ result:=INVALID_HANDLE_VALUE;
+ contact:=pluginlink^.CallService(MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while (contact<>0) do
+ begin
+ otherproto:=PChar(pluginlink^.CallService(MS_PROTO_GETCONTACTBASEPROTO,contact,0));
+ if otherproto=proto then
+ begin
+ ci.cbSize:=SizeOf(ci);
+ ci.dwFlag:=CNF_UNIQUEID;
+ if IsMirandaUnicode then ci.dwFlag:=ci.dwFlag or CNF_UNICODE;
+ ci.hContact:=contact;
+ ci.szProto:=PChar(otherproto);
+ if pluginlink^.CallService(MS_CONTACT_GETCONTACTINFO,0,integer(@ci))=0 then
+ begin
+ case ( ci._type ) of
+ CNFT_BYTE: if ci.retval.bVal = idnum then
+ begin
+ result:=contact;
+ break;
+ end;
+ CNFT_WORD: if ci.retval.wVal = idnum then
+ begin
+ result:=contact;
+ break;
+ end;
+ CNFT_DWORD: if ci.retval.dVal = DWORD(idnum) then
+ begin
+ result:=contact;
+ break;
+ end;
+ CNFT_ASCIIZ:
+ if IsMirandaUnicode then
+ if ws=ci.retval.szVal.w then
+ begin
+ result:=contact;
+ break;
+ end else
+ else
+ if id=ci.retval.szVal.a then
+ begin
+ result:=contact;
+ break;
+ end;
+ end; //case
+ end; //if
+ end; //if
+ contact:= Pluginlink^.CallService(MS_DB_CONTACT_FINDNEXT,contact,0);
+ end; //while
+end;
+
+function GetContactByNick(Proto:string;Nick:string):THandle;
+var
+ contact:THandle;
+ otherproto:string;
+ ci:TCONTACTINFO;
+ tempwstr:PWideChar;
+ ws:WideString;
+begin
+ if IsMirandaUnicode then
+ begin
+ tempwstr:=UTF8ToWide(PChar(Nick),tempwstr);
+ ws :=tempwstr;
+ FreeMem(tempwstr);
+ end;
+ result:=INVALID_HANDLE_VALUE;
+ contact:=pluginlink^.CallService(MS_DB_CONTACT_FINDFIRST, 0, 0 );
+ while (contact<>0) do
+ begin
+ otherproto:=PChar(pluginlink^.CallService(MS_PROTO_GETCONTACTBASEPROTO,contact,0));
+ if otherproto=proto then
+ begin
+ ci.cbSize:=SizeOf(ci);
+ ci.dwFlag:=CNF_NICK;
+ if IsMirandaUnicode then ci.dwFlag:=ci.dwFlag or CNF_UNICODE;
+ ci.hContact:=contact;
+ ci.szProto:=PChar(otherproto);
+ if pluginlink^.CallService(MS_CONTACT_GETCONTACTINFO,0,integer(@ci))=0 then
+ begin
+ if IsMirandaUnicode then
+ begin
+ if ws=ci.retval.szVal.w then
+ begin
+ result:=contact;
+ break;
+ end;
+ end
+ else
+ begin
+ if Nick=ci.retval.szVal.a then
+ begin
+ result:=contact;
+ break;
+ end;
+ end;
+ end; //if
+ end; //if
+ contact:= Pluginlink^.CallService(MS_DB_CONTACT_FINDNEXT,contact,0);
+ end; //while
+end;
+
+procedure EnumProtocols;
+var i,iProtoCount:integer;
+ ppAccounts:^PPROTOACCOUNT;
+ temps:string;
+begin
+ ProtoCount:=0;
+ SetLength(Protocols,30);
+ if MirVers> $080000 then pluginLink^.CallService(MS_PROTO_ENUMACCOUNTS,int(@iProtoCount),int(@ppAccounts))
+ else pluginLink^.CallService(MS_PROTO_ENUMPROTOCOLS,int(@iProtoCount),int(@ppAccounts));
+ for i:=1 to iProtoCount do
+ begin
+ if (ppAccounts^^._type=PROTOTYPE_PROTOCOL) then
+ begin
+ temps:=GetContactID(0,ppAccounts^^.szModuleName,false);
+ if temps<>'' then
+ begin
+ protocols[ProtoCount].ProtoName:=ppAccounts^^.szModuleName;
+ protocols[ProtoCount].ProtoUID:=temps;
+ protocols[ProtoCount].ProtoNick:=GetContactNick(0,ppAccounts^^.szModuleName,false);
+ inc(ProtoCount);
+ end;
+ end;
+ inc(ppAccounts);
+ end;
+ SetLength(Protocols,ProtoCount);
+end;
+
+function fIsMirandaUnicode:boolean;
+var ver:ShortString;
+begin
+ Result:=true;
+ SetLength(ver,255);
+ if PluginLink.CallService(MS_SYSTEM_GETVERSIONTEXT,wParam(255),lParam(@ver[1]))=0 then
+ Result:=Pos('Unicode',ver)>0;
+end;
+
+function GetContactProto(hContact: THandle): String;
+begin
+ Result := PChar(PluginLink.CallService(MS_PROTO_GETCONTACTBASEPROTO,hContact,0));
+end;
+
+function DBFreeVariant(dbv:PDBVARIANT):integer;
+begin
+ Result:=PluginLink^.CallService(MS_DB_CONTACT_FREEVARIANT,0,lParam(dbv));
+end;
+
+function GetContactID(hContact: THandle; Proto: String = ''; Contact: boolean = false): String;
+var
+ uid: PChar;
+ dbv: TDBVARIANT;
+ cgs: TDBCONTACTGETSETTING;
+ tempstr:PChar;
+begin
+ Result := '';
+ if not ((hContact = 0) and Contact) then begin
+ if Proto = '' then Proto := GetContactProto(hContact);
+ uid := PChar(CallProtoService(PChar(Proto),PS_GETCAPS,PFLAG_UNIQUEIDSETTING,0));
+ if (Cardinal(uid) <> CALLSERVICE_NOTFOUND) and (uid <> nil) then begin
+ cgs.szModule := PChar(Proto);
+ cgs.szSetting := uid;
+ cgs.pValue := @dbv;
+ if PluginLink^.CallService(MS_DB_CONTACT_GETSETTING,hContact,LPARAM(@cgs)) = 0 then begin
+ case dbv._type of
+ DBVT_BYTE:
+ Result := intToStr(dbv.bVal);
+ DBVT_WORD:
+ Result := intToStr(dbv.wVal);
+ DBVT_DWORD:
+ Result := intToStr(dbv.dVal);
+ DBVT_ASCIIZ:
+ if IsMirandaUnicode then
+ begin
+ tempstr:=ANSIToUTF8(dbv.szVal.a,tempstr,cp);
+ Result :=tempstr;
+ FreeMem(tempstr);
+ end else Result := dbv.szVal.a;
+ DBVT_UTF8:
+ if IsMirandaUnicode then Result :=dbv.szVal.a
+ else
+ begin
+ tempstr:=UTF8ToANSI(dbv.szVal.a,tempstr,cp);
+ Result :=tempstr;
+ FreeMem(tempstr);
+ end;
+ DBVT_WCHAR:
+ begin
+ if IsMirandaUnicode then tempstr:=WideToUTF8(dbv.szVal.w,tempstr)
+ else tempstr:=WideToAnsi(dbv.szVal.w,tempstr,cp);
+ Result:=tempstr;
+ FreeMem(tempstr);
+ end;
+ end;
+ // free variant
+ DBFreeVariant(@dbv);
+ end;
+ end;
+ end;
+end;
+
+function GetContactNick(hContact: THandle; Proto: String = ''; Contact: boolean = false): String;
+var
+ dbv: TDBVARIANT;
+ cgs: TDBCONTACTGETSETTING;
+ tempstr:PChar;
+begin
+ Result := '';
+ if not ((hContact = 0) and Contact) then begin
+ if Proto = '' then Proto := GetContactProto(hContact);
+ cgs.szModule := PChar(Proto);
+ cgs.szSetting := 'Nick';
+ cgs.pValue := @dbv;
+ if PluginLink^.CallService(MS_DB_CONTACT_GETSETTING,hContact,LPARAM(@cgs)) = 0 then begin
+ case dbv._type of
+ DBVT_BYTE:
+ Result := intToStr(dbv.bVal);
+ DBVT_WORD:
+ Result := intToStr(dbv.wVal);
+ DBVT_DWORD:
+ Result := intToStr(dbv.dVal);
+ DBVT_ASCIIZ:
+ if IsMirandaUnicode then
+ begin
+ tempstr:=ANSIToUTF8(dbv.szVal.a,tempstr,cp);
+ Result :=tempstr;
+ FreeMem(tempstr);
+ end else Result := dbv.szVal.a;
+ DBVT_UTF8:
+ if IsMirandaUnicode then Result :=dbv.szVal.a
+ else
+ begin
+ tempstr:=UTF8ToANSI(dbv.szVal.a,tempstr,cp);
+ Result :=tempstr;
+ FreeMem(tempstr);
+ end;
+ DBVT_WCHAR:
+ begin
+ if IsMirandaUnicode then tempstr:=WideToUTF8(dbv.szVal.w,tempstr)
+ else tempstr:=WideToAnsi(dbv.szVal.w,tempstr,cp);
+ Result:=tempstr;
+ FreeMem(tempstr);
+ end;
+ end;
+ // free variant
+ DBFreeVariant(@dbv);
+ end;
+ end;
+end;
+
+function DBReadByte(hContact:THANDLE;szModule:PChar;szSetting:PChar;default:byte=0):byte;
+var
+ dbv:TDBVARIANT;
+ cgs:TDBCONTACTGETSETTING;
+begin
+ cgs.szModule :=szModule;
+ cgs.szSetting:=szSetting;
+ cgs.pValue :=@dbv;
+ If PluginLink^.CallService(MS_DB_CONTACT_GETSETTING,hContact,lParam(@cgs))<>0 then
+ Result:=default
+ else
+ Result:=dbv.bVal;
+end;
+
+function DBWriteByte(hContact:THANDLE;szModule:PChar;szSetting:PChar;val:Byte):Integer;
+var
+ cws:TDBCONTACTWRITESETTING;
+begin
+ cws.szModule :=szModule;
+ cws.szSetting :=szSetting;
+ cws.value._type:=DBVT_BYTE;
+ cws.value.bVal :=Val;
+ Result:=PluginLink^.CallService(MS_DB_CONTACT_WRITESETTING,hContact,lParam(@cws));
+end;
+
+procedure SetLastPattern(lp:byte);
+begin
+ DBWriteByte(0,IMPORT_TXT_MODULE,IMPORT_TXT_LP,lp);
+end;
+
+function GetLastPattern:byte;
+begin
+ result:=DBReadByte(0,IMPORT_TXT_MODULE,IMPORT_TXT_LP,0);
+ if result>=PatternsCount then result:=0;
+end;
+
+function TimeStampToWStr(ts:dword):WideString;
+var dbtts:TDBTIMETOSTRING;
+ s:WideString;
+begin
+ SetLength(s,20);
+ dbtts.szFormat.w:='d s';
+ dbtts.szDest.w:=PWideChar(s);
+ dbtts.cbDest:=20;
+ pluginlink^.CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT,ts,Int(@dbtts));
+ result:=s;
+end;
+
+function StrToTimeStamp(STime:PChar;len:integer):dword;
+var hour, min, sec, day, month, year: integer;
+begin
+ sec:=0;
+ day:=(ord(stime[0])-$30)*10+(ord(stime[1])-$30);
+ month:=(ord(stime[3])-$30)*10+(ord(stime[4])-$30);
+ year:=(ord(stime[6])-$30)*1000+(ord(stime[7])-$30)*100+(ord(stime[8])-$30)*10+(ord(stime[9])-$30);
+ hour:=(ord(stime[11])-$30)*10+(ord(stime[12])-$30);
+ min:=(ord(stime[14])-$30)*10+(ord(stime[15])-$30);
+ if len>15 then sec:=(ord(stime[17])-$30)*10+(ord(stime[18])-$30);
+ result:=Timestamp(year,month,day,hour,min,sec);
+end;
+
+function RLWord(adr:integer):word;
+begin
+ Result:=PByte(adr+1)^ + (PByte(adr)^ *$100);
+end;
+
+function RLInteger(adr:integer):integer;
+begin
+ Result:=PByte(adr+3)^ + (PByte(adr+2)^*$100) +
+ (PByte(adr+1)^ * $10000) + (PByte(adr)^ *$1000000);
+end;
+
+begin
+ GetModuleFileName(hInstance,@AppPath[0],MAX_PATH);
+ ExtractFilePath(AppPath);
+ ReadPatterns;
+end.
|