source: trunk/dll/avl.c@ 618

Last change on this file since 618 was 618, checked in by Steven Levine, 18 years ago

Add more drag/drop error checking
Use FreeDragInfoData
Sync with NumItemsToUnhilite AcceptOneDrop GetOneDrop mods

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