source: trunk/dll/avl.c@ 603

Last change on this file since 603 was 603, checked in by Gregg Young, 18 years ago

Work around for PM drag/drop limit; more drag/drop error checking

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.6 KB
Line 
1
2/***********************************************************************
3
4 $Id: avl.c 603 2007-04-06 21:57:45Z gyoung $
5
6 archiver.bb2 search, load, save and date parse
7
8 Copyright (c) 1993, 1998 M. Kimes
9 Copyright (c) 2004, 2006 Steven H.Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 13 Aug 05 SHL Beautify with indent
13 13 Aug 05 SHL find_type: correct no sig exists bypass logic
14 13 Aug 05 SHL SBoxDlgProc: avoid dereferencing NULL signature
15 18 Aug 05 SHL Comments
16 31 Dec 05 SHL indent -i2
17 08 Dec 05 SHL load_archivers: allow empty startlist
18 30 Dec 05 SHL load_archivers: use get_archiver_line?(), clean nits
19 29 May 06 SHL SBoxDlgProc: support move, add, delete
20 30 May 06 SHL load_archivers: add reload support
21 16 Jun 06 SHL load_archivers: support signatures containing 0s
22 26 Jun 06 SHL load_archivers: remember where comments are
23 14 Jul 06 SHL Use Runtime_Error
24 29 Jul 06 SHL Use xfgets, xfgets_bstripcr
25 15 Aug 06 SHL Use Runtime_Error more
26 01 Nov 06 SHL Turn off leftover debug code
27 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limit
28
29***********************************************************************/
30
31#define INCL_WIN
32#define INCL_WINSTDDRAG
33#define INCL_DOS
34#include <os2.h>
35
36#include <stdlib.h>
37#include <stdio.h>
38#include <string.h>
39#include <share.h>
40#include <ctype.h>
41
42#include "fm3dll.h"
43#include "fm3dlg.h"
44#include "fm3str.h"
45
46static PSZ pszSrcFile = __FILE__;
47
48#pragma alloc_text(MISC9,quick_find_type,find_type)
49
50static void free_arc_type(ARC_TYPE * pat);
51static void fill_listbox(HWND hwnd, BOOL fShowAll, SHORT sOldSelect);
52
53//=== quick_find_type() ===
54
55ARC_TYPE *quick_find_type(CHAR * filespec, ARC_TYPE * topsig)
56{
57 ARC_TYPE *info, *found = NULL;
58 CHAR *p;
59
60 if (!arcsigsloaded)
61 load_archivers();
62 p = strrchr(filespec, '.');
63 if (p) {
64 p++;
65 info = (topsig) ? topsig : arcsighead;
66 while (info) {
67 if (info->ext && *(info->ext) && !stricmp(p, info->ext)) {
68 found = find_type(filespec, topsig);
69 break;
70 }
71 info = info->next;
72 }
73 }
74 return found;
75}
76
77//=== fill_listbox() fill or refill listbox from current archiver definitions ===
78
79static VOID fill_listbox(HWND hwnd, BOOL fShowAll, SHORT sOldSelect)
80{
81 ARC_TYPE *pat;
82 BOOL found = FALSE;
83 SHORT sSelect;
84
85 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
86
87 for (pat = arcsighead; pat; pat = pat->next) {
88 /*
89 * this inner loop tests for a dup signature entry and assures
90 * that only the entry at the top of the list gets used for
91 * conversion; editing any is okay
92 */
93 if (!fShowAll) {
94 ARC_TYPE *pat2;
95 BOOL isDup = FALSE;
96
97 for (pat2 = arcsighead;
98 pat2 && pat->siglen && pat2 != pat && !isDup; pat2 = pat2->next) {
99 isDup = pat2->siglen == pat->siglen &&
100 !memcmp(pat2->signature, pat->signature, pat->siglen);
101 } // for
102 if (isDup)
103 continue;
104 }
105
106 // If caller is editing archivers or entry useful to caller, show in listbox
107 if (fShowAll || (pat->id && pat->extract && pat->create)) {
108 sSelect = (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
109 MPFROM2SHORT(LIT_END, 0),
110 MPFROMP(pat->id ? pat->id : "?"));
111 if (!found && *szDefArc && pat->id && !strcmp(szDefArc, pat->id)) {
112 // Highlight default
113 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
114 MPFROMSHORT(sSelect), MPFROMSHORT(TRUE));
115 found = TRUE;
116 }
117 }
118 else {
119 // Complain about odd entry
120 if (!pat->id || !*pat->id) {
121 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
122 MPFROM2SHORT(LIT_END, 0),
123 MPFROMP(GetPString(IDS_UNKNOWNUNUSABLETEXT)));
124 }
125 else {
126 CHAR s[81];
127
128 sprintf(s, "%0.12s %s", pat->id, GetPString(IDS_UNUSABLETEXT));
129 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
130 MPFROM2SHORT(LIT_END, 0), MPFROMP(s));
131 }
132 }
133 } // while scanning
134
135 // Try to reselect last selection unless user wants default selection
136 if (sOldSelect != LIT_NONE && !found) {
137 SHORT sItemCount =
138 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
139 MPVOID, MPVOID);
140
141 if (sOldSelect >= sItemCount)
142 sOldSelect = sItemCount - 1;
143 if (sOldSelect >= 0) {
144 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
145 MPFROMSHORT(sOldSelect), MPFROMSHORT(TRUE));
146 }
147 }
148
149 if (found)
150 PosOverOkay(hwnd);
151}
152
153ARC_TYPE *find_type(CHAR * filespec, ARC_TYPE * topsig)
154{
155 HFILE handle;
156 ULONG action;
157 ULONG len;
158 ULONG l;
159 ARC_TYPE *info;
160 CHAR *p;
161 CHAR buffer[80];
162
163 if (!arcsigsloaded)
164 load_archivers();
165 if (!topsig)
166 topsig = arcsighead;
167 DosError(FERR_DISABLEHARDERR);
168 if (DosOpen(filespec,
169 &handle,
170 &action,
171 0L,
172 0L,
173 OPEN_ACTION_FAIL_IF_NEW |
174 OPEN_ACTION_OPEN_IF_EXISTS,
175 OPEN_FLAGS_FAIL_ON_ERROR |
176 OPEN_FLAGS_NOINHERIT |
177 OPEN_FLAGS_RANDOMSEQUENTIAL |
178 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0L))
179 return NULL;
180 // Scan signatures
181 for (info = topsig; info; info = info->next) {
182 if (info->siglen == 0) {
183 // No signature -- check extension
184 p = strrchr(filespec, '.');
185 if (p) {
186 p++;
187 if (info->ext && *(info->ext) && !stricmp(p, info->ext))
188 break; // Matched
189
190 }
191 continue; // Next sig
192
193 }
194 // Try signature match
195 l = info->siglen;
196 l = min(l, 79);
197 if (!DosChgFilePtr(handle,
198 abs(info->file_offset),
199 (info->file_offset >= 0L) ?
200 FILE_BEGIN : FILE_END, &len)) {
201 if (!DosRead(handle, buffer, l, &len) && len == l) {
202 if (!memcmp(info->signature, buffer, l))
203 break; // Matched
204
205 }
206 }
207 } // for
208
209 DosClose(handle); /* Either way, we're done for now */
210 return info; /* Return signature, if any */
211}
212
213//=== free_arc_type() free allocated ARC_TYPE ===
214
215static void free_arc_type(ARC_TYPE * pat)
216{
217 if (pat) {
218 xfree(pat->id);
219 xfree(pat->ext);
220 xfree(pat->list);
221 xfree(pat->extract);
222 xfree(pat->create);
223 xfree(pat->move);
224 xfree(pat->delete);
225 xfree(pat->signature);
226 xfree(pat->startlist);
227 xfree(pat->endlist);
228 xfree(pat->exwdirs);
229 xfree(pat->test);
230 xfree(pat->createrecurse);
231 xfree(pat->createwdirs);
232 xfree(pat->movewdirs);
233 free(pat);
234 }
235}
236
237static UINT cur_line_num; // Input file line counter
238
239#pragma alloc_text(AVL,load_archivers, get_line_strip_comments, get_line_strip_white)
240
241//=== get_line_strip_comments() read line, strip comments and whitespace ===
242
243#define ARCHIVER_LINE_BYTES 256
244
245static PSZ get_line_strip_comments(PSZ pszIn, FILE * fp)
246{
247 PSZ psz = xfgets(pszIn, ARCHIVER_LINE_BYTES, fp, pszSrcFile, __LINE__);
248 PSZ psz2;
249
250 if (psz) {
251 cur_line_num++;
252 psz2 = strchr(pszIn, ';');
253 if (psz2)
254 *psz2 = 0; // Chop comment
255 bstripcr(pszIn); // Strip leading white and trailing white and CR/LF
256
257 }
258 return psz;
259}
260
261//=== get_line_strip_white() read line, strip whitespace ===
262
263static PSZ get_line_strip_white(PSZ pszIn, FILE * fp)
264{
265 PSZ psz =
266 xfgets_bstripcr(pszIn, ARCHIVER_LINE_BYTES, fp, pszSrcFile, __LINE__);
267
268 if (psz)
269 cur_line_num++;
270
271 return psz;
272}
273
274//=== load_archivers() load or reload archive definitions from archiver.bb2 ===
275
276INT load_archivers(VOID)
277{
278 FILE *fp;
279 CHAR sz[ARCHIVER_LINE_BYTES + 1];
280 CHAR *psz;
281 ARC_TYPE *pat = NULL;
282 ARC_TYPE *patLast = NULL;
283 UINT lines_per_arcsig = LINES_PER_ARCSIG;
284 UINT per_sig_comment_line_num = 0;
285 INT i;
286
287 // Free current signatures
288 if (arcsighead) {
289 for (pat = arcsighead; pat;) {
290 patLast = pat;
291 pat = pat->next;
292 free_arc_type(patLast);
293 }
294 arcsighead = NULL;
295 }
296
297 arcsigsmodified = FALSE;
298 arcsigs_header_lines = 0;
299 arcsigs_trailer_line_num = 0;
300
301 DosEnterCritSec();
302 psz = searchpath(GetPString(IDS_ARCHIVERBB2));
303 if (!psz || !*psz) {
304 DosExitCritSec();
305 return -1;
306 }
307 fp = _fsopen(psz, "r", SH_DENYWR);
308 DosExitCritSec();
309 if (!fp)
310 return -2;
311 strcpy(archiverbb2, psz); // Remember full path
312
313 cur_line_num = 0;
314
315 // Line 1 must contain number of lines per signature definition
316 if (!get_line_strip_comments(sz, fp)) {
317 fclose(fp);
318 return -3;
319 }
320 if (*sz)
321 lines_per_arcsig = atoi(sz);
322 if (!*sz || lines_per_arcsig < LINES_PER_ARCSIG)
323 return -3;
324
325 // Parse rest of file
326 // 1st non-blank line starts definition
327 // Need to determine header size and start of trailer
328
329 while (!feof(fp)) {
330 // If reading header
331 if (!arcsigs_header_lines) {
332 // Reading header - find header size and start of signtures
333 if (!get_line_strip_white(sz, fp))
334 break; // Unexpected EOF
335 if (stristr(sz, "-- Current Archivers --")) {
336 arcsigs_header_lines = cur_line_num;
337 continue;
338 }
339 if (!*sz || *sz == ';')
340 continue; // Header comment or blank line
341 else {
342 // Not a comment, must be start of signatures
343 PSZ psz2 = strchr(sz, ';');
344
345 if (psz2) {
346 *psz2 = 0; // Chop trailing comment
347 bstripcr(sz); // Strip leading white and trailing white and CR/LF
348 }
349 arcsigs_header_lines = cur_line_num - 1;
350 }
351 }
352 else {
353 // Reading defintiions
354 if (!get_line_strip_comments(sz, fp))
355 break; // EOF
356 }
357
358 // fixme to avoid allocating empty fields
359
360 // Remember start of per sig comments for next definition
361 if (per_sig_comment_line_num == 0)
362 per_sig_comment_line_num = cur_line_num;
363
364 if (*sz) {
365 // At start of defintion
366
367 pat = xmallocz(sizeof(ARC_TYPE), pszSrcFile, __LINE__);
368 if (!pat)
369 break;
370 pat->id = xstrdup(sz, pszSrcFile, __LINE__);
371
372 pat->comment_line_num = per_sig_comment_line_num;
373 pat->defn_line_num = cur_line_num;
374
375 if (!get_line_strip_comments(sz, fp)) // line 2 - extension
376 break;
377 if (*sz)
378 pat->ext = xstrdup(sz, pszSrcFile, __LINE__);
379 else
380 pat->ext = NULL;
381 if (!get_line_strip_comments(sz, fp)) // line 3 - offset to signature
382 break;
383 pat->file_offset = atol(sz);
384 if (!get_line_strip_comments(sz, fp)) // line 4 - list command
385 break;
386 if (*sz)
387 pat->list = xstrdup(sz, pszSrcFile, __LINE__);
388 else
389 pat->list = NULL;
390 if (!pat->list)
391 break; // Must have list command - fixme to complain
392 if (!get_line_strip_comments(sz, fp)) // line 5
393 break;
394 if (*sz)
395 pat->extract = xstrdup(sz, pszSrcFile, __LINE__);
396 else
397 pat->extract = NULL;
398 if (!get_line_strip_comments(sz, fp)) // line 6
399 break;
400 if (*sz)
401 pat->exwdirs = xstrdup(sz, pszSrcFile, __LINE__);
402 else
403 pat->exwdirs = NULL;
404 if (!get_line_strip_comments(sz, fp)) // line 7
405 break;
406 if (*sz)
407 pat->test = xstrdup(sz, pszSrcFile, __LINE__);
408 else
409 pat->test = NULL;
410 if (!get_line_strip_comments(sz, fp)) // line 8
411 break;
412 if (*sz)
413 pat->create = xstrdup(sz, pszSrcFile, __LINE__);
414 else
415 pat->create = NULL;
416 if (!get_line_strip_comments(sz, fp)) // line 9
417 break;
418 if (*sz)
419 pat->createwdirs = xstrdup(sz, pszSrcFile, __LINE__);
420 else
421 pat->createwdirs = NULL;
422 if (!get_line_strip_comments(sz, fp)) // line 10
423 break;
424 if (*sz)
425 pat->createrecurse = xstrdup(sz, pszSrcFile, __LINE__);
426 else
427 pat->createrecurse = NULL;
428 if (!get_line_strip_comments(sz, fp)) // line 11
429 break;
430 if (*sz)
431 pat->move = xstrdup(sz, pszSrcFile, __LINE__);
432 else
433 pat->move = NULL;
434 if (!get_line_strip_comments(sz, fp)) // line 12
435 break;
436 if (*sz)
437 pat->movewdirs = xstrdup(sz, pszSrcFile, __LINE__);
438 else
439 pat->movewdirs = NULL;
440 if (!get_line_strip_comments(sz, fp)) // line 13
441 break;
442 if (*sz)
443 pat->delete = xstrdup(sz, pszSrcFile, __LINE__);
444 else
445 pat->delete = NULL;
446 if (!get_line_strip_white(sz, fp)) // line 14
447 break;
448 i = literal(sz); // Translate \ escapes
449 if (i) {
450 pat->siglen = i;
451 pat->signature = xmalloc(i, pszSrcFile, __LINE__);
452 if (!pat->signature)
453 break;
454 memcpy(pat->signature, sz, i); // signature may not be a string
455 }
456 else {
457 pat->siglen = 0;
458 pat->signature = NULL;
459 }
460 if (!get_line_strip_white(sz, fp)) // line 15
461 break;
462 if (*sz)
463 pat->startlist = xstrdup(sz, pszSrcFile, __LINE__);
464 else
465 pat->startlist = NULL;
466 if (!get_line_strip_white(sz, fp)) // line 16
467 break;
468 if (*sz)
469 pat->endlist = xstrdup(sz, pszSrcFile, __LINE__);
470 else
471 pat->endlist = NULL;
472 if (!get_line_strip_comments(sz, fp)) // line 17
473 break;
474 pat->osizepos = atoi(sz);
475 if (!get_line_strip_comments(sz, fp)) // line 18
476 break;
477 pat->nsizepos = atoi(sz);
478 if (!get_line_strip_comments(sz, fp)) // line 19
479 break;
480 pat->fdpos = atoi(sz);
481 psz = strchr(sz, ',');
482 if (psz) {
483 psz++;
484 pat->datetype = atoi(psz);
485 }
486 if (!get_line_strip_comments(sz, fp)) // line 20
487 break;
488 pat->fdflds = atoi(sz);
489 if (!get_line_strip_comments(sz, fp)) // line 21
490 break;
491 pat->fnpos = atoi(sz);
492 psz = strchr(sz, ',');
493 if (psz) {
494 psz++;
495 pat->nameislast = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
496 psz = strchr(psz, ',');
497 if (psz) {
498 psz++;
499 pat->nameisnext = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
500 psz = strchr(psz, ',');
501 if (psz) {
502 psz++;
503 pat->nameisfirst = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
504 }
505 }
506 }
507 // Ignore unknown lines - must be newer file format
508 for (i = LINES_PER_ARCSIG; i < lines_per_arcsig; i++) {
509 if (!get_line_strip_comments(sz, fp))
510 break; // Unexpected EOF - fixme to complain
511 }
512
513 // Add to list, assume next and prev already NULL
514 if (!arcsighead)
515 arcsighead = patLast = pat;
516 else {
517 patLast->next = pat;
518 pat->prev = patLast;
519 patLast = pat;
520 }
521 pat = NULL; // Done with this defintion
522
523 arcsigs_trailer_line_num = cur_line_num + 1; // In case this is last defintion
524 per_sig_comment_line_num = 0;
525 } // if got definition
526
527 } // while more lines
528
529 fclose(fp);
530
531 free_arc_type(pat); // In case partial definition in progress
532
533 if (!arcsighead)
534 return -4;
535
536 arcsigsloaded = TRUE;
537
538 return 0;
539}
540
541#define TEST_DRAG 0 // fixme to be gone or to work
542
543#pragma alloc_text(FMARCHIVE,SBoxDlgProc,SDlgListboxSubclassProc)
544
545static MRESULT EXPENTRY SDlgListboxSubclassProc(HWND hwnd, ULONG msg,
546 MPARAM mp1, MPARAM mp2)
547{
548 PFNWP pfnOldProc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
549
550 PDRAGITEM pditem;
551 PDRAGINFO pdinfo;
552 BOOL ok;
553
554 static BOOL emphasized = FALSE;
555 static PSZ DRMDRF_LBOX = "<DRM_LBOX,DRF_UNKNOWN>";
556 static PSZ DRM_LBOX = "DRM_LBOX";
557
558 switch (msg) {
559 case WM_BEGINDRAG:
560 {
561 LONG cur_ndx;
562 DRAGITEM ditem;
563 DRAGIMAGE dimage;
564 HWND hwndDrop;
565
566 // fprintf(stderr, "SDlgListboxSubclassProc: BEGINDRAG\n");
567 cur_ndx = WinQueryLboxSelectedItem(hwnd);
568
569 if (cur_ndx != LIT_NONE) {
570 pdinfo = DrgAllocDraginfo(1);
571 if (pdinfo) {
572 pdinfo->usOperation = DO_DEFAULT;
573 pdinfo->hwndSource = hwnd;
574
575 memset(&ditem, 0, sizeof(DRAGITEM));
576 ditem.hwndItem = hwnd;
577 ditem.ulItemID = 1;
578 ditem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
579 ditem.hstrRMF = DrgAddStrHandle(DRMDRF_LBOX);
580 ditem.hstrContainerName = DrgAddStrHandle("");
581 ditem.hstrSourceName = DrgAddStrHandle("");
582 ditem.hstrTargetName = DrgAddStrHandle("");
583 // ditem.fsControl = 0;
584 ditem.fsSupportedOps = DO_MOVEABLE;
585
586 memset(&dimage, 0, sizeof(DRAGIMAGE));
587 dimage.cb = sizeof(DRAGIMAGE);
588 dimage.hImage = hptrFile;
589 dimage.cptl = 0;
590 dimage.fl = DRG_ICON;
591 dimage.sizlStretch.cx = 32;
592 dimage.sizlStretch.cy = 32;
593 dimage.cxOffset = -16;
594 dimage.cyOffset = 0;
595 DrgSetDragitem(pdinfo, &ditem, sizeof(DRAGITEM), 0); /* Index of DRAGITEM */
596 hwndDrop = DrgDrag(hwnd, pdinfo, &dimage, 1, /* One DRAGIMAGE */
597 VK_ENDDRAG, NULL);
598 if (!hwndDrop)
599 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DrgDrag");
600
601 DrgFreeDraginfo(pdinfo);
602 // WinSetWindowPos(hwnd,HWND_TOP,0,0,0,0,SWP_ACTIVATE);
603 }
604 }
605 break;
606 }
607
608 case DM_DRAGOVER:
609 ok = FALSE;
610 if (!emphasized) {
611 POINTL ptl;
612 POINTL ptl2;
613
614 emphasized = TRUE;
615 ptl.x = SHORT1FROMMP(mp2);
616 ptl.y = SHORT2FROMMP(mp2);
617 ptl2 = ptl;
618 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl2, 1);
619 // fprintf(stderr, "DRAGOVER mapped x y %d %d to %d %d\n", ptl.x, ptl.y, ptl2.x, ptl2.y);
620 WinPostMsg(hwnd, WM_BUTTON1CLICK,
621 MPFROM2SHORT((SHORT) ptl2.x, (SHORT) ptl2.y),
622 MPFROM2SHORT(HT_NORMAL, KC_NONE));
623 // fprintf(stderr, "DRAGOVER posted 0x%x WM_BUTTON1CLICK x y %d %d\n", hwnd, ptl2.x, ptl2.y);
624 }
625 pdinfo = (PDRAGINFO) mp1; /* Get DRAGINFO pointer */
626 if (pdinfo) {
627 DrgAccessDraginfo(pdinfo);
628 pditem = DrgQueryDragitemPtr(pdinfo, 0);
629 /* Check valid rendering mechanisms and data format */
630 ok = DrgVerifyRMF(pditem, DRM_LBOX, NULL);
631 DrgFreeDraginfo(pdinfo);
632 if (ok) {
633 }
634 }
635 return ok ? MRFROM2SHORT(DOR_DROP, DO_MOVE) : MRFROM2SHORT(DOR_NEVERDROP,
636 0);
637
638 case DM_DRAGLEAVE:
639 if (emphasized) {
640 emphasized = FALSE;
641 // fixme to draw listbox item emphasized
642 // DrawTargetEmphasis(hwnd, emphasized);
643 // fprintf(stderr, "DRAGLEAVE\n");
644 fflush(stderr);
645 }
646 return 0;
647
648 case DM_DROPHELP:
649 DropHelp(mp1, mp2, hwnd, "fixme to give some help");
650 return 0;
651
652 case DM_DROP:
653 ok = FALSE;
654 // fprintf(stderr, "DROP\n");
655 fflush(stderr);
656 if (emphasized) {
657 emphasized = FALSE;
658 // DrawTargetEmphasis(hwnd, emphasized);
659 }
660 pdinfo = (PDRAGINFO) mp1; /* Get DRAGINFO pointer */
661 if (pdinfo) {
662 DrgAccessDraginfo(pdinfo);
663 pditem = DrgQueryDragitemPtr(pdinfo, 0);
664 if (!pditem)
665 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DM_DROP");
666 /* Check valid rendering mechanisms and data */
667 ok = DrgVerifyRMF(pditem, DRM_LBOX, NULL)
668 && ~pditem->fsControl & DC_PREPARE;
669 if (ok) {
670 // ret = FullDrgName(pditem,buffer,buflen);
671 /* note: targetfail is returned to source for all items */
672 DrgSendTransferMsg(pdinfo->hwndSource, DM_ENDCONVERSATION,
673 MPFROMLONG(pditem->ulItemID),
674 MPFROMLONG(DMFL_TARGETSUCCESSFUL));
675 }
676 DeleteDragitemStrHandles(pdinfo); //
677 DrgDeleteDraginfoStrHandles(pdinfo);
678 DrgFreeDraginfo(pdinfo);
679 }
680 return 0;
681 } // switch
682 return pfnOldProc ? pfnOldProc(hwnd, msg, mp1, mp2) :
683 WinDefWindowProc(hwnd, msg, mp1, mp2);
684}
685
686//=== SBoxDlgProc() Select archiver to use or edit, supports list reorder too ===
687
688static PSZ pszCantFindMsg = "Can't find item %d";
689
690MRESULT EXPENTRY SBoxDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
691{
692 ARC_TYPE **ppatReturn; // Where to return selected archiver
693 ARC_TYPE *pat;
694 SHORT sSelect;
695 SHORT sItemCount;
696 CHAR szItemText[256];
697 CHAR szPCItemText[256]; // Parent or child item text
698 SHORT i;
699 APIRET apiret;
700 BOOL fShowAll;
701
702 static SHORT sLastSelect = LIT_NONE;
703
704 switch (msg) {
705 case WM_INITDLG:
706 if (!arcsigsloaded)
707 load_archivers();
708 if (!(ARC_TYPE **) mp2) {
709 Runtime_Error2(pszSrcFile, __LINE__, IDS_NODATATEXT);
710 WinDismissDlg(hwnd, 0);
711 break;
712 }
713 /* Passed arg points to where to return selected archiver definition
714 * On input arg value controls selection list content
715 * If non-NULL, dup names are suppressed
716 * If NULL, all definitions are shown
717 */
718 ppatReturn = (ARC_TYPE **) mp2;
719 fShowAll = *ppatReturn == NULL;
720 if (*ppatReturn)
721 *ppatReturn = arcsighead; // Preset to first
722 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) ppatReturn);
723 fill_listbox(hwnd, fShowAll, sLastSelect);
724
725#ifdef TEST_DRAG // fixme
726 {
727 HWND hwnd2 = WinWindowFromID(hwnd, ASEL_LISTBOX);
728 PFNWP pfn = WinSubclassWindow(hwnd2,
729 SDlgListboxSubclassProc);
730
731 WinSetWindowPtr(hwnd2, QWL_USER, (PVOID) pfn);
732 }
733#endif // TEST_DRAG fixme
734
735 break;
736
737 case WM_COMMAND:
738 ppatReturn = (ARC_TYPE **) WinQueryWindowPtr(hwnd, QWL_USER);
739 switch (SHORT1FROMMP(mp1)) {
740 case DID_OK:
741 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
742 ASEL_LISTBOX,
743 LM_QUERYSELECTION,
744 MPFROMSHORT(LIT_FIRST), MPVOID);
745 if (sSelect == LIT_NONE) {
746 Runtime_Error(pszSrcFile, __LINE__, "list empty");
747 return 0;
748 }
749 pat = arcsighead;
750 if (*ppatReturn) {
751 // If dups hidden, find archiver with matching id
752 *szItemText = 0;
753 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
754 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
755 if (!*szItemText)
756 pat = NULL;
757 else {
758 for (; pat; pat = pat->next) {
759 if (pat->id && !strcmp(szItemText, pat->id))
760 break; // Found it
761 }
762 }
763 }
764 else {
765 // If dups not hidden, lookup by count
766 for (i = 0; pat && i < sSelect; i++, pat = pat->next) ; // Scan
767 }
768 if (pat && (!*ppatReturn || (pat->id && pat->extract && pat->create))) {
769 *ppatReturn = pat;
770 }
771 else {
772 Runtime_Error(pszSrcFile, __LINE__, "no match");
773 // Refuse to select
774 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
775 MPFROMSHORT(LIT_NONE), FALSE);
776 return 0;
777 }
778 sLastSelect = sSelect;
779 WinDismissDlg(hwnd, TRUE);
780 return 0;
781
782 case DID_CANCEL:
783 if (arcsigsmodified) {
784 if (saymsg(MB_YESNO,
785 hwnd,
786 GetPString(IDS_ADCHANGESINMEMTEXT),
787 GetPString(IDS_ADREWRITETEXT), NullStr) == MBID_YES) {
788 PSZ ab2 = searchpath(GetPString(IDS_ARCHIVERBB2)); // Rewrite without prompting
789
790 rewrite_archiverbb2(ab2);
791 }
792 }
793 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
794 ASEL_LISTBOX,
795 LM_QUERYSELECTION,
796 MPFROMSHORT(LIT_FIRST), MPVOID);
797 if (sSelect != LIT_NONE)
798 sLastSelect = sSelect;
799 *ppatReturn = NULL;
800 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID); // fixme to understand why needed
801 return 0;
802
803 case ASEL_PB_ADD:
804 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
805 ASEL_LISTBOX,
806 LM_QUERYSELECTION,
807 MPFROMSHORT(LIT_FIRST), MPVOID);
808 if (sSelect != LIT_NONE) {
809 ARCDUMP ad;
810
811 memset(&ad, 0, sizeof(ARCDUMP));
812 ad.info = xmallocz(sizeof(ARC_TYPE), pszSrcFile, __LINE__);
813 if (ad.info) {
814 if (!WinDlgBox(HWND_DESKTOP,
815 hwnd,
816 ArcReviewDlgProc,
817 FM3ModHandle, AD_FRAME, MPFROMP(&ad))) {
818 free(ad.info);
819 }
820 else {
821 // Find self - assume all archivers listed since we are editing
822 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
823
824 if (!pat) {
825 if (arcsighead)
826 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
827 else
828 arcsighead = ad.info;
829 }
830 else {
831 // Insert before
832 if (pat->prev) {
833 ad.info->next = pat;
834 ad.info->prev = pat->prev;
835 pat->prev->next = ad.info;
836 pat->prev = ad.info;
837 }
838 else {
839 arcsighead = ad.info;
840 ad.info->next = pat;
841 pat->prev = ad.info;
842 }
843 }
844 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
845 MPFROM2SHORT(sSelect, 0),
846 MPFROMP(ad.info->id ? ad.info->id : "?"));
847 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
848 MPFROMSHORT(sSelect - 1), MPFROMSHORT(TRUE));
849 arcsigsmodified = TRUE;
850 }
851 }
852 }
853 return 0;
854 case ASEL_PB_DELETE:
855 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
856 ASEL_LISTBOX,
857 LM_QUERYSELECTION,
858 MPFROMSHORT(LIT_FIRST), MPVOID);
859 if (sSelect != LIT_NONE) {
860 // Find self - assume all archivers listed since we are editing
861 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
862
863 if (!pat)
864 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
865 else {
866 // Delete current
867 if (pat->prev) {
868 pat->prev->next = pat->next;
869 if (pat->next)
870 pat->next->prev = pat->prev;
871 }
872 else {
873 arcsighead = pat->next;
874 if (pat->next)
875 pat->next->prev = pat->prev;
876 }
877 }
878 free_arc_type(pat);
879 arcsigsmodified = TRUE;
880 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_DELETEITEM,
881 MPFROM2SHORT(sSelect, 0), MPVOID);
882 sItemCount =
883 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
884 MPVOID, MPVOID);
885 if (sSelect >= sItemCount)
886 sSelect--;
887 if (sSelect >= 0) {
888 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
889 MPFROMSHORT(sSelect), MPFROMSHORT(TRUE));
890 }
891 }
892 return 0;
893 case ASEL_PB_UP:
894 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
895 ASEL_LISTBOX,
896 LM_QUERYSELECTION,
897 MPFROMSHORT(LIT_FIRST), MPVOID);
898 if (sSelect != LIT_NONE && sSelect > 0) {
899 // Find self - assume all archivers listed since we are editing
900 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
901 if (!pat || !pat->prev)
902 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
903 else {
904 ARC_TYPE *patGDad;
905 ARC_TYPE *patDad;
906 ARC_TYPE *patChild;
907
908 patChild = pat->next;
909 patDad = pat->prev;
910 patGDad = patDad->prev;
911 patDad->next = patChild;
912 if (patChild)
913 patChild->prev = patDad;
914 patDad->prev = pat;
915 pat->next = patDad;
916 if (patGDad) {
917 patGDad->next = pat;
918 pat->prev = patGDad;
919 }
920 else {
921 arcsighead = pat;
922 pat->prev = NULL;
923 }
924
925 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
926 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
927 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
928 MPFROM2SHORT(sSelect - 1, 255),
929 MPFROMP(szPCItemText));
930 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
931 MPFROMSHORT(sSelect), MPFROMP(szPCItemText));
932 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
933 MPFROMSHORT(sSelect - 1), MPFROMP(szItemText));
934 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
935 MPFROMSHORT(sSelect - 1), MPFROMSHORT(TRUE));
936 arcsigsmodified = TRUE;
937 }
938 }
939 return 0;
940 case ASEL_PB_DOWN:
941 sSelect =
942 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYSELECTION,
943 MPFROMSHORT(LIT_FIRST), MPVOID);
944 sItemCount =
945 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
946 MPVOID, MPVOID);
947 if (sSelect != LIT_NONE && sSelect < sItemCount - 1) {
948 // Find self - assume all archivers listed since we are editing
949 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
950 if (!pat || !pat->next)
951 Runtime_Error(pszSrcFile, __LINE__, "Can't find item %d of %d",
952 sSelect, sItemCount);
953 else {
954 ARC_TYPE *patDad;
955 ARC_TYPE *patChild;
956
957 patDad = pat->prev;
958 patChild = pat->next;
959 pat->next = patChild->next;
960 patChild->next = pat;
961 pat->prev = patChild;
962 patChild->prev = patDad;
963 if (patDad) {
964 patDad->next = patChild;
965 patChild->prev = patDad;
966 }
967 else {
968 arcsighead = patChild;
969 patChild->prev = NULL;
970 }
971
972 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
973 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
974 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
975 MPFROM2SHORT(sSelect + 1, 255),
976 MPFROMP(szPCItemText));
977 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
978 MPFROMSHORT(sSelect), MPFROMP(szPCItemText));
979 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
980 MPFROMSHORT(sSelect + 1), MPFROMP(szItemText));
981 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
982 MPFROMSHORT(sSelect + 1), MPFROMSHORT(TRUE));
983 arcsigsmodified = TRUE;
984 }
985 }
986 return 0;
987
988 case ASEL_PB_REVERT:
989 // Reload without checking in case changed outside
990 sSelect =
991 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYSELECTION,
992 MPFROMSHORT(LIT_FIRST), MPVOID);
993 load_archivers();
994 fill_listbox(hwnd, TRUE, sSelect);
995 return 0;
996
997 case IDM_HELP:
998 if (hwndHelp) {
999 WinSendMsg(hwndHelp, HM_DISPLAY_HELP, MPFROM2SHORT(HELP_EDITARC, 0), // fixme to be HELP_SELARC
1000 MPFROMSHORT(HM_RESOURCEID));
1001 }
1002 }
1003 return 0; // WM_COMMAND
1004
1005 case WM_CONTROL:
1006 if (SHORT1FROMMP(mp1) == ASEL_LISTBOX && SHORT2FROMMP(mp1) == LN_ENTER)
1007 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1008 return 0;
1009
1010 case WM_CLOSE:
1011 WinDismissDlg(hwnd, FALSE);
1012 return 0;
1013
1014 default:
1015 break;
1016 }
1017 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1018}
1019
1020/*
1021 see archiver.tmp
1022 02-08-96 23:55 1
1023 8 Feb 96 23:55:32 2
1024 8 Feb 96 11:55p 3
1025 96-02-08 23:55:32 4
1026 31-02-98 23:55 5
1027 */
1028
1029#pragma alloc_text(ARCCNRS,ArcDateTime)
1030
1031BOOL ArcDateTime(CHAR * dt, INT type, CDATE * cdate, CTIME * ctime)
1032{
1033 INT x;
1034 BOOL ret = FALSE;
1035 CHAR *p, *pp, *pd;
1036
1037 if (dt && cdate && ctime) {
1038 memset(cdate, 0, sizeof(CDATE));
1039 memset(ctime, 0, sizeof(CTIME));
1040 if (type) {
1041 p = dt;
1042 while (*p && *p == ' ')
1043 p++;
1044 pd = dt;
1045 switch (type) {
1046 case 1:
1047 cdate->month = atoi(pd);
1048 p = to_delim(pd, "-/.");
1049 if (p) {
1050 p++;
1051 cdate->day = atoi(p);
1052 pd = p;
1053 p = to_delim(pd, "-/.");
1054 if (p) {
1055 p++;
1056 cdate->year = atoi(p);
1057 if (cdate->year > 80 && cdate->year < 1900)
1058 cdate->year += 1900;
1059 else if (cdate->year < 1900)
1060 cdate->year += 2000;
1061 ret = TRUE;
1062 p = strchr(p, ' ');
1063 if (p) {
1064 while (*p && *p == ' ')
1065 p++;
1066 ctime->hours = atoi(p);
1067 p = to_delim(pd, ":.");
1068 if (p) {
1069 p++;
1070 ctime->minutes = atoi(p);
1071 p = to_delim(pd, ":.");
1072 if (p) {
1073 p++;
1074 ctime->seconds = atoi(p);
1075 }
1076 }
1077 }
1078 }
1079 }
1080 break;
1081
1082 case 2:
1083 cdate->day = atoi(p);
1084 p = strchr(p, ' ');
1085 if (p) {
1086 p++;
1087 for (x = 0; x < 12; x++) {
1088 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1089 break;
1090 }
1091 if (x < 12) {
1092 cdate->month = x;
1093 p = strchr(p, ' ');
1094 if (p) {
1095 p++;
1096 cdate->year = atoi(p);
1097 if (cdate->year > 80 && cdate->year < 1900)
1098 cdate->year += 1900;
1099 else if (cdate->year < 1900)
1100 cdate->year += 2000;
1101 ret = TRUE;
1102 p = strchr(p, ' ');
1103 if (p) {
1104 while (*p && *p == ' ')
1105 p++;
1106 ctime->hours = atoi(p);
1107 p = to_delim(pd, ":.");
1108 if (p) {
1109 p++;
1110 ctime->minutes = atoi(p);
1111 p = to_delim(pd, ":.");
1112 if (p) {
1113 p++;
1114 ctime->seconds = atoi(p);
1115 }
1116 }
1117 }
1118 }
1119 }
1120 }
1121 break;
1122
1123 case 3:
1124 cdate->day = atoi(p);
1125 p = strchr(p, ' ');
1126 if (p) {
1127 p++;
1128 for (x = 0; x < 12; x++) {
1129 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1130 break;
1131 }
1132 if (x < 12) {
1133 cdate->month = x;
1134 p = strchr(p, ' ');
1135 if (p) {
1136 p++;
1137 cdate->year = atoi(p);
1138 if (cdate->year > 80 && cdate->year < 1900)
1139 cdate->year += 1900;
1140 else if (cdate->year < 1900)
1141 cdate->year += 2000;
1142 ret = TRUE;
1143 p = strchr(p, ' ');
1144 if (p) {
1145 while (*p && *p == ' ')
1146 p++;
1147 ctime->hours = atoi(p);
1148 p = to_delim(pd, ":.");
1149 if (p) {
1150 p++;
1151 pp = p;
1152 ctime->minutes = atoi(p);
1153 p = to_delim(pd, ":.");
1154 if (p) {
1155 p++;
1156 ctime->seconds = atoi(p);
1157 p += 2;
1158 if (toupper(*p) == 'P')
1159 ctime->hours += 12;
1160 }
1161 else {
1162 p = pp;
1163 p += 2;
1164 if (toupper(*p) == 'P')
1165 ctime->hours += 12;
1166 }
1167 }
1168 }
1169 }
1170 }
1171 }
1172 break;
1173
1174 case 4:
1175 cdate->year = atoi(p);
1176 if (cdate->year > 80 && cdate->year < 1900)
1177 cdate->year += 1900;
1178 else if (cdate->year < 1900)
1179 cdate->year += 2000;
1180 p = to_delim(pd, "-/.");
1181 if (p) {
1182 p++;
1183 cdate->month = atoi(p);
1184 pd = p;
1185 p = to_delim(pd, "-/.");
1186 if (p) {
1187 p++;
1188 cdate->day = atoi(p);
1189 ret = TRUE;
1190 p = strchr(p, ' ');
1191 if (p) {
1192 while (*p && *p == ' ')
1193 p++;
1194 ctime->hours = atoi(p);
1195 p = to_delim(pd, ":.");
1196 if (p) {
1197 p++;
1198 ctime->minutes = atoi(p);
1199 p = to_delim(pd, ":.");
1200 if (p) {
1201 p++;
1202 ctime->seconds = atoi(p);
1203 }
1204 }
1205 }
1206 }
1207 }
1208 break;
1209
1210 case 5:
1211 cdate->day = atoi(pd);
1212 p = to_delim(pd, "-/.");
1213 if (p) {
1214 p++;
1215 cdate->month = atoi(p);
1216 pd = p;
1217 p = to_delim(pd, "-/.");
1218 if (p) {
1219 p++;
1220 cdate->year = atoi(p);
1221 if (cdate->year > 80 && cdate->year < 1900)
1222 cdate->year += 1900;
1223 else if (cdate->year < 1900)
1224 cdate->year += 2000;
1225 ret = TRUE;
1226 p = strchr(p, ' ');
1227 if (p) {
1228 while (*p && *p == ' ')
1229 p++;
1230 ctime->hours = atoi(p);
1231 p = to_delim(pd, ":.");
1232 if (p) {
1233 p++;
1234 ctime->minutes = atoi(p);
1235 p = to_delim(pd, ":.");
1236 if (p) {
1237 p++;
1238 ctime->seconds = atoi(p);
1239 }
1240 }
1241 }
1242 }
1243 }
1244 break;
1245
1246 default:
1247 break;
1248 }
1249 }
1250 }
1251 return ret;
1252}
Note: See TracBrowser for help on using the repository browser.