Subversion Repositories filter_foundry

Rev

Rev 393 | Rev 456 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
  3.     Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
  4.     Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. */
  20.  
  21. /* This is PLATFORM INDEPENDENT user interface code - mainly dialog logic */
  22.  
  23. #include "ff.h"
  24. #include "compat_string.h"
  25.  
  26. int ctls[8],maps[4];
  27. int checksliders_result;
  28.  
  29. /* one-time initialisation of dialog box */
  30.  
  31. void builddlginit(DIALOGREF dp){
  32.         int i;
  33.         char s[0x100];
  34.  
  35.         if(gdata->parmloaded){
  36.                 SetDlgItemTextA(dp,CATEGORYITEM, gdata->parm.szCategory);
  37.                 SetDlgItemTextA(dp,TITLEITEM,    gdata->parm.szTitle);
  38.                 SetDlgItemTextA(dp,COPYRIGHTITEM,gdata->parm.szCopyright);
  39.                 SetDlgItemTextA(dp,AUTHORITEM,   gdata->parm.szAuthor);
  40.                 for(i=0;i<4;++i){
  41.                         SetDlgItemTextA(dp,FIRSTMAPNAMEITEM+i,gdata->parm.szMap[i]);
  42.                 }
  43.                 for(i=0;i<8;++i){
  44.                         SetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i,gdata->parm.szCtl[i]);
  45.                 }
  46.         }else{
  47.                 /* strictly speaking this is not needed on the Mac,
  48.                    we can set initial values statically in the rez description */
  49.                 SetDlgItemTextA(dp,CATEGORYITEM, "Filter Foundry");
  50.                 SetDlgItemTextA(dp,TITLEITEM,    "Untitled");
  51.                 SetDlgItemTextA(dp,COPYRIGHTITEM,""); //"Filter Foundry Copyright (C) 2003-2009 Toby Thain, 2018-" RELEASE_YEAR " Daniel Marschall"
  52.                 SetDlgItemTextA(dp,AUTHORITEM,   "Anonymous");
  53.                 strcpy(s,"Map X");
  54.                 for(i = 0; i < 4; ++i){
  55.                         s[4] = '0'+i;
  56.                         SetDlgItemTextA(dp,FIRSTMAPNAMEITEM+i,s);
  57.                 }
  58.                 strcpy(s,"ctl(X)");
  59.                 for(i = 0; i < 8; ++i){
  60.                         s[4] = '0'+i;
  61.                         SetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i,s);
  62.                 }
  63.         }
  64.  
  65.         checksliders_result = checksliders(4,ctls,maps);
  66.         for(i = 4; i--;){
  67.                 DISABLEDLGITEM(dp,FIRSTMAPCHECKITEM+i);
  68.                 if(maps[i] || (checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS))
  69.                         CHECKDLGBUTTON(dp,FIRSTMAPCHECKITEM+i,true);
  70.                 else
  71.                         HideDialogItem(dp,FIRSTMAPNAMEITEM+i);
  72.         }
  73.         for(i = 8; i--;){
  74.                 DISABLEDLGITEM(dp,FIRSTCTLCHECKITEM+i);
  75.                 if((ctls[i] || (checksliders_result & CHECKSLIDERS_CTL_AMBIGUOUS)) &&
  76.                    // When map() is activated, we don't need ctl labels,
  77.                    // since the standalone filter will only show map labels
  78.                    !maps[i/2] &&
  79.                    (!(checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS))
  80.                    )
  81.                         CHECKDLGBUTTON(dp,FIRSTCTLCHECKITEM+i,true);
  82.                 else
  83.                         HideDialogItem(dp,FIRSTCTLNAMEITEM+i);
  84.         }
  85.  
  86.         CHECKDLGBUTTON(dp, PROTECTITEM, 0); // TODO: should we remember the last setting?
  87.  
  88.         SELECTDLGITEMTEXT(dp,TITLEITEM,0,-1);
  89. }
  90.  
  91. Boolean containsUnicodeInput(DIALOGREF dp, int item) {
  92.         enum { MAXFIELD = 0x100 };
  93.         char s[MAXFIELD + 1];
  94.         wchar_t sw[MAXFIELD + 1];
  95.         size_t i;
  96.  
  97.         GetDlgItemTextA(dp, item, s, MAXFIELD);
  98.         GetDlgItemTextW(dp, item, sw, MAXFIELD);
  99.         for (i = 0; i < strlen(s); i++) {
  100.                 if (((wchar_t)s[i] != sw[i]) && (s[i] == '?')) {
  101.                         return true;
  102.                 }
  103.         }
  104.  
  105.         return false;
  106. }
  107.  
  108. Boolean containsExtCharset(DIALOGREF dp, int item) {
  109.         enum { MAXFIELD = 0x100 };
  110.         char s[MAXFIELD + 1];
  111.         size_t i;
  112.  
  113.         GetDlgItemTextA(dp, item, s, MAXFIELD);
  114.         for (i = 0; i < strlen(s); i++) {
  115.                 if ((unsigned char)s[i] > (unsigned char)0x7F) {
  116.                         return true;
  117.                 }
  118.         }
  119.  
  120.         return false;
  121. }
  122.  
  123. /* process an item hit. return false if the dialog is finished; otherwise return true. */
  124.  
  125. Boolean builddlgitem(DIALOGREF dp,int item){
  126.         enum{MAXFIELD=0x100};
  127.         char s[MAXFIELD+1];
  128.         int i,needui;
  129.         TCHAR fname[MAX_PATH + 1];
  130.         StandardFileReply sfr;
  131.         NavReplyRecord reply;
  132.         #ifdef UNICODE
  133.         Boolean unicode;
  134.         #endif
  135.         Boolean extCharset;
  136.  
  137.         switch(item){
  138. #ifdef MAC_ENV
  139.         case ok:
  140. #else
  141.         case IDOK:
  142. #endif
  143.                 // Do a few checks first
  144.                 GetDlgItemTextA(dp, CATEGORYITEM, s, MAXFIELD);
  145.                 if (strlen(s) == 0) {
  146.                         simplealert((TCHAR*)TEXT("Category must not be empty!"));
  147.                         return true; // don't continue (i.e. don't call EndDialog). Let the user correct the input
  148.                 }
  149.                 GetDlgItemTextA(dp, TITLEITEM, s, MAXFIELD);
  150.                 if (strlen(s) == 0) {
  151.                         simplealert((TCHAR*)TEXT("Title must not be empty!"));
  152.                         return true; // don't continue (i.e. don't call EndDialog). Let the user correct the input
  153.                 }
  154.  
  155.                 // The PiPL and PARM structure does only define single byte charsets
  156.                 #ifdef UNICODE
  157.                 unicode =
  158.                         containsUnicodeInput(dp, CATEGORYITEM) ||
  159.                         containsUnicodeInput(dp, TITLEITEM) ||
  160.                         containsUnicodeInput(dp, COPYRIGHTITEM) ||
  161.                         containsUnicodeInput(dp, AUTHORITEM);
  162.                 #endif
  163.                 extCharset =
  164.                         containsExtCharset(dp, CATEGORYITEM) ||
  165.                         containsExtCharset(dp, TITLEITEM) ||
  166.                         containsExtCharset(dp, COPYRIGHTITEM) ||
  167.                         containsExtCharset(dp, AUTHORITEM);
  168.  
  169.                 // The AETE structure does only define single byte charsets
  170.                 for (i = 0; i < 8; ++i) {
  171.                         if (ctls[i] || (checksliders_result & CHECKSLIDERS_CTL_AMBIGUOUS)) {
  172.                                 #ifdef UNICODE
  173.                                 unicode |= containsUnicodeInput(dp, FIRSTCTLNAMEITEM + i);
  174.                                 #endif
  175.                                 extCharset |= containsExtCharset(dp, FIRSTCTLNAMEITEM + i);
  176.                         }
  177.                 }
  178.                 for (i = 0; i < 4; ++i) {
  179.                         if (maps[i] || (checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS)) {
  180.                                 #ifdef UNICODE
  181.                                 unicode |= containsUnicodeInput(dp, FIRSTMAPNAMEITEM + i);
  182.                                 #endif
  183.                                 extCharset |= containsExtCharset(dp, FIRSTMAPNAMEITEM + i);
  184.                         }
  185.                 }
  186.  
  187.                 #ifdef UNICODE
  188.                 if (unicode) {
  189.                         simplewarning((TCHAR*)TEXT("The internal structures of Photoshop and Filter Factory are not compatible with Unicode characters. It is highly recommended that you only use characters of your current charset. Unicode characters will be converted into question mark symbols."));
  190.                 }
  191.                 else
  192.                 #endif
  193.                 if (extCharset) {
  194.                         simplewarning((TCHAR*)TEXT("You were using characters of an extended charset. The characters might look correct on your machine, but on a machine in a different country, the characters might look wrong. Please consider using the ASCII character set only (i.e. Latin characters without accent marks)."));
  195.                 }
  196.  
  197.                 // Now begin
  198.                 memset(&gdata->parm,0,sizeof(PARM_T));
  199.                 GetDlgItemTextA(dp,CATEGORYITEM,gdata->parm.szCategory,MAXFIELD-4/*ProtectFlag*/);
  200.                 GetDlgItemTextA(dp,TITLEITEM,gdata->parm.szTitle,MAXFIELD);
  201.                 GetDlgItemTextA(dp,COPYRIGHTITEM,gdata->parm.szCopyright,MAXFIELD);
  202.                 GetDlgItemTextA(dp,AUTHORITEM,gdata->parm.szAuthor,MAXFIELD);
  203.                 gdata->parm.cbSize = PARM_SIZE;
  204.                 gdata->parm.standalone = 1;  //0=original FF, 1=standalone filter
  205.                 needui = 0;
  206.                 // Sliders
  207.                 for(i = 0; i < 8; ++i){
  208.                         gdata->parm.val[i] = slider[i];
  209.                         gdata->parm.ctl_used[i] = ctls[i] || (checksliders_result & CHECKSLIDERS_CTL_AMBIGUOUS);
  210.                         needui |= gdata->parm.ctl_used[i];
  211.                         GetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i, gdata->parm.szCtl[i],MAXFIELD);
  212.                 }
  213.                 // Maps
  214.                 for (i = 0; i < 4; ++i) {
  215.                         gdata->parm.map_used[i] = maps[i] || (checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS);
  216.                         needui |= gdata->parm.map_used[i];
  217.                         GetDlgItemTextA(dp, FIRSTMAPNAMEITEM + i, gdata->parm.szMap[i], MAXFIELD);
  218.                 }
  219.                 // Expressions
  220.                 for (i = 0; i < 4; ++i) {
  221.                         if (!expr[i]) {
  222.                                 simplealert((TCHAR*)TEXT("Bug! see builddlgitem"));
  223.                                 return true; // keep going. Let the user try again
  224.                         }
  225.                         if (strlen(expr[i]) >= sizeof(gdata->parm.szFormula[i])) {
  226.                                 if (i == 0) {
  227.                                         simplealert((TCHAR*)TEXT("Attention! The formula for channel R was too long (longer than 1023 characters) and was truncated."));
  228.                                 }
  229.                                 else if (i == 1) {
  230.                                         simplealert((TCHAR*)TEXT("Attention! The formula for channel G was too long (longer than 1023 characters) and was truncated."));
  231.                                 }
  232.                                 else if (i == 2) {
  233.                                         simplealert((TCHAR*)TEXT("Attention! The formula for channel B was too long (longer than 1023 characters) and was truncated."));
  234.                                 }
  235.                                 else if (i == 3) {
  236.                                         simplealert((TCHAR*)TEXT("Attention! The formula for channel A was too long (longer than 1023 characters) and was truncated."));
  237.                                 }
  238.                                 expr[i][sizeof(gdata->parm.szFormula[i]) - 1] = '\0';
  239.                         }
  240.                         strcpy(gdata->parm.szFormula[i], expr[i]);
  241.                 }
  242.                 gdata->parm.popDialog = needui; //true if need to pop a parameter dialog
  243.                 gdata->parm.unknown1 = gdata->parm.unknown2 = gdata->parm.unknown3 = 0;
  244.                 gdata->parm.iProtected = ISDLGBUTTONCHECKED(dp,PROTECTITEM); // == 1 means protected
  245.                 gdata->obfusc = ISDLGBUTTONCHECKED(dp,PROTECTITEM);
  246.  
  247.                 // TODO: Unicode!
  248.                 //xstrcpy(fname, gdata->parm.szTitle);
  249.                 /*
  250.                 for (i = 0; i < (int)strlen(gdata->parm.szTitle); i++) {
  251.                         fname[i] = gdata->parm.szTitle[i];
  252.                         fname[i + 1] = 0;
  253.                 }
  254.                 */
  255.                 GetDlgItemText(dp, TITLEITEM, fname, MAXFIELD);
  256.  
  257.                 #ifdef MACMACHO
  258.                 strcat(fname, ".plugin");
  259.                 #endif
  260.                 if (putfile(
  261.                         #ifdef MAC_ENV
  262.                         (StringPtr)_strdup("\pMake standalone filter"), // "\p" means "Pascal string"
  263.                         (StringPtr)myc2pstr(_strdup(fname)),
  264.                         PS_FILTER_FILETYPE, kPhotoshopSignature, & reply, & sfr,
  265.                         "8bf", "Filter plugin file (.8bf)\0*.8bf\0\0", 1
  266.                         #else
  267.                         TEXT("Make standalone filter"),
  268.                         fname,
  269.                         PS_FILTER_FILETYPE, kPhotoshopSignature, & reply, & sfr,
  270.                         TEXT("8bf"),
  271.                         TEXT("Filter plugin file (.8bf)\0*.8bf\0\0"), 1
  272.                         , (HWND)dp
  273.                         #endif
  274.                 )) {
  275.                         make_standalone(&sfr);
  276.                 }
  277.                 else {
  278.                         return true; // keep going. Let the user correct their input
  279.                 }
  280.  
  281.                 return false; // end dialog
  282. #ifdef MAC_ENV
  283.         case cancel:
  284. #else
  285.         case IDCANCEL:
  286. #endif
  287.                 return false; // end dialog
  288.         case PROTECTITEM:
  289.                 CHECKDLGBUTTON(dp, item, ISDLGBUTTONCHECKED(dp,item) ^ 1);
  290.                 break;
  291.         }
  292.  
  293.         return true; // keep going
  294. }
  295.