- Timestamp:
- 05/22/11 16:40:03 (1 year ago)
- Files:
-
- trunk/win32/entice/aboutform.d (modified) (2 diffs)
- trunk/win32/entice/aclist.d (added)
- trunk/win32/entice/advfindpanel.d (modified) (20 diffs)
- trunk/win32/entice/apiinfo.d (modified) (9 diffs)
- trunk/win32/entice/apisearchopts.d (modified) (12 diffs)
- trunk/win32/entice/apiviewer.d (modified) (3 diffs)
- trunk/win32/entice/checkup.d (modified) (4 diffs)
- trunk/win32/entice/compile.d (added)
- trunk/win32/entice/controlchildren.d (modified) (1 diff)
- trunk/win32/entice/ddcontrolchildren.d (modified) (27 diffs)
- trunk/win32/entice/ddcontrolspace.d (modified) (1 diff)
- trunk/win32/entice/dddesignform.d (modified) (1 diff)
- trunk/win32/entice/ddeditorstyler.d (modified) (1 diff)
- trunk/win32/entice/ddexprops.d (modified) (9 diffs)
- trunk/win32/entice/ddfindreplace.d (modified) (9 diffs)
- trunk/win32/entice/ddopenparser.d (modified) (1 diff)
- trunk/win32/entice/ddoptions.d (modified) (8 diffs)
- trunk/win32/entice/ddoptscompilerpanel.d (added)
- trunk/win32/entice/ddoptsdesignpanel.d (modified) (5 diffs)
- trunk/win32/entice/ddoptsnetworkpanel.d (modified) (8 diffs)
- trunk/win32/entice/ddoptspluginspanel.d (modified) (5 diffs)
- trunk/win32/entice/ddprojectfile.d (added)
- trunk/win32/entice/ddprojectmanager.d (modified) (8 diffs)
- trunk/win32/entice/dependencies (added)
- trunk/win32/entice/dependencies/ini.d (moved) (moved from trunk/win32/entice/ini.d)
- trunk/win32/entice/dependencies/rdflregistry.d (moved) (moved from trunk/win32/entice/rdflregistry.d)
- trunk/win32/entice/dependencies/rgroup.d (moved) (moved from trunk/win32/entice/rgroup.d)
- trunk/win32/entice/dependencies/rini.d (moved) (moved from trunk/win32/entice/rini.d)
- trunk/win32/entice/design.d (modified) (2 diffs)
- trunk/win32/entice/designcontrol.d (modified) (3 diffs)
- trunk/win32/entice/dfldesigner.d (modified) (72 diffs)
- trunk/win32/entice/dfldesigner.rc (modified) (1 diff)
- trunk/win32/entice/dinstallform.d (added)
- trunk/win32/entice/dirchanges.d (modified) (1 diff)
- trunk/win32/entice/dlangselectorpanel.d (added)
- trunk/win32/entice/dmdversionselectorpanel.d (added)
- trunk/win32/entice/downloaderpanel.d (added)
- trunk/win32/entice/drawing.d (modified) (1 diff)
- trunk/win32/entice/dscale.d (modified) (1 diff)
- trunk/win32/entice/editorexprops.d (modified) (10 diffs)
- trunk/win32/entice/editorstyler.d (modified) (1 diff)
- trunk/win32/entice/etabber.d (modified) (1 diff)
- trunk/win32/entice/findreplace.d (modified) (15 diffs)
- trunk/win32/entice/firstsetupstartpagepanel.d (added)
- trunk/win32/entice/images/bug16.ico (added)
- trunk/win32/entice/images/dfldesigner.ico (added)
- trunk/win32/entice/images/dlsm.ico (added)
- trunk/win32/entice/images/e.ico (modified) (previous)
- trunk/win32/entice/images/e64.png (added)
- trunk/win32/entice/images/edlg.gif (added)
- trunk/win32/entice/images/happylovesm.ico (added)
- trunk/win32/entice/images/madsm.ico (added)
- trunk/win32/entice/images/mailsm.ico (added)
- trunk/win32/entice/images/treeadd12.bmp (modified) (previous)
- trunk/win32/entice/inputform.d (modified) (3 diffs)
- trunk/win32/entice/mak.bat (modified) (1 diff)
- trunk/win32/entice/newform.d (modified) (10 diffs)
- trunk/win32/entice/options.d (modified) (4 diffs)
- trunk/win32/entice/parse.d (modified) (5 diffs)
- trunk/win32/entice/plugins.d (modified) (13 diffs)
- trunk/win32/entice/process.d (added)
- trunk/win32/entice/projectmanager.d (modified) (3 diffs)
- trunk/win32/entice/promptbox.d (added)
- trunk/win32/entice/proppanel.d (modified) (1 diff)
- trunk/win32/entice/savetodirpanel.d (added)
- trunk/win32/entice/scintilladlex.d (modified) (7 diffs)
- trunk/win32/entice/scistyles.d (modified) (1 diff)
- trunk/win32/entice/startpage.d (modified) (11 diffs)
- trunk/win32/entice/tabber.d (modified) (32 diffs)
- trunk/win32/entice/toolbox.d (modified) (3 diffs)
- trunk/win32/entice/trimjsonapi.d (added)
- trunk/win32/entice/usercomment.d (modified) (11 diffs)
- trunk/win32/entice/usercommentemail.d (modified) (5 diffs)
- trunk/win32/entice/usereditlistbox.d (added)
- trunk/win32/entice/util.d (modified) (5 diffs)
- trunk/win32/entice/winapi.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/win32/entice/aboutform.d
r101 r102 3 3 4 4 5 import dfl.all, dfl. winapi;5 import dfl.all, dfl.internal.winapi; 6 6 7 7 import std.file, std.path; … … 215 215 okBtn.name = "okBtn"; 216 216 okBtn.text = "OK"; 217 okBtn.bounds = dfl. base.Rect(296, 240, 75, 23);217 okBtn.bounds = dfl.all.Rect(296, 240, 75, 23); 218 218 okBtn.parent = this; 219 219 //~DFL Tabber:dfl.panel.Panel=tabs 220 220 tabs = new Tabber(); 221 221 tabs.name = "tabs"; 222 tabs.bounds = dfl. base.Rect(0, 0, 376, 232);222 tabs.bounds = dfl.all.Rect(0, 0, 376, 232); 223 223 tabs.parent = this; 224 224 //~Entice Designer 0.8pre8 code ends here. trunk/win32/entice/advfindpanel.d
r101 r102 6 6 7 7 import std.path, std.thread, std.file, std.stream, 8 std.regexp, std.conv ;8 std.regexp, std.conv, std.string; 9 9 10 10 import dfl.scintilla, dfl.cpp.scintilla, dfl.cpp.scilexer; … … 321 321 } 322 322 return false; 323 } 324 325 static bool isFileOrDirHidden(char[] x) 326 { 327 bool wasdot = false; 328 foreach_reverse(char c; x) 329 { 330 if('.' == c) 331 { 332 wasdot = true; 333 continue; 334 } 335 if('\\' == c || '/' == c) 336 { 337 return wasdot; 338 } 339 wasdot = false; 340 } 341 return wasdot; 323 342 } 324 343 … … 399 418 if(de.isdir()) 400 419 { 420 if(isFileOrDirHidden(de.name)) 421 goto skip_this_dir; 401 422 foreach(char[] nodir; excludeDirs) 402 423 { … … 469 490 if(de.isdir()) 470 491 { 492 if(isFileOrDirHidden(de.name)) 493 goto skip_this_dir; 471 494 foreach(char[] nodir; excludeDirs) 472 495 { … … 621 644 622 645 623 class AdvFindScintilla: Scintilla 646 class AdvFindScintilla: Scintilla, IFindReplaceTitle 624 647 { 625 648 static struct SCell … … 627 650 char ch; // Character. 628 651 ubyte st; // Style. 652 } 653 654 655 string findReplaceTitle() // getter 656 { 657 return "Find within Advanced Find results"; 629 658 } 630 659 … … 715 744 sendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_EMPTY); 716 745 717 sendEditor(SCI_SETFOLDFLAGS, 16, 0); // 16 Draw line below if not expanded. 746 //sendEditor(SCI_SETFOLDFLAGS, 16, 0); // 16 Draw line below if not expanded. 747 //sendEditor(SCI_SETFOLDFLAGS, 2 | 4, 0); // 16 Draw line above (expanded & not) 718 748 719 749 sendEditor(SCI_SETMARGINSENSITIVEN, MARGIN_SCRIPT_FOLD_INDEX, 1); … … 881 911 { 882 912 sendEditor(SCI_SETSEL, -1, -1); // Set sel at very end, no selected chars, and scroll to it. The starting line should be in view. 913 914 //if(autoCollapseAdvancedFind) 915 { 916 int maxLine = sendEditor(SCI_GETLINECOUNT); 917 for(int iline = 0; iline < maxLine; iline++) 918 { 919 int level = sendEditor(SCI_GETFOLDLEVEL, iline); 920 if((level & SC_FOLDLEVELHEADERFLAG) 921 && (SC_FOLDLEVELBASE == (level & SC_FOLDLEVELNUMBERMASK))) 922 { 923 int lineMaxSubord = sendEditor(SCI_GETLASTCHILD, iline, -1); 924 sendEditor(SCI_SETFOLDEXPANDED, iline, 0); 925 if (lineMaxSubord > iline) 926 sendEditor(SCI_HIDELINES, iline + 1, lineMaxSubord); 927 } 928 } 929 } 930 883 931 startLine = sendEditor(SCI_LINEFROMPOSITION, int.max); // "The return value is the last line if pos is beyond the end of the document." 884 932 … … 891 939 startLine++; 892 940 } 893 s2 = "Searching for: "; 941 //s2 = "Searching for: "; 942 s2 = "Search for: "; 894 943 s3 = searchingFor; 895 944 … … 1019 1068 afthd = null; 1020 1069 1021 //disp.forceAppend("Search stopped\r\n");1022 1070 disp.addEndLine(false); 1023 1071 … … 1029 1077 this() 1030 1078 { 1079 flags |= ETabFlags.ALLOW_DETACH; 1031 1080 Entity ent = new Entity(); 1032 1081 super(ent, "Advanced Find"); … … 1049 1098 1050 1099 findpanel.findBtn.enabled = true; 1100 findpanel.findBox.select(); 1051 1101 }); 1052 1102 } … … 1057 1107 { 1058 1108 char[1024 * 4] buf = void; 1059 1060 1109 disp.sendEditor(SCI_GETCURLINE, buf.length, cast(size_t)buf.ptr); 1110 string line = .toString(buf); 1061 1111 disp.selectionLength = 0; 1062 1063 size_t iw; 1064 size_t lparen = 0, rparen = 0, colon = 0; 1065 for(iw = 0; buf[iw]; iw++) 1066 { 1067 if('(' == buf[iw]) 1068 { 1069 lparen = iw; 1070 rparen = 0; 1071 } 1072 else if(')' == buf[iw]) 1073 { 1074 if(lparen) 1075 rparen = iw; 1076 } 1077 else if(':' == buf[iw] && iw > 1) 1078 { 1079 char[] fn; 1080 uint linnum; 1081 if(lparen && rparen) 1082 { 1083 fn = buf[0 .. lparen]; 1084 try 1085 { 1086 linnum = std.conv.toUint(buf[lparen + 1 .. rparen]); 1087 } 1088 catch 1089 { 1090 } 1091 } 1092 else if(colon) 1093 { 1094 fn = buf[0 .. colon]; 1095 } 1096 else 1097 { 1098 break; 1099 } 1100 fn = fn.dup; 1101 1102 auto altdown = Control.modifierKeys & Keys.ALT; 1103 1104 auto clpos = disp.sendEditor(SCI_POSITIONFROMLINE, -1); // Current line position. 1105 disp.sendEditor(SCI_SETSEL, clpos, clpos + fn.length); 1106 1107 if(mainForm) 1108 { 1109 EditorTab etab; 1110 1111 mainForm.doOpen(fn, true); // wantEditor = true 1112 etab = cast(EditorTab)getCurrentTab(); 1113 if(!etab) 1114 break; 1115 //if(etab is this) 1116 // break; 1117 1118 if(linnum) 1119 { 1120 Application.doEvents(); 1121 if(altdown) 1122 { 1123 //EditorTab etab = cast(EditorTab)getCurrentTab(); 1124 //if(etab) 1125 { 1126 etab.switchToOppositeView(); 1127 Application.doEvents(); // ! 1128 } 1129 } 1130 mainForm.doGotoLine(etab.asci, linnum); 1131 //Application.doEvents(); 1132 //etab.asci.select(); 1133 etab.asci.delayInvoke( 1134 function(Control cc, size_t[] params) 1135 { 1136 cc.select(); 1137 }, null); 1138 } 1139 } 1140 1141 break; 1142 } 1143 } 1112 doubleclickedStatusOpenFile(line); 1144 1113 } 1145 1114 … … 1150 1119 findpanel.invoke( 1151 1120 { 1152 if(file.length )1121 if(file.length && afthd) 1153 1122 { 1154 1123 //disp.forceAppend(std.string.format("%s(%s): %s\r\n", file, linnum, matchline)); … … 1222 1191 1223 1192 1193 Form detachform; 1194 1195 Form getDetachForm(Tabber tabc, int index) 1196 { 1197 if(detachform) 1198 return detachform; 1199 detachform = new DetachedTabForm(tabc, tabc.tabs[index]); 1200 detachform.owner = mainForm; 1201 detachform.clientSize = Size(700, 500); 1202 return detachform; 1203 } 1204 1205 1206 override void onDetach(Tabber tabc, int index) 1207 { 1208 if(findpanel && disp) 1209 { 1210 if(!detachform) 1211 detachform = getDetachForm(tabc, index); 1212 { 1213 findpanel.parent = detachform; 1214 disp.parent = detachform; 1215 detachform.show(); 1216 findpanel.bringToFront(); 1217 } 1218 } 1219 } 1220 1221 1222 override void onAttach(Tabber tabc, int index) 1223 { 1224 if(detachform) 1225 { 1226 findpanel.parent = tabc; 1227 disp.parent = tabc; 1228 detachform.close(); 1229 detachform = null; 1230 } 1231 if(findpanel && disp) 1232 { 1233 findpanel.parent = tabc; 1234 disp.parent = tabc; 1235 findpanel.bringToFront(); 1236 } 1237 } 1238 1239 1224 1240 override void onHide(Tabber tabc, int index) 1225 1241 { … … 1234 1250 { 1235 1251 super.onShow(tabc, index); 1252 1253 Control tparent = tabc; 1254 if(tabc.tabs[index].detached) 1255 { 1256 if(!detachform) 1257 detachform = getDetachForm(tabc, index); 1258 tparent = detachform; 1259 } 1236 1260 1237 1261 if(!findpanel) … … 1244 1268 dock = DockStyle.TOP; 1245 1269 backColor = SystemColors.control; // Because of tabber's color. 1246 parent = t abc;1270 parent = tparent; 1247 1271 //show(); 1248 1272 //findBox.select(); // Need to select it each show because of hiding/showing the tab removes the selection. … … 1255 1279 { 1256 1280 dock = DockStyle.FILL; 1257 parent = t abc;1281 parent = tparent; 1258 1282 1259 1283 doubleClick ~= &disp_doubleClick; … … 1263 1287 findpanel.show(); 1264 1288 //findpanel.findBox.select(); // Not needed anymore; handled in DFL. 1289 if(detachform) 1290 detachform.acceptButton = findpanel.findBtn; 1265 1291 mainForm.acceptButton = findpanel.findBtn; 1266 1292 disp.show(); 1293 tparent.show(); 1267 1294 1268 1295 DdFindReplace.sci = disp; // Let the user find within the advanced find results. … … 1290 1317 i = tabs.addTab(advfindtab); 1291 1318 } 1292 tabs.selectedIndex = i; 1319 if(!tabs.tabs[i].detached) 1320 tabs.selectedIndex = i; 1321 1322 advfindtab.findpanel.findBox.select(); 1293 1323 } 1294 1324 trunk/win32/entice/apiinfo.d
r101 r102 8 8 9 9 import util : nextWord; 10 11 12 debug 13 { 14 version = API_PICKY_JSON; 15 version = addApiEntry_THROWS; 16 } 10 17 11 18 … … 557 564 char[] name; // "std.file.read" would be "read". 558 565 ApiFlags flags; 566 //ushort line; // Only set via JSON. 559 567 560 568 … … 784 792 return data.ptr[0 .. length]; 785 793 } 794 795 const int MAX_LENGTH = ushort.max; 786 796 } 787 797 … … 1206 1216 pparent = findEntry(toparent); 1207 1217 if(!pparent) 1218 { 1219 version(addApiEntry_THROWS) 1220 throw new Exception(std.string.format("... Unable to add `%.*s . %.*s` - cannot find parent\n", toparent, ae.name)); 1208 1221 return; 1222 } 1209 1223 1210 1224 if(pparent.type & ApiType.NEST) 1225 { 1211 1226 (cast(ApiNest*)pparent).addNestEntry(ae); 1227 } 1228 else 1229 { 1230 version(addApiEntry_THROWS) 1231 throw new Exception(std.string.format("... Unable to add `%.*s . %.*s` - cannot nest in parent\n", toparent, ae.name)); 1232 return; 1233 } 1212 1234 } 1213 1235 … … 1298 1320 break; 1299 1321 } 1322 /+remainbytes--; 1323 if(remainbytes < 0) 1324 { 1325 assert(remainbytes >= 0, "loadApiInfo, streamReadLine: reamainbytes is negative"); 1326 remainbytes = 0; 1327 }+/ 1300 1328 if('\r' == ch) 1301 1329 { … … 1322 1350 } 1323 1351 1324 1352 char _jtNext = 0; 1353 bool streamReadJsonToken() 1354 { 1355 if(_jtNext) 1356 { 1357 _linebuf[0] = _jtNext; 1358 _jtNext = 0; 1359 line = _linebuf[0 .. 1]; 1360 return true; 1361 } 1362 line = null; 1363 bool isgood = true; 1364 size_t srliw = 0; 1365 char ch; 1366 bool instring = false; 1367 bool inescape = false; 1368 charloop: 1369 for(;;) 1370 { 1371 if(srliw >= _linebuf.length) 1372 break; // ? or should it keep reading until the end of the line. 1373 if(1 != stm.readBlock(&ch, 1)) 1374 { 1375 isgood = false; 1376 break; 1377 } 1378 /+remainbytes--; 1379 if(remainbytes < 0) 1380 { 1381 assert(remainbytes >= 0, "loadApiInfo, streamReadJsonToken: reamainbytes is negative"); 1382 remainbytes = 0; 1383 }+/ 1384 if(instring) 1385 { 1386 if(inescape) 1387 { 1388 inescape = false; 1389 } 1390 else 1391 { 1392 if(ch == '"') 1393 { 1394 instring = false; 1395 } 1396 else if(ch == '\\') 1397 { 1398 inescape = true; 1399 } 1400 } 1401 _linebuf[srliw++] = ch; 1402 if(!instring) 1403 { 1404 break; 1405 } 1406 } 1407 else 1408 { 1409 switch(ch) 1410 { 1411 case '\r': 1412 case '\n': 1413 case ' ': 1414 case '\t': 1415 case '\f': 1416 case '\v': 1417 if(srliw) 1418 break charloop; 1419 break; 1420 1421 case '[': 1422 case ']': 1423 case '{': 1424 case '}': 1425 case ':': 1426 case ',': 1427 if(srliw) 1428 { 1429 _jtNext = ch; 1430 break charloop; 1431 } 1432 _linebuf[srliw++] = ch; 1433 break charloop; 1434 1435 case '"': 1436 instring = true; 1437 _linebuf[srliw++] = ch; 1438 break; 1439 1440 default: 1441 _linebuf[srliw++] = ch; 1442 break; 1443 } 1444 } 1445 } 1446 if(!srliw) 1447 return isgood; 1448 line = _linebuf[0 .. srliw]; 1449 if(instring) 1450 { 1451 version(API_PICKY_JSON) 1452 throw new Exception("Unterminated string in JSON: " ~ line); 1453 return false; 1454 } 1455 return true; 1456 } 1457 1458 char[] nextJsonToken() 1459 { 1460 if(!streamReadJsonToken()) 1461 { 1462 return null; 1463 } 1464 //printf(" `%.*s`", line); 1465 return line; 1466 } 1467 1468 ApiInfo api; 1469 api = new ApiInfo; 1470 api.name = name; 1471 1472 LoadingApi lapi; 1473 lapi.api = api; 1474 1475 bool isjson = false; 1476 while(streamReadLine()) 1477 { 1478 string s = std.string.strip(line); 1479 if(s.length == 0) 1480 { 1481 continue; 1482 } 1483 if("[" == s) 1484 { 1485 isjson = true; 1486 } 1487 else if('[' == s[0]) 1488 { 1489 throw new Exception("Expected [ on its own line in JSON file for " ~ api.name ~ " API plugin"); 1490 } 1491 else 1492 { 1493 isjson = false; 1494 } 1495 break; 1496 } 1497 if(isjson) 1498 { 1499 lapi._jsonLoadMembers(&nextJsonToken); 1500 } 1501 else 1502 { 1503 if(line.length) 1504 lapi._dapiLoadLine(line); 1505 while(streamReadLine()) 1506 { 1507 lapi._dapiLoadLine(line); 1508 } 1509 } 1510 1511 if(addGlobal) 1512 addGlobalApiInfo(api); 1513 1514 return api; 1515 } 1516 1517 1518 private struct LoadingApi 1519 { 1325 1520 ApiInfo api; 1326 1521 void[] _mpool; // Current malloc memory pool. 1327 api = new ApiInfo; 1328 api.name = name; 1329 1522 //long remainbytes; 1523 uint curline; 1330 1524 1331 1525 // Allocates from the malloc memory pool. … … 1340 1534 if(n > MIN_POOL_SIZE) 1341 1535 mpn = round2power(n); 1342 // Determine how much extra to preallocate based on remaining bytes in stream.1343 1536 size_t pren; 1344 pren = round2power((stm.size() - stm.position()) / 8); 1537 //pren = round2power(remainbytes / 8); 1538 pren = round2power(1024 * 4); 1345 1539 if(pren > MAX_POOL_SIZE) 1346 1540 pren = MAX_POOL_SIZE; … … 1359 1553 void errmodpath() 1360 1554 { 1361 throw new Exception("Module path too long"); 1362 } 1555 throw new Exception("Fully-qualified name too long for API information"); 1556 } 1557 1363 1558 1364 1559 char[2048] parentbuf; 1365 char[] curmodule; // Refers to first (curmodule.length) bytes of parentbuf, and parentbuf[curmodule.length] is '.'. 1366 1367 char[] s, s2; 1368 int i; 1369 while(streamReadLine()) 1370 { 1371 switch(nextWord(line)) 1372 { 1373 case "module": 1560 char[] curscope; // Refers to first (curscope.length) bytes of parentbuf, and parentbuf[curscope.length] is '.'. 1561 // Note: curscope is different for JSON and DAPI; for DAPI it's the module. 1562 1563 1564 // Already ate '['. 1565 void _jsonLoadMembers(char[] delegate() nexttok) 1566 { 1567 // Note: string returned by nexttok is temporary. 1568 1569 char[] prevmodule = curscope; 1570 1571 char[] decodeString(char[] str, char[] buf) 1572 { 1573 if(str.length < 1 || '"' != str[0]) 1574 { 1575 return buf[0 .. 0]; 1576 } 1577 bool inescape = false; 1578 int ibuf = 0; 1579 strloop: 1580 for(int i = 1; i < str.length; i++) 1581 { 1582 if(inescape) 1374 1583 { 1375 s = nextWord(line); 1376 if(s.length) 1377 { 1378 if(s.length >= parentbuf.length - 128) 1379 errmodpath(); 1584 switch(str[i]) 1585 { 1586 case 'r': 1587 buf[ibuf++] = '\n'; 1588 break; 1589 case 'n': 1590 buf[ibuf++] = '\n'; 1591 break; 1592 case 't': 1593 buf[ibuf++] = '\t'; 1594 break; 1595 case 'v': 1596 buf[ibuf++] = '\v'; 1597 break; 1598 case 'f': 1599 buf[ibuf++] = '\f'; 1600 break; 1601 case '\\': 1602 case '\'': 1603 case '"': 1604 buf[ibuf++] = str[i]; 1605 break; 1606 default: 1607 //buf[ibuf++] = '\\'; 1608 buf[ibuf++] = str[i]; 1609 break; 1610 } 1611 inescape = false; 1612 } 1613 else 1614 { 1615 switch(str[i]) 1616 { 1617 case '"': 1618 break strloop; 1619 case '\\': 1620 inescape = true; 1621 break; 1622 default: 1623 buf[ibuf++] = str[i]; 1624 } 1625 } 1626 } 1627 return buf[0 .. ibuf]; 1628 } 1629 1630 void eatValues() 1631 { 1632 // Note: doesn't eat trailing ','. 1633 char[] s = nexttok(); 1634 int nbracks = 0; 1635 int nbraces = 0; 1636 if(s == "[") 1637 { 1638 nbracks++; 1639 } 1640 else if(s == "{") 1641 { 1642 nbraces++; 1643 } 1644 else 1645 { 1646 return; 1647 } 1648 assert(nbracks > 0 || nbraces > 0); 1649 for(;;) 1650 { 1651 s = nexttok(); 1652 if(!s.length) 1653 { 1654 break; 1655 } 1656 if(s == "]") 1657 { 1658 nbracks--; 1659 assert(nbracks >= 0); 1660 if(nbracks < 1 1661 && nbraces < 1) 1662 { 1663 break; 1664 } 1665 } 1666 else if(s == "}") 1667 { 1668 nbraces--; 1669 assert(nbraces >= 0); 1670 if(nbraces < 1 1671 && nbracks < 1) 1672 { 1673 break; 1674 } 1675 } 1676 else if(s == "[") 1677 { 1678 nbracks++; 1679 } 1680 else if(s == "{") 1681 { 1682 nbraces++; 1683 } 1684 } 1685 } 1686 1687 char[128] _namebuf; 1688 char[] name = null; // Note: might refer to local memory. 1689 char[128] _typebuf; 1690 char[] type = null; // Note: might refer to local memory. 1691 ApiType kind = ApiType.UNKNOWN; 1692 ApiEntry* curae = null; 1693 char[128] _baseitembuf; 1694 char[] baseitem = null; // Note: might refer to local memory. 1695 ApiFlags attribs = ApiFlags.NONE; 1696 char[128] _commentbuf; 1697 char[] comment = null; // Note: might refer to local memory. 1698 ushort line = 0; 1699 1700 void resetall() 1701 { 1702 name = null; 1703 type = null; 1704 kind = ApiType.UNKNOWN; 1705 baseitem = null; 1706 attribs = ApiFlags.NONE; 1707 comment = null; 1708 curae = null; 1709 curscope = prevmodule; 1710 line = 0; 1711 } 1712 1713 void setcurae() 1714 { 1715 if(curae !is null) 1716 { 1717 curae.type = kind; 1718 curae.flags = attribs; 1719 if(null == curae.name) 1720 { 1721 char[] name2 = cast(char[])mem(name.length)[0 .. name.length]; 1722 name2[] = name; 1723 curae.name = name2; 1724 } 1725 if(baseitem.length > 0) 1726 { 1727 if(curae.type == ApiType.CLASS) 1728 { 1729 ApiClass* ac = cast(ApiClass*)curae; 1730 if(null == ac.baseItemName) 1731 { 1732 ac.baseItemName = cast(char[])mem(baseitem.length)[0 .. baseitem.length]; 1733 ac.baseItemName[] = baseitem; 1734 } 1735 } 1736 } 1737 if(type.length > 0) 1738 { 1739 if(curae.type == ApiType.VAR) 1740 { 1741 ApiVar* av = cast(ApiVar*)curae; 1742 av.itemRValue = cast(char[])mem(type.length)[0 .. type.length]; 1743 av.itemRValue[] = type; 1744 } 1745 else if(curae.type == ApiType.FUNC) 1746 { 1747 char[] rvalue; 1748 char[] sparams; 1749 int i = 0; 1750 for(; i < type.length; i++) 1751 { 1752 if('(' == type[i]) 1753 { 1754 rvalue = type[0 .. i]; 1755 sparams = type[i .. $]; 1756 break; 1757 } 1758 if(type[i] == '!') 1759 { 1760 // Parse past template args. 1761 char[] targs = type[i + 1 .. $]; 1762 ParenItem pitem; 1763 if(!(ParamResult.DONE & nextParenItemStart(targs, pitem))) 1764 { 1765 ParenItem tpi; 1766 while(!(ParamResult.DONE & nextParenItemNext(targs, tpi))) 1767 { 1768 // Make sure to skip to ')'. 1769 } 1770 } 1771 if(targs.ptr > type.ptr + i + 1) 1772 { 1773 i = targs.ptr - type.ptr; 1774 assert(i >= 0); 1775 assert(i < type.length); 1776 i--; // Next loop iter will ++ again. 1777 } 1778 } 1779 } 1780 ApiFunc* af = cast(ApiFunc*)curae; 1781 af.itemRValue = cast(char[])mem(rvalue.length)[0 .. rvalue.length]; 1782 af.itemRValue[] = rvalue; 1783 { 1784 // Get params. 1785 ParenItem pitem; 1786 ParamResult pr; 1787 pr = nextParenItemStart(sparams, pitem); 1788 if(pr & ParamResult.VALID) 1789 { 1790 if(pitem.str.length <= ApiFuncArg.MAX_LENGTH) 1791 { 1792 ApiFuncArg* lastarg; 1793 lastarg = cast(ApiFuncArg*)mem(ApiFuncArg.sizeof + pitem.str.length); 1794 lastarg.next = null; 1795 lastarg.length = pitem.str.length; 1796 lastarg.data.ptr[0 .. pitem.str.length] = pitem.str; 1797 af.args = lastarg; // First. 1798 while(pr & ParamResult.MORE) 1799 { 1800 pr = nextParenItemNext(sparams, pitem); 1801 if(!(pr & ParamResult.VALID)) 1802 break; 1803 if(pitem.str.length > ApiFuncArg.MAX_LENGTH) 1804 { 1805 af.args = null; 1806 break; 1807 } 1808 ApiFuncArg* arg; 1809 arg = cast(ApiFuncArg*)mem(ApiFuncArg.sizeof + pitem.str.length); 1810 arg.next = null; 1811 arg.length = pitem.str.length; 1812 arg.data.ptr[0 .. pitem.str.length] = pitem.str; 1813 lastarg.next = arg; 1814 lastarg = arg; 1815 } 1816 } 1817 } 1818 } 1819 } 1820 } 1821 } 1822 } 1823 1824 fieldloop: 1825 for(;;) 1826 { 1827 char[] stok = nexttok(); 1828 switch(stok) 1829 { 1830 case "\"name\"": 1831 case "\"n\"": 1832 if(":" != nexttok()) 1833 { 1834 version(API_PICKY_JSON) 1835 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 1836 return; 1837 } 1838 { 1839 char[] s = nexttok(); 1840 if(s.length > _namebuf.length) 1841 { 1842 name = decodeString(s, new char[s.length]); 1843 } 1844 else 1845 { 1846 name = decodeString(s, _namebuf); 1847 } 1848 version(API_PICKY_JSON) 1849 { 1850 if(name.length < 1) 1851 { 1852 throw new Exception("name is empty in JSON; \"name\" : " ~ s); 1853 } 1854 } 1855 } 1856 break; 1857 case "\"type\"": 1858 case "\"t\"": 1859 if(":" != nexttok()) 1860 { 1861 version(API_PICKY_JSON) 1862 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 1863 return; 1864 } 1865 { 1866 char[] s = nexttok(); 1867 if(s.length > _typebuf.length) 1868 { 1869 type = decodeString(s, new char[s.length]); 1870 } 1871 else 1872 { 1873 type = decodeString(s, _typebuf); 1874 } 1875 } 1876 break; 1877 case "\"attributes\"": 1878 case "\"a\"": 1879 if(":" != nexttok()) 1880 { 1881 version(API_PICKY_JSON) 1882 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 1883 return; 1884 } 1885 { 1886 //eatValues(); 1887 if("[" != nexttok()) 1888 { 1889 throw new Exception("Expected [ for \"attributes\" in JSON"); 1890 return; 1891 } 1380 1892 1381 curmodule = parentbuf[0 .. s.length]; 1382 curmodule[] = s; 1383 parentbuf[curmodule.length] = '.'; 1893 attribloop: 1894 for(;;) 1895 { 1896 char[] s = nexttok(); 1897 switch(s) 1898 { 1899 case "\"protected\"": 1900 attribs |= ApiFlags.PROTECTED; 1901 break; 1902 case "\"const\"": 1903 attribs |= ApiFlags.CONST; 1904 break; 1905 case "\"static\"": 1906 attribs |= ApiFlags.STATIC; 1907 break; 1908 case "\"final\"": 1909 attribs |= ApiFlags.FINAL; 1910 break; 1911 case "\"auto\"": 1912 attribs |= ApiFlags.AUTO; 1913 break; 1914 case "\"deprecated\"": 1915 attribs |= ApiFlags.DEPRECATED; 1916 break; 1917 case "\"package\"": 1918 attribs |= ApiFlags.PACKAGE; 1919 break; 1920 case "\"private\"": 1921 attribs |= ApiFlags.PRIVATE; 1922 break; 1923 case ",": 1924 break; 1925 case "": 1926 case "]": 1927 break attribloop; 1928 default: 1929 break; 1930 } 1931 } 1932 } 1933 break; 1934 case "\"base\"": 1935 case "\"b\"": 1936 // Base class. 1937 if(":" != nexttok()) 1938 { 1939 version(API_PICKY_JSON) 1940 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 1941 return; 1942 } 1943 { 1944 char[] s = nexttok(); 1945 if(s.length > _baseitembuf.length) 1946 { 1947 baseitem = decodeString(s, new char[s.length]); 1948 } 1949 else 1950 { 1951 baseitem = decodeString(s, _baseitembuf); 1952 } 1953 } 1954 break; 1955 case "\"line\"": 1956 case "\"l\"": 1957 if(":" != nexttok()) 1958 { 1959 version(API_PICKY_JSON) 1960 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 1961 return; 1962 } 1963 { 1964 char[] sline = nexttok(); 1965 /+try 1966 { 1967 line = std.conv.toUshort(sline); 1968 } 1969 catch 1970 { 1971 }+/ 1972 } 1973 break; 1974 case "\"kind\"": 1975 case "\"k\"": 1976 if(":" != nexttok()) 1977 { 1978 version(API_PICKY_JSON) 1979 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 1980 return; 1981 } 1982 if(name.length < 1) 1983 { 1984 version(API_PICKY_JSON) 1985 throw new Exception("name must be specified before kind in JSON"); 1986 nexttok(); 1987 break; 1988 } 1989 switch(nexttok()) 1990 { 1991 case "\"module\"": 1992 case "\"m\"": 1993 kind = ApiType.MODULE; 1994 { 1995 if(name.length >= parentbuf.length - 128) 1996 errmodpath(); 1997 1998 curscope = parentbuf[0 .. name.length]; 1999 curscope[] = name; 2000 parentbuf[curscope.length] = '.'; 2001 2002 ApiModule* ae = cast(ApiModule*)mem(ApiModule.sizeof); 2003 *ae = ApiModule.init; 2004 curae = ae.entry; 2005 setcurae(); 2006 int i = std.string.rfind(ae.entry.name, '.'); 2007 string pkg = ""; 2008 if(i != -1) 2009 { 2010 pkg = ae.entry.name[0 .. i]; // Packages. 2011 ae.entry.name = ae.entry.name[i + 1 .. $]; 2012 //ae.entry.parent = pkg; 2013 } 2014 api.addApiModule(pkg, ae, { return cast(ApiPackage*)mem(ApiPackage.sizeof); }); 2015 } 2016 break; 2017 case "\"alias\"": 2018 case "\"a\"": 2019 kind = ApiType.UNKNOWN; // Hmm. 2020 break; 2021 case "\"interface\"": 2022 case "\"i\"": 2023 kind = ApiType.INTERFACE; 2024 { 2025 if(!curscope.length) 2026 break; 2027 assert('.' == parentbuf[curscope.length]); 2028 2029 ApiInterface* ai; 2030 ai = cast(ApiInterface*)mem(ApiInterface.sizeof); 2031 *ai = ApiInterface.init; 2032 curae = ai.entry; 2033 setcurae(); 2034 char[] myscope = curscope; 2035 { 2036 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2037 errmodpath(); 2038 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2039 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2040 parentbuf[curscope.length] = '.'; 2041 } 2042 //("Adding interface '" ~ ai.entry.name ~ "' to scope '" ~ myscope ~ "'"); 2043 api.addApiInterface(myscope, ai); 2044 } 2045 break; 2046 case "\"union\"": 2047 case "\"u\"": 2048 kind = ApiType.UNION; 2049 { 2050 if(!curscope.length) 2051 break; 2052 assert('.' == parentbuf[curscope.length]); 2053 2054 ApiUnion* au; 2055 au = cast(ApiUnion*)mem(ApiUnion.sizeof); 2056 *au = ApiUnion.init; 2057 curae = au.entry; 2058 setcurae(); 2059 char[] myscope = curscope; 2060 { 2061 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2062 errmodpath(); 2063 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2064 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2065 parentbuf[curscope.length] = '.'; 2066 } 2067 api.addApiUnion(myscope, au); 2068 } 2069 break; 2070 case "\"struct\"": 2071 case "\"s\"": 2072 kind = ApiType.STRUCT; 2073 { 2074 if(!curscope.length) 2075 break; 2076 assert('.' == parentbuf[curscope.length]); 2077 2078 ApiStruct* as; 2079 as = cast(ApiStruct*)mem(ApiStruct.sizeof); 2080 *as = ApiStruct.init; 2081 curae = as.entry; 2082 setcurae(); 2083 char[] myscope = curscope; 2084 { 2085 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2086 errmodpath(); 2087 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2088 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2089 parentbuf[curscope.length] = '.'; 2090 } 2091 api.addApiStruct(myscope, as); 2092 } 2093 break; 2094 case "\"class\"": 2095 case "\"c\"": 2096 kind = ApiType.CLASS; 2097 { 2098 if(!curscope.length) 2099 break; 2100 assert('.' == parentbuf[curscope.length]); 2101 2102 ApiClass* ac; 2103 ac = cast(ApiClass*)mem(ApiClass.sizeof); 2104 *ac = ApiClass.init; 2105 curae = ac.entry; 2106 setcurae(); 2107 char[] myscope = curscope; 2108 { 2109 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2110 errmodpath(); 2111 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2112 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2113 parentbuf[curscope.length] = '.'; 2114 } 2115 api.addApiClass(myscope, ac); 2116 } 2117 break; 2118 case "\"constructor\"": 2119 kind = ApiType.FUNC; // Constructor->function. 2120 case "\"destructor\"": 2121 kind = ApiType.FUNC; // Destructor->function. 2122 case "\"function\"": 2123 case "\"f\"": 2124 kind = ApiType.FUNC; 2125 { 2126 if(!curscope.length) 2127 break; 2128 assert('.' == parentbuf[curscope.length]); 2129 2130 ApiFunc* af; 2131 af = cast(ApiFunc*)mem(ApiFunc.sizeof); 2132 *af = ApiFunc.init; 2133 curae = af.entry; 2134 setcurae(); 2135 char[] myscope = curscope; 2136 { 2137 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2138 errmodpath(); 2139 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2140 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2141 parentbuf[curscope.length] = '.'; 2142 } 2143 api.addApiFunc(myscope, af); 2144 } 2145 break; 2146 case "\"variable\"": 2147 case "\"v\"": 2148 kind = ApiType.VAR; 2149 { 2150 if(!curscope.length) 2151 break; 2152 assert('.' == parentbuf[curscope.length]); 2153 2154 ApiVar* av; 2155 av = cast(ApiVar*)mem(ApiVar.sizeof); 2156 *av = ApiVar.init; 2157 curae = av.entry; 2158 setcurae(); 2159 char[] myscope = curscope; 2160 { 2161 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2162 errmodpath(); 2163 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2164 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2165 parentbuf[curscope.length] = '.'; 2166 } 2167 api.addApiVar(myscope, av); 2168 } 2169 break; 2170 case "\"enum\"": 2171 case "\"e\"": 2172 kind = ApiType.ENUM; 2173 { 2174 if(!curscope.length) 2175 break; 2176 assert('.' == parentbuf[curscope.length]); 2177 2178 ApiEnum* ae; 2179 ae = cast(ApiEnum*)mem(ApiEnum.sizeof); 2180 *ae = ApiEnum.init; 2181 curae = ae.entry; 2182 setcurae(); 2183 char[] myscope = curscope; 2184 { 2185 if(curscope.length + 1 + name.length + 1 > parentbuf.length) 2186 errmodpath(); 2187 parentbuf[curscope.length + 1 .. curscope.length + 1 + name.length] = name; 2188 curscope = parentbuf[0 .. curscope.length + 1 + name.length]; // Scope for members. 2189 parentbuf[curscope.length] = '.'; 2190 } 2191 api.addApiEnum(myscope, ae); 2192 } 2193 break; 2194 case "\"enum member\"": 2195 case "\"ev\"": 2196 kind = ApiType.ENUMVALUE; 2197 { 2198 if(!curscope.length) 2199 break; 2200 assert('.' == parentbuf[curscope.length]); 2201 2202 ApiEnumValue* ae; 2203 ae = cast(ApiEnumValue*)mem(ApiEnumValue.sizeof); 2204 *ae = ApiEnumValue.init; 2205 curae = ae.entry; 2206 setcurae(); 2207 char[] myscope = curscope; 2208 api.addApiEnumValue(myscope, ae); 2209 } 2210 break; 2211 default: ; 2212 } 2213 break; 2214 case "\"members\"": 2215 case "\"m\"": 2216 if(":" != nexttok()) 2217 { 2218 version(API_PICKY_JSON) 2219 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 2220 return; 2221 } 2222 if("[" != nexttok()) 2223 { 2224 throw new Exception("Expected [ for \"members\" in JSON"); 2225 return; 2226 } 2227 _jsonLoadMembers(nexttok); 2228 curscope = prevmodule; 2229 break; 2230 case "\"comment\"": 2231 case "\"c\"": 2232 if(":" != nexttok()) 2233 { 2234 version(API_PICKY_JSON) 2235 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 2236 return; 2237 } 2238 { 2239 char[] s = nexttok(); 2240 if(s.length > _commentbuf.length) 2241 { 2242 comment = decodeString(s, new char[s.length]); 2243 } 2244 else 2245 { 2246 comment = decodeString(s, _commentbuf); 2247 } 2248 } 2249 break; 2250 case "]": 2251 break fieldloop; 2252 case ",": 2253 break; 2254 case "}": 2255 // Save current member. 2256 setcurae(); 2257 if(curae != null) 2258 { 2259 if(comment is null) 2260 { 2261 //curae.flags |= ApiFlags.PRIVATE; 2262 curae.flags |= ApiFlags.UNDOCUMENTED; 2263 } 2264 else if(curae.type == ApiType.FUNC) 2265 { 2266 if(-1 != std.string.find(comment, "@getter")) 2267 { 2268 ApiFunc* af = cast(ApiFunc*)curae; 2269 af.functype = ApiFunc.GETTER; 2270 } 2271 else if(-1 != std.string.find(comment, "@setter")) 2272 { 2273 ApiFunc* af = cast(ApiFunc*)curae; 2274 af.functype = ApiFunc.SETTER; 2275 } 2276 } 2277 } 2278 // Reset for new member. 2279 resetall(); 2280 break; 2281 case "{": 2282 // New member. 2283 break; 2284 default: 2285 if(stok.length > 0 && '"' == stok[0]) 2286 { 2287 if(":" != nexttok()) 2288 { 2289 version(API_PICKY_JSON) 2290 throw new Exception("Expected : in JSON (" ~ stok ~ ")"); 2291 return; 2292 } 2293 eatValues(); 2294 } 2295 else 2296 { 2297 version(API_PICKY_JSON) 2298 { 2299 char[] nstok = nexttok(); 2300 if(nstok.length) 2301 throw new Exception("JSON error, unexpected " ~ stok ~ " " ~ nstok); 2302 } 2303 break fieldloop; 2304 } 2305 } 2306 } 2307 } 2308 2309 2310 void _dapiLoadLine(char[] line) 2311 { 2312 char[] s, s2; 2313 int i; 2314 { 2315 switch(nextWord(line)) 2316 { 2317 case "module": 2318 { 2319 s = nextWord(line); 2320 if(s.length) 2321 { 2322 if(s.length >= parentbuf.length - 128) 2323 errmodpath(); 2324 2325 curscope = parentbuf[0 .. s.length]; 2326 curscope[] = s; 2327 parentbuf[curscope.length] = '.'; 2328 2329 s2 = cast(char[])mem(s.length)[0 .. s.length]; 2330 s2[] = s; 2331 ApiModule* ae; 2332 ae = cast(ApiModule*)mem(ApiModule.sizeof); 2333 *ae = ApiModule.init; 2334 ae.entry.type = ApiType.MODULE; 2335 ae.entry.name = s2; 2336 s = null; 2337 i = std.string.rfind(s2, '.'); 2338 if(i != -1) 2339 { 2340 s = s2[0 .. i]; // Packages. 2341 ae.entry.name = s2[i + 1 .. s2.length]; 2342 //ae.entry.parent = s; 2343 } 2344 api.addApiModule(s, ae, { return cast(ApiPackage*)mem(ApiPackage.sizeof); }); 2345 } 2346 } 2347 break; 2348 2349 case "class": 2350 { 2351 if(!curscope.length) 2352 break; 2353 assert('.' == parentbuf[curscope.length]); 1384 2354 1385 s2 = cast(char[])mem(s.length)[0 .. s.length]; 1386 s2[] = s; 1387 ApiModule* ae; 1388 ae = cast(ApiModule*)mem(ApiModule.sizeof); 1389 *ae = ApiModule.init; 1390 ae.entry.type = ApiType.MODULE; 1391 ae.entry.name = s2; 1392 s = null; 1393 i = std.string.rfind(s2, '.'); 1394 if(i != -1) 1395 { 1396 s = s2[0 .. i]; // Packages. 1397 ae.entry.name = s2[i + 1 .. s2.length]; 1398 //ae.entry.parent = s; 1399 } 1400 api.addApiModule(s, ae, { return cast(ApiPackage*)mem(ApiPackage.sizeof); }); 1401 } 1402 } 1403 break; 1404 1405 case "class": 1406 { 1407 if(!curmodule.length) 1408 break; 1409 assert('.' == parentbuf[curmodule.length]); 1410 1411 char[] flagstr; 1412 flagstr = nextWord(line); 1413 char[] path; 1414 path = nextWord(line); 1415 char[] ename; 1416 ename = nextWord(line); 1417 char[] basename; 1418 basename = nextWord(line); 1419 ApiClass* ac; 1420 ac = cast(ApiClass*)mem(ApiClass.sizeof); 1421 *ac = ApiClass.init; 1422 ac.entry.type = ApiType.CLASS; 1423 ac.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1424 ac.name[] = ename; 1425 s2 = curmodule; 1426 if("-" != path && "." != path) 1427 { 1428 //ac.parent = path; 1429 if(curmodule.length + 1 + path.length > parentbuf.length) 1430 errmodpath(); 1431 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1432 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1433 } 1434 if(basename.length && "-" != basename) 1435 { 1436 //ac.baseItemName = basename; 1437 ac.baseItemName = cast(char[])mem(basename.length)[0 .. basename.length]; 1438 ac.baseItemName[0 .. basename.length] = basename; 1439 } 1440 ac.flags = parseDApiFlags(flagstr); 1441 api.addApiClass(s2, ac); 1442 } 1443 break; 1444 1445 case "struct": 1446 { 1447 if(!curmodule.length) 1448 break; 1449 assert('.' == parentbuf[curmodule.length]); 1450 1451 char[] flagstr; 1452 flagstr = nextWord(line); 1453 char[] path; 1454 path = nextWord(line); 1455 char[] ename; 1456 ename = nextWord(line); 1457 ApiStruct* as; 1458 as = cast(ApiStruct*)mem(ApiStruct.sizeof); 1459 *as = ApiStruct.init; 1460 as.entry.type = ApiType.STRUCT; 1461 as.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1462 as.name[] = ename; 1463 s2 = curmodule; 1464 if("-" != path && "." != path) 1465 { 1466 //as.parent = path; 1467 if(curmodule.length + 1 + path.length > parentbuf.length) 1468 errmodpath(); 1469 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1470 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1471 } 1472 as.flags = parseDApiFlags(flagstr); 1473 api.addApiStruct(s2, as); 1474 } 1475 break; 1476 1477 case "interface": 1478 { 1479 if(!curmodule.length) 1480 break; 1481 assert('.' == parentbuf[curmodule.length]); 1482 1483 char[] flagstr; 1484 flagstr = nextWord(line); 1485 char[] path; 1486 path = nextWord(line); 1487 char[] ename; 1488 ename = nextWord(line); 1489 ApiInterface* ai; 1490 ai = cast(ApiInterface*)mem(ApiInterface.sizeof); 1491 *ai = ApiInterface.init; 1492 ai.entry.type = ApiType.INTERFACE; 1493 ai.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1494 ai.name[] = ename; 1495 s2 = curmodule; 1496 if("-" != path && "." != path) 1497 { 1498 //ai.parent = path; 1499 if(curmodule.length + 1 + path.length > parentbuf.length) 1500 errmodpath(); 1501 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1502 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1503 } 1504 ai.flags = parseDApiFlags(flagstr); 1505 api.addApiInterface(s2, ai); 1506 } 1507 break; 1508 1509 case "union": 1510 { 1511 if(!curmodule.length) 1512 break; 1513 assert('.' == parentbuf[curmodule.length]); 1514 1515 char[] flagstr; 1516 flagstr = nextWord(line); 1517 char[] path; 1518 path = nextWord(line); 1519 char[] ename; 1520 ename = nextWord(line); 1521 ApiUnion* au; 1522 au = cast(ApiUnion*)mem(ApiUnion.sizeof); 1523 *au = ApiUnion.init; 1524 au.entry.type = ApiType.UNION; 1525 au.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1526 au.name[] = ename; 1527 s2 = curmodule; 1528 if("-" != path && "." != path) 1529 { 1530 //au.parent = path; 1531 if(curmodule.length + 1 + path.length > parentbuf.length) 1532 errmodpath(); 1533 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1534 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1535 } 1536 au.flags = parseDApiFlags(flagstr); 1537 api.addApiUnion(s2, au); 1538 } 1539 break; 1540 1541 case "getter": 1542 i = ApiFunc.GETTER; 1543 goto in_func; 1544 case "setter": 1545 i = ApiFunc.SETTER; 1546 goto in_func; 1547 case "func": 1548 i = ApiFunc.FUNC; 1549 in_func: 1550 { 1551 if(!curmodule.length) 1552 break; 1553 assert('.' == parentbuf[curmodule.length]); 1554 1555 char[] flagstr; 1556 flagstr = nextWord(line); 1557 char[] path; 1558 path = nextWord(line); 1559 char[] ename; 1560 ename = nextWord(line); 1561 ParenItem pitem; 1562 if(!(ParamResult.DONE & nextParenItemStart(line, pitem))) 1563 { 1564 ParenItem tpi; 1565 while(!(ParamResult.DONE & nextParenItemNext(line, tpi))) 1566 { 1567 // Make sure to skip to ')'. 1568 } 1569 } 1570 ApiFunc* af; 1571 af = cast(ApiFunc*)mem(ApiFunc.sizeof); 1572 *af = ApiFunc.init; 1573 af.type = ApiType.FUNC; 1574 af.functype = i; 1575 af.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1576 af.name[] = ename; 1577 s2 = curmodule; 1578 if("-" != path && "." != path) 1579 { 1580 //af.parent = path; 1581 if(curmodule.length + 1 + path.length > parentbuf.length) 1582 errmodpath(); 1583 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1584 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1585 } 1586 af.flags = parseDApiFlags(flagstr); 1587 //af.itemRValue = pitem.str.dup; 1588 af.itemRValue = cast(char[])mem(pitem.str.length)[0 .. pitem.str.length]; 1589 af.itemRValue[] = pitem.str; 1590 // Get params. 1591 ParamResult pr; 1592 pr = nextParenItemStart(line, pitem); 1593 if(pr & ParamResult.VALID) 1594 { 1595 if(pitem.str.length <= ApiFuncArg.length.max) 1596 { 1597 ApiFuncArg* lastarg; 1598 lastarg = cast(ApiFuncArg*)mem(ApiFuncArg.sizeof + pitem.str.length); 1599 lastarg.next = null; 1600 lastarg.length = pitem.str.length; 1601 lastarg.data.ptr[0 .. pitem.str.length] = pitem.str; 1602 af.args = lastarg; // First. 1603 while(pr & ParamResult.MORE) 2355 char[] flagstr; 2356 flagstr = nextWord(line); 2357 char[] path; 2358 path = nextWord(line); 2359 char[] ename; 2360 ename = nextWord(line); 2361 char[] basename; 2362 basename = nextWord(line); 2363 ApiClass* ac; 2364 ac = cast(ApiClass*)mem(ApiClass.sizeof); 2365 *ac = ApiClass.init; 2366 ac.entry.type = ApiType.CLASS; 2367 ac.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2368 ac.name[] = ename; 2369 s2 = curscope; 2370 if("-" != path && "." != path) 2371 { 2372 //ac.parent = path; 2373 if(curscope.length + 1 + path.length > parentbuf.length) 2374 errmodpath(); 2375 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2376 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2377 } 2378 if(basename.length && "-" != basename) 2379 { 2380 //ac.baseItemName = basename; 2381 ac.baseItemName = cast(char[])mem(basename.length)[0 .. basename.length]; 2382 ac.baseItemName[0 .. basename.length] = basename; 2383 } 2384 ac.flags = parseDApiFlags(flagstr); 2385 api.addApiClass(s2, ac); 2386 } 2387 break; 2388 2389 case "struct": 2390 { 2391 if(!curscope.length) 2392 break; 2393 assert('.' == parentbuf[curscope.length]); 2394 2395 char[] flagstr; 2396 flagstr = nextWord(line); 2397 char[] path; 2398 path = nextWord(line); 2399 char[] ename; 2400 ename = nextWord(line); 2401 ApiStruct* as; 2402 as = cast(ApiStruct*)mem(ApiStruct.sizeof); 2403 *as = ApiStruct.init; 2404 as.entry.type = ApiType.STRUCT; 2405 as.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2406 as.name[] = ename; 2407 s2 = curscope; 2408 if("-" != path && "." != path) 2409 { 2410 //as.parent = path; 2411 if(curscope.length + 1 + path.length > parentbuf.length) 2412 errmodpath(); 2413 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2414 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2415 } 2416 as.flags = parseDApiFlags(flagstr); 2417 api.addApiStruct(s2, as); 2418 } 2419 break; 2420 2421 case "interface": 2422 { 2423 if(!curscope.length) 2424 break; 2425 assert('.' == parentbuf[curscope.length]); 2426 2427 char[] flagstr; 2428 flagstr = nextWord(line); 2429 char[] path; 2430 path = nextWord(line); 2431 char[] ename; 2432 ename = nextWord(line); 2433 ApiInterface* ai; 2434 ai = cast(ApiInterface*)mem(ApiInterface.sizeof); 2435 *ai = ApiInterface.init; 2436 ai.entry.type = ApiType.INTERFACE; 2437 ai.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2438 ai.name[] = ename; 2439 s2 = curscope; 2440 if("-" != path && "." != path) 2441 { 2442 //ai.parent = path; 2443 if(curscope.length + 1 + path.length > parentbuf.length) 2444 errmodpath(); 2445 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2446 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2447 } 2448 ai.flags = parseDApiFlags(flagstr); 2449 api.addApiInterface(s2, ai); 2450 } 2451 break; 2452 2453 case "union": 2454 { 2455 if(!curscope.length) 2456 break; 2457 assert('.' == parentbuf[curscope.length]); 2458 2459 char[] flagstr; 2460 flagstr = nextWord(line); 2461 char[] path; 2462 path = nextWord(line); 2463 char[] ename; 2464 ename = nextWord(line); 2465 ApiUnion* au; 2466 au = cast(ApiUnion*)mem(ApiUnion.sizeof); 2467 *au = ApiUnion.init; 2468 au.entry.type = ApiType.UNION; 2469 au.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2470 au.name[] = ename; 2471 s2 = curscope; 2472 if("-" != path && "." != path) 2473 { 2474 //au.parent = path; 2475 if(curscope.length + 1 + path.length > parentbuf.length) 2476 errmodpath(); 2477 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2478 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2479 } 2480 au.flags = parseDApiFlags(flagstr); 2481 api.addApiUnion(s2, au); 2482 } 2483 break; 2484 2485 case "getter": 2486 i = ApiFunc.GETTER; 2487 goto in_func; 2488 case "setter": 2489 i = ApiFunc.SETTER; 2490 goto in_func; 2491 case "func": 2492 i = ApiFunc.FUNC; 2493 in_func: 2494 { 2495 if(!curscope.length) 2496 break; 2497 assert('.' == parentbuf[curscope.length]); 2498 2499 char[] flagstr; 2500 flagstr = nextWord(line); 2501 char[] path; 2502 path = nextWord(line); 2503 char[] ename; 2504 ename = nextWord(line); 2505 ParenItem pitem; 2506 if(!(ParamResult.DONE & nextParenItemStart(line, pitem))) 2507 { 2508 ParenItem tpi; 2509 while(!(ParamResult.DONE & nextParenItemNext(line, tpi))) 1604 2510 { 1605 pr = nextParenItemNext(line, pitem); 1606 if(!(pr & ParamResult.VALID)) 1607 break; 1608 if(pitem.str.length > ApiFuncArg.length.max) 2511 // Make sure to skip to ')'. 2512 } 2513 } 2514 ApiFunc* af; 2515 af = cast(ApiFunc*)mem(ApiFunc.sizeof); 2516 *af = ApiFunc.init; 2517 af.type = ApiType.FUNC; 2518 af.functype = i; 2519 af.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2520 af.name[] = ename; 2521 s2 = curscope; 2522 if("-" != path && "." != path) 2523 { 2524 //af.parent = path; 2525 if(curscope.length + 1 + path.length > parentbuf.length) 2526 errmodpath(); 2527 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2528 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2529 } 2530 af.flags = parseDApiFlags(flagstr); 2531 //af.itemRValue = pitem.str.dup; 2532 af.itemRValue = cast(char[])mem(pitem.str.length)[0 .. pitem.str.length]; 2533 af.itemRValue[] = pitem.str; 2534 // Get params. 2535 ParamResult pr; 2536 pr = nextParenItemStart(line, pitem); 2537 if(pr & ParamResult.VALID) 2538 { 2539 if(pitem.str.length <= ApiFuncArg.MAX_LENGTH) 2540 { 2541 ApiFuncArg* lastarg; 2542 lastarg = cast(ApiFuncArg*)mem(ApiFuncArg.sizeof + pitem.str.length); 2543 lastarg.next = null; 2544 lastarg.length = pitem.str.length; 2545 lastarg.data.ptr[0 .. pitem.str.length] = pitem.str; 2546 af.args = lastarg; // First. 2547 while(pr & ParamResult.MORE) 1609 2548 { 1610 af.args = null; 1611 break; 2549 pr = nextParenItemNext(line, pitem); 2550 if(!(pr & ParamResult.VALID)) 2551 break; 2552 if(pitem.str.length > ApiFuncArg.MAX_LENGTH) 2553 { 2554 af.args = null; 2555 break; 2556 } 2557 ApiFuncArg* arg; 2558 arg = cast(ApiFuncArg*)mem(ApiFuncArg.sizeof + pitem.str.length); 2559 arg.next = null; 2560 arg.length = pitem.str.length; 2561 arg.data.ptr[0 .. pitem.str.length] = pitem.str; 2562 lastarg.next = arg; 2563 lastarg = arg; 1612 2564 } 1613 ApiFuncArg* arg;1614 arg = cast(ApiFuncArg*)mem(ApiFuncArg.sizeof + pitem.str.length);1615 arg.next = null;1616 arg.length = pitem.str.length;1617 arg.data.ptr[0 .. pitem.str.length] = pitem.str;1618 lastarg.next = arg;1619 lastarg = arg;1620 2565 } 1621 2566 } 1622 } 1623 api.addApiFunc(s2, af); 1624 } 1625 break; 1626 1627 case "var": 1628 { 1629 if(!curmodule.length) 1630 break; 1631 assert('.' == parentbuf[curmodule.length]); 1632 1633 char[] flagstr; 1634 flagstr = nextWord(line); 1635 char[] path; 1636 path = nextWord(line); 1637 char[] ename; 1638 ename = nextWord(line); 1639 ParenItem pitem; 1640 nextParenItemStart(line, pitem); 1641 ApiVar* av; 1642 av = cast(ApiVar*)mem(ApiVar.sizeof); 1643 *av = ApiVar.init; 1644 av.type = ApiType.VAR; 1645 av.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1646 av.name[] = ename; 1647 s2 = curmodule; 1648 if("-" != path && "." != path) 1649 { 1650 //av.parent = path; 1651 if(curmodule.length + 1 + path.length > parentbuf.length) 1652 errmodpath(); 1653 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1654 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1655 } 1656 av.flags = parseDApiFlags(flagstr); 1657 //av.itemRValue = pitem.str.dup; 1658 av.itemRValue = cast(char[])mem(pitem.str.length)[0 .. pitem.str.length]; 1659 av.itemRValue[] = pitem.str; 1660 api.addApiVar(s2, av); 1661 } 1662 break; 1663 1664 case "enum": 1665 { 1666 if(!curmodule.length) 1667 break; 1668 assert('.' == parentbuf[curmodule.length]); 1669 1670 char[] flagstr; 1671 flagstr = nextWord(line); 1672 char[] path; 1673 path = nextWord(line); 1674 char[] ename; 1675 ename = nextWord(line); 1676 ApiEnum* ae; 1677 ae = cast(ApiEnum*)mem(ApiEnum.sizeof); 1678 *ae = ApiEnum.init; 1679 ae.type = ApiType.ENUM; 1680 ae.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1681 ae.name[] = ename; 1682 s2 = curmodule; 1683 if("-" != path && "." != path) 1684 { 1685 //ae.parent = path; 1686 if(curmodule.length + 1 + path.length > parentbuf.length) 1687 errmodpath(); 1688 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1689 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1690 } 1691 ae.flags = parseDApiFlags(flagstr); 1692 api.addApiEnum(s2, ae); 1693 } 1694 break; 1695 1696 case "enumval": 1697 { 1698 if(!curmodule.length) 1699 break; 1700 assert('.' == parentbuf[curmodule.length]); 1701 1702 char[] flagstr; 1703 flagstr = nextWord(line); 1704 char[] path; 1705 path = nextWord(line); 1706 char[] ename; 1707 ename = nextWord(line); 1708 ApiEnumValue* ae; 1709 ae = cast(ApiEnumValue*)mem(ApiEnumValue.sizeof); 1710 *ae = ApiEnumValue.init; 1711 ae.type = ApiType.ENUMVALUE; 1712 ae.name = cast(char[])mem(ename.length)[0 .. ename.length]; 1713 ae.name[] = ename; 1714 s2 = curmodule; 1715 if("-" != path && "." != path) 1716 { 1717 //ae.parent = path; 1718 if(curmodule.length + 1 + path.length > parentbuf.length) 1719 errmodpath(); 1720 parentbuf[curmodule.length + 1 .. curmodule.length + 1 + path.length] = path; 1721 s2 = parentbuf[0 .. curmodule.length + 1 + path.length]; 1722 } 1723 ae.flags = parseDApiFlags(flagstr); 1724 api.addApiEnumValue(s2, ae); 1725 } 1726 break; 1727 1728 case "import": 1729 { 1730 if(!curmodule.length) 1731 break; 1732 assert('.' == parentbuf[curmodule.length]); // ? 1733 1734 char[] flagstr; 1735 flagstr = nextWord(line); 1736 char[] impmod; 1737 impmod = nextWord(line); 1738 ApiImport* ai; 1739 ai = cast(ApiImport*)mem(ApiImport.sizeof); 1740 *ai = ApiImport.init; 1741 ai.type = ApiType.IMPORT; 1742 ai.name = ""; // ... it doesn't have a name unless it imported-as or something. Guess that's a to-do. The = name could be the next word. 1743 ai.importmodule = cast(char[])mem(impmod.length)[0 .. impmod.length]; 1744 s2 = curmodule; 1745 ai.flags = parseDApiFlags(flagstr); 1746 api.addApiImport(s2, ai); 1747 } 1748 break; 1749 1750 default: ; 1751 } 1752 } 1753 1754 if(addGlobal) 1755 addGlobalApiInfo(api); 1756 return api; 2567 api.addApiFunc(s2, af); 2568 } 2569 break; 2570 2571 case "var": 2572 { 2573 if(!curscope.length) 2574 break; 2575 assert('.' == parentbuf[curscope.length]); 2576 2577 char[] flagstr; 2578 flagstr = nextWord(line); 2579 char[] path; 2580 path = nextWord(line); 2581 char[] ename; 2582 ename = nextWord(line); 2583 ParenItem pitem; 2584 nextParenItemStart(line, pitem); 2585 ApiVar* av; 2586 av = cast(ApiVar*)mem(ApiVar.sizeof); 2587 *av = ApiVar.init; 2588 av.type = ApiType.VAR; 2589 av.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2590 av.name[] = ename; 2591 s2 = curscope; 2592 if("-" != path && "." != path) 2593 { 2594 //av.parent = path; 2595 if(curscope.length + 1 + path.length > parentbuf.length) 2596 errmodpath(); 2597 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2598 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2599 } 2600 av.flags = parseDApiFlags(flagstr); 2601 //av.itemRValue = pitem.str.dup; 2602 av.itemRValue = cast(char[])mem(pitem.str.length)[0 .. pitem.str.length]; 2603 av.itemRValue[] = pitem.str; 2604 api.addApiVar(s2, av); 2605 } 2606 break; 2607 2608 case "enum": 2609 { 2610 if(!curscope.length) 2611 break; 2612 assert('.' == parentbuf[curscope.length]); 2613 2614 char[] flagstr; 2615 flagstr = nextWord(line); 2616 char[] path; 2617 path = nextWord(line); 2618 char[] ename; 2619 ename = nextWord(line); 2620 ApiEnum* ae; 2621 ae = cast(ApiEnum*)mem(ApiEnum.sizeof); 2622 *ae = ApiEnum.init; 2623 ae.type = ApiType.ENUM; 2624 ae.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2625 ae.name[] = ename; 2626 s2 = curscope; 2627 if("-" != path && "." != path) 2628 { 2629 //ae.parent = path; 2630 if(curscope.length + 1 + path.length > parentbuf.length) 2631 errmodpath(); 2632 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2633 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2634 } 2635 ae.flags = parseDApiFlags(flagstr); 2636 api.addApiEnum(s2, ae); 2637 } 2638 break; 2639 2640 case "enumval": 2641 { 2642 if(!curscope.length) 2643 break; 2644 assert('.' == parentbuf[curscope.length]); 2645 2646 char[] flagstr; 2647 flagstr = nextWord(line); 2648 char[] path; 2649 path = nextWord(line); 2650 char[] ename; 2651 ename = nextWord(line); 2652 ApiEnumValue* ae; 2653 ae = cast(ApiEnumValue*)mem(ApiEnumValue.sizeof); 2654 *ae = ApiEnumValue.init; 2655 ae.type = ApiType.ENUMVALUE; 2656 ae.name = cast(char[])mem(ename.length)[0 .. ename.length]; 2657 ae.name[] = ename; 2658 s2 = curscope; 2659 if("-" != path && "." != path) 2660 { 2661 //ae.parent = path; 2662 if(curscope.length + 1 + path.length > parentbuf.length) 2663 errmodpath(); 2664 parentbuf[curscope.length + 1 .. curscope.length + 1 + path.length] = path; 2665 s2 = parentbuf[0 .. curscope.length + 1 + path.length]; 2666 } 2667 ae.flags = parseDApiFlags(flagstr); 2668 api.addApiEnumValue(s2, ae); 2669 } 2670 break; 2671 2672 case "import": 2673 { 2674 if(!curscope.length) 2675 break; 2676 assert('.' == parentbuf[curscope.length]); // ? 2677 2678 char[] flagstr; 2679 flagstr = nextWord(line); 2680 char[] impmod; 2681 impmod = nextWord(line); 2682 ApiImport* ai; 2683 ai = cast(ApiImport*)mem(ApiImport.sizeof); 2684 *ai = ApiImport.init; 2685 ai.type = ApiType.IMPORT; 2686 ai.name = ""; // ... it doesn't have a name unless it imported-as or something. Guess that's a to-do. The = name could be the next word. 2687 ai.importmodule = cast(char[])mem(impmod.length)[0 .. impmod.length]; 2688 s2 = curscope; 2689 ai.flags = parseDApiFlags(flagstr); 2690 api.addApiImport(s2, ai); 2691 } 2692 break; 2693 2694 default: ; 2695 } 2696 } 2697 } 2698 1757 2699 } 1758 2700 … … 1939 2881 DEPRECATED = 0x20, // d 1940 2882 PACKAGE = 0x40, // k 2883 2884 PRIVATE = 0x80, // 2885 2886 UNDOCUMENTED = 0x100, // JSON only. 1941 2887 } 1942 2888 trunk/win32/entice/apisearchopts.d
r101 r102 48 48 checkBox1.text = "Use &wildcards"; 49 49 checkBox1.checkState = dfl.button.CheckState.CHECKED; 50 checkBox1.bounds = dfl. base.Rect(8, 8, 115, 15);50 checkBox1.bounds = dfl.all.Rect(8, 8, 115, 15); 51 51 checkBox1.parent = this; 52 52 //~DFL dfl.button.CheckBox=checkBox2 … … 55 55 checkBox2.text = "Search &class names"; 56 56 checkBox2.checkState = dfl.button.CheckState.CHECKED; 57 checkBox2.bounds = dfl. base.Rect(8, 40, 139, 15);57 checkBox2.bounds = dfl.all.Rect(8, 40, 139, 15); 58 58 checkBox2.parent = this; 59 59 //~DFL dfl.button.CheckBox=checkBox3 … … 62 62 checkBox3.text = "Search &struct names"; 63 63 checkBox3.checkState = dfl.button.CheckState.CHECKED; 64 checkBox3.bounds = dfl. base.Rect(8, 64, 139, 15);64 checkBox3.bounds = dfl.all.Rect(8, 64, 139, 15); 65 65 checkBox3.parent = this; 66 66 //~DFL dfl.button.CheckBox=checkBox4 … … 69 69 checkBox4.text = "Search &interface names"; 70 70 checkBox4.checkState = dfl.button.CheckState.CHECKED; 71 checkBox4.bounds = dfl. base.Rect(8, 88, 139, 15);71 checkBox4.bounds = dfl.all.Rect(8, 88, 139, 15); 72 72 checkBox4.parent = this; 73 73 //~DFL dfl.button.CheckBox=checkBox5 … … 76 76 checkBox5.text = "Search &union names"; 77 77 checkBox5.checkState = dfl.button.CheckState.CHECKED; 78 checkBox5.bounds = dfl. base.Rect(8, 112, 139, 15);78 checkBox5.bounds = dfl.all.Rect(8, 112, 139, 15); 79 79 checkBox5.parent = this; 80 80 //~DFL dfl.button.CheckBox=checkBox6 … … 83 83 checkBox6.text = "Search &function names (top level / global)"; 84 84 checkBox6.checkState = dfl.button.CheckState.CHECKED; 85 checkBox6.bounds = dfl. base.Rect(8, 144, 251, 15);85 checkBox6.bounds = dfl.all.Rect(8, 144, 251, 15); 86 86 checkBox6.parent = this; 87 87 //~DFL dfl.button.CheckBox=checkBox7 … … 90 90 checkBox7.text = "Search &method / member function names"; 91 91 checkBox7.checkState = dfl.button.CheckState.CHECKED; 92 checkBox7.bounds = dfl. base.Rect(8, 168, 251, 15);92 checkBox7.bounds = dfl.all.Rect(8, 168, 251, 15); 93 93 checkBox7.parent = this; 94 94 //~DFL dfl.button.CheckBox=checkBox8 … … 96 96 checkBox8.name = "checkBox8"; 97 97 checkBox8.text = "Search &constant names"; 98 checkBox8.bounds = dfl. base.Rect(8, 200, 219, 15);98 checkBox8.bounds = dfl.all.Rect(8, 200, 219, 15); 99 99 checkBox8.parent = this; 100 100 //~DFL dfl.button.CheckBox=checkBox9 … … 102 102 checkBox9.name = "checkBox9"; 103 103 checkBox9.text = "Search &field / member variable names"; 104 checkBox9.bounds = dfl. base.Rect(8, 224, 219, 15);104 checkBox9.bounds = dfl.all.Rect(8, 224, 219, 15); 105 105 checkBox9.parent = this; 106 106 //~DFL dfl.button.CheckBox=checkBox10 … … 108 108 checkBox10.name = "checkBox10"; 109 109 checkBox10.text = "Search pu&blic items"; 110 checkBox10.bounds = dfl. base.Rect(8, 256, 155, 15);110 checkBox10.bounds = dfl.all.Rect(8, 256, 155, 15); 111 111 checkBox10.parent = this; 112 112 //~DFL dfl.button.CheckBox=checkBox11 … … 114 114 checkBox11.name = "checkBox11"; 115 115 checkBox11.text = "Search p&rotected items"; 116 checkBox11.bounds = dfl. base.Rect(8, 280, 155, 15);116 checkBox11.bounds = dfl.all.Rect(8, 280, 155, 15); 117 117 checkBox11.parent = this; 118 118 //~DFL dfl.button.CheckBox=checkBox12 … … 120 120 checkBox12.name = "checkBox12"; 121 121 checkBox12.text = "Treat properties as fields"; 122 checkBox12.bounds = dfl. base.Rect(8, 312, 155, 15);122 checkBox12.bounds = dfl.all.Rect(8, 312, 155, 15); 123 123 checkBox12.parent = this; 124 124 //~Entice Designer 0.7.3pre4 code ends here. trunk/win32/entice/apiviewer.d
r101 r102 5 5 import std.uri, std.string; 6 6 7 private import dfl.all , dfl.winapi;8 9 import dscale ;7 private import dfl.all; 8 9 import dscale, util; 10 10 11 11 import resource; 12 12 13 13 import apiinfo; 14 15 16 void launchUrl(char[] url)17 {18 if(cast(int)ShellExecuteA(null, "open", std.string.toStringz(url), null, null, 0) <= 32)19 {20 msgBox("Unable to open URL");21 }22 23 /+24 ShellExecuteA(null, "open", "rundll32.exe",25 std.string.toStringz("url.dll,FileProtocolHandler " ~ url),26 null, SW_SHOWDEFAULT);27 +/28 }29 14 30 15 … … 222 207 void dispApi(ApiFlags af, char[] apicat, char[] beforename, char[] name, char[] aftername = null) 223 208 { 209 char[] s; 210 if(af & ApiFlags.PRIVATE) 211 { 212 s ~= "private "; 213 } 214 else if(af & ApiFlags.PROTECTED) 215 { 216 s ~= "protected "; 217 } 218 else if(af & ApiFlags.PACKAGE) 219 { 220 s ~= "package "; 221 } 222 if(af & ApiFlags.STATIC) 223 { 224 s ~= "static "; 225 } 226 else if(af & ApiFlags.FINAL) 227 { 228 s ~= "final "; 229 } 230 if(s.length) 231 { 232 infoDisp.selectionColor = Color(0x7F, 0, 0).blendColor(infoDisp.foreColor); 233 infoDisp.appendText(s); 234 } 235 224 236 infoDisp.selectionColor = Color(0, 0, 0xFF).blendColor(infoDisp.foreColor); 225 237 infoDisp.appendText(apicat ~ " "); 226 227 char[] s;228 if(af & ApiFlags.PROTECTED)229 {230 s ~= "protected ";231 }232 if(af & ApiFlags.STATIC)233 {234 s ~= "static ";235 }236 if(s.length)237 {238 infoDisp.selectionColor = Color(0x7F, 0, 0).blendColor(infoDisp.foreColor);239 infoDisp.appendText(s);240 }241 238 242 239 if(beforename.length) … … 310 307 else 311 308 { 312 if(af.functype & ApiFunc.METHOD) 309 if(af.entry.name == "this") 310 { 311 dispApi(apinode.apiEntry.flags, "constructor", af.itemRValue ~ " ", apinode.apiEntry.name, af.getArgsString()); 312 } 313 else if(af.entry.name == "~this") 314 { 315 dispApi(apinode.apiEntry.flags, "destructor", af.itemRValue ~ " ", apinode.apiEntry.name, af.getArgsString()); 316 } 317 else if(af.functype & ApiFunc.METHOD) 313 318 { 314 319 dispApi(apinode.apiEntry.flags, "method", af.itemRValue ~ " ", apinode.apiEntry.name, af.getArgsString()); trunk/win32/entice/checkup.d
r101 r102 5 5 private import std.socket, std.string; 6 6 7 private import dfl.all, dfl. winapi;7 private import dfl.all, dfl.internal.winapi; 8 8 9 9 private import dfldesigner; … … 451 451 checkout.multiline = true; 452 452 checkout.readOnly = true; 453 checkout.bounds = dfl. base.Rect(8, 8, 248, 104);453 checkout.bounds = dfl.all.Rect(8, 8, 248, 104); 454 454 checkout.parent = this; 455 455 //~DFL dfl.button.Button=checkBtn … … 457 457 checkBtn.name = "checkBtn"; 458 458 checkBtn.text = "Check"; 459 checkBtn.bounds = dfl. base.Rect(104, 120, 75, 23);459 checkBtn.bounds = dfl.all.Rect(104, 120, 75, 23); 460 460 checkBtn.parent = this; 461 461 //~DFL dfl.button.Button=closeBtn … … 463 463 closeBtn.name = "closeBtn"; 464 464 closeBtn.text = "Close"; 465 closeBtn.bounds = dfl. base.Rect(184, 120, 75, 23);465 closeBtn.bounds = dfl.all.Rect(184, 120, 75, 23); 466 466 closeBtn.parent = this; 467 467 //~Entice Designer 0.8pre8 code ends here. trunk/win32/entice/controlchildren.d
r101 r102 3 3 4 4 5 private import dfl.all, dfl. winapi;5 private import dfl.all, dfl.internal.winapi; 6 6 7 7 private import design, designcontrol, designform; trunk/win32/entice/ddcontrolchildren.d
r101 r102 115 115 116 116 117 void updateVariableNames(DflDesignTab dtab, EditorTab etab )117 void updateVariableNames(DflDesignTab dtab, EditorTab etab, bool alsoDesignSource = true) 118 118 { 119 119 assert(dtab.entity !is null); … … 154 154 } 155 155 156 etab.sci.beginDesignUpdate(); 157 156 158 etab.sci.sendEditor(SCI_REPLACETARGET, dvarsec.length, cast(LPARAM)dvarsec.ptr); 157 etab.sci.changedDesignerVariables(); // Clears undo buffer if needed. 158 } 159 160 161 void updateVariableNames(DflDesignTab dtab) 159 etab.sci.changedDesignerVariables(); 160 161 if(alsoDesignSource) 162 { 163 _regenDesignSource(dtab, etab); 164 } 165 166 etab.sci.endDesignUpdate(); 167 } 168 169 170 void updateVariableNames(DflDesignTab dtab, bool alsoDesignSource = true) 162 171 { 163 172 EditorTab etab; … … 171 180 } 172 181 173 updateVariableNames(dtab, etab );182 updateVariableNames(dtab, etab, alsoDesignSource); 174 183 } 175 184 … … 177 186 // Note: does not set as modified. 178 187 void regenDesignSource(DflDesignTab dtab, EditorTab etab) 188 { 189 etab.sci.beginDesignUpdate(); 190 _regenDesignSource(dtab, etab); 191 etab.sci.endDesignUpdate(); 192 } 193 194 void regenDesignSource(DflDesignTab dtab) 195 { 196 EditorTab etab; 197 198 assert(dtab.entity !is null); 199 foreach(ETab ontab; dtab.entity.etabs) 200 { 201 etab = cast(EditorTab)ontab; 202 if(etab) 203 break; 204 } 205 206 regenDesignSource(dtab, etab); 207 } 208 209 private void _regenDesignSource(DflDesignTab dtab, EditorTab etab) 179 210 { 180 211 assert(dtab.entity !is null); … … 225 256 etab.sci.foldDesignerSource(); 226 257 } 227 }228 229 230 void regenDesignSource(DflDesignTab dtab)231 {232 EditorTab etab;233 234 assert(dtab.entity !is null);235 foreach(ETab ontab; dtab.entity.etabs)236 {237 etab = cast(EditorTab)ontab;238 if(etab)239 break;240 }241 242 regenDesignSource(dtab, etab);243 258 } 244 259 … … 422 437 { 423 438 Size sz; 424 sz = typeof(this).defaultSize; 439 //sz = typeof(this).defaultSize; // DMD 1.033: ddcontrolchildren.d(424): Error: this for defaultSize needs to be type Form not type ddcontrolchildren.DesignUnknownControl 440 sz = defaultSize; 425 441 if(!sz.width) 426 442 sz.width = 32; … … 784 800 private void showPropBox() 785 801 { 786 // Show my prop box first. Showing it after causes extra flickering. 787 //propBox.dock = DockStyle.FILL; 788 propBox.parent = propPanel; 789 propBox.visible = true; 802 // If multiple selected, don't show any (for now). 803 // Later I'll show the properties in common. 804 if(!dControlMultipleSelected(this, true)) 805 { 806 // Show my prop box first. Showing it after causes extra flickering. 807 //propBox.dock = DockStyle.FILL; 808 propBox.parent = propPanel; 809 propBox.visible = true; 810 } 790 811 791 812 // Hide other prop boxes. … … 876 897 final void updatePropInfo() 877 898 { 878 if(propBox) 879 { 880 updatePropInfoFromPropBox(propBox); 899 int numsel = dControlCountSelected(this, true); 900 if(numsel > 1) 901 { 902 // If multiple selected,.. 903 propInfo.setInfo(std.string.toString(numsel) ~ " selected", null); 904 } 905 else 906 { 907 if(propBox) 908 { 909 updatePropInfoFromPropBox(propBox); 910 } 881 911 } 882 912 } … … 969 999 970 1000 971 void updateVariableNames( )972 { 973 //if(! loaded)1001 void updateVariableNames(bool alsoDesignSource = true, bool force = false) 1002 { 1003 //if(!force && !loaded) 974 1004 // return; 975 1005 976 .updateVariableNames(dtab); 1006 if(alsoDesignSource) 1007 { 1008 if(!force && !loaded) 1009 alsoDesignSource = false; 1010 } 1011 1012 .updateVariableNames(dtab, alsoDesignSource); 977 1013 } 978 1014 … … 1003 1039 updateVariableNames(); 1004 1040 } 1005 1006 regenDesignSource(); 1041 else 1042 { 1043 regenDesignSource(); 1044 } 1007 1045 1008 1046 // Sometimes a prop change causes a visual update, so need to refresh design overlays. … … 1110 1148 dtab.entity.modified = true; 1111 1149 1150 loaded = true; 1151 1112 1152 updateVariableNames(); 1113 1114 loaded = true;1115 1116 regenDesignSource();1117 1153 } 1118 1154 1119 1155 1120 1156 void initRemoveThisDesign(bit first) 1121 in1122 1157 { 1123 1158 assert(this.dtab !is null); 1124 } 1125 body 1126 { 1159 1127 1160 Control ctrl; 1128 1161 IDesignControl dcparent; … … 1163 1196 1164 1197 dtab.entity.modified = true; 1165 updateVariableNames(); 1166 regenDesignSource(true); // Has to be forced because the control is gone! 1198 updateVariableNames(true, true); // Design update to be forced because the control is gone! 1167 1199 } 1168 1200 … … 1194 1226 // Adding -dctrl- to DflDesignTab dtab. -dctrl-'s icon is -icon-. 1195 1227 final void addDesignControl(IDflDesignChildControl dctrl, DflDesignTab dtab, Icon icon) 1196 in1197 1228 { 1198 1229 assert(dctrl !is null); 1199 1230 //assert(pcombo !is null); 1200 1231 assert(dtab !is null); 1201 } 1202 body 1203 { 1232 1204 1233 ctrlSpacing = false; 1205 1234 … … 1256 1285 1257 1286 final void removeDesignControl(IDflDesignChildControl dctrl, bit first = true) 1258 in1259 1287 { 1260 1288 assert(dctrl !is null); 1261 } 1262 body 1263 { 1289 1264 1290 dctrl.initRemoveThisDesign(first); 1265 1291 } … … 1275 1301 1276 1302 1277 protected void deleteThisDesign() 1278 { 1303 protected void deleteAllSelectedDesign() 1304 { 1305 IDflDesignChildControl[4] _delbuf; 1306 IDflDesignChildControl[] delbuf = _delbuf; 1307 int numdels = 0; 1308 1279 1309 dControlAllSelected(this, 1280 delegate bit(IDesignControlItem dctrli)1310 delegate (IDesignControlItem dctrli) 1281 1311 { 1282 1312 IDflDesignChildControl dctrlc; 1283 1313 dctrlc = cast(IDflDesignChildControl)dctrli; 1284 if(dctrlc && !(dctrlc.getDesignControlFlags() & DdDesignControlFlags.OPEN_ITEM))1314 if(dctrlc) 1285 1315 { 1286 removeDesignControl(dctrlc); 1316 if(numdels >= delbuf.length) 1317 delbuf ~= dctrlc; 1318 else 1319 delbuf[numdels] = dctrlc; 1320 numdels++; 1287 1321 } 1288 1322 else … … 1292 1326 return true; // Continue. 1293 1327 }); 1328 1329 foreach(IDflDesignChildControl dctrlc; delbuf[0 .. numdels]) 1330 { 1331 if(!(dctrlc.getDesignControlFlags() & DdDesignControlFlags.OPEN_ITEM)) 1332 { 1333 removeDesignControl(dctrlc); 1334 } 1335 } 1336 1294 1337 } 1295 1338 … … 1298 1341 void itemDeleteKey() 1299 1342 { 1300 //if(!(ddcflags & DdDesignControlFlags.OPEN_ITEM)) 1301 deleteThisDesign(); 1343 deleteAllSelectedDesign(); 1302 1344 } 1303 1345 … … 1329 1371 1330 1372 doneUsingTool(); 1331 } 1373 1374 return; // Handled! 1375 } 1376 } 1377 1378 version(ENTICE_MULTISEL) 1379 { 1380 // Select all in selection rectangle. 1381 bool clearOthers = true; 1382 this.getItems( 1383 (IDesignControlItem idci) 1384 { 1385 Rect idciRect; 1386 idci.getItemBounds(idciRect); 1387 if(itembounds.intersectsWith(idciRect)) 1388 { 1389 IDesignControl idc = cast(IDesignControl)idci; 1390 if(idc) 1391 { 1392 dControlUpdateSelect(idc, true, clearOthers); 1393 clearOthers = false; 1394 } 1395 } 1396 return true; // Continue. 1397 }); 1332 1398 } 1333 1399 } … … 1364 1430 1365 1431 doneUsingTool(); 1432 1433 return; // Handled! 1366 1434 } 1367 1435 } … … 1373 1441 void itemPaint(PAINTSTRUCT* ps) 1374 1442 { 1375 autoGraphics g = new Graphics(ps.hdc, false);1443 scope Graphics g = new Graphics(ps.hdc, false); 1376 1444 auto PaintEventArgs ea = new PaintEventArgs(g, Rect(&ps.rcPaint)); 1377 1445 onPaint(ea); … … 1522 1590 if(mod) 1523 1591 { 1524 regenDesignSource();1525 1592 if(modvars) 1526 1593 updateVariableNames(); 1594 else 1595 regenDesignSource(); 1527 1596 1528 1597 if(newtype) … … 1584 1653 if(topmost) 1585 1654 { 1586 scopezof = new ZOF.ZOrderForm();1655 auto zof = new ZOF.ZOrderForm(); 1587 1656 1588 1657 void allchildren(Control cc, uint indentlevel) … … 1665 1734 private void deleteMenu_click(Object sender, EventArgs ea) 1666 1735 { 1667 delete ThisDesign();1736 deleteAllSelectedDesign(); 1668 1737 1669 1738 dtab.entity.modified = true; … … 1754 1823 1755 1824 void initContextMenu() 1756 in1825 /+in 1757 1826 { 1758 1827 assert(cmenu is null); … … 1762 1831 assert(cmenu !is null); 1763 1832 } 1764 body 1833 body+/ 1765 1834 { 1766 1835 MenuItem mi; … … 2217 2286 delegate(HDC hdc, Rect r) 2218 2287 { 2219 autoGraphics g = new Graphics(hdc, false);2220 autoPaintEventArgs ea = new PaintEventArgs(g, r);2288 scope Graphics g = new Graphics(hdc, false); 2289 scope PaintEventArgs ea = new PaintEventArgs(g, r); 2221 2290 onPaintBackground(ea); 2222 2291 }, … … 6967 7036 6968 7037 6969 private extern(Windows) voidchildEditWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)7038 private extern(Windows) LRESULT childEditWndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 6970 7039 { 6971 7040 Message m; trunk/win32/entice/ddcontrolspace.d
r101 r102 3 3 4 4 5 import dfl.all, dfl. winapi;5 import dfl.all, dfl.internal.winapi; 6 6 7 7 import winapi, design; trunk/win32/entice/dddesignform.d
r101 r102 15 15 16 16 const char[][] FORM_START_POSITION_NAMES = ["CENTER_PARENT", "CENTER_SCREEN", "MANUAL", 17 " WINDOWS_DEFAULT_BOUNDS", "WINDOWS_DEFAULT_LOCATION"];17 "DEFAULT_BOUNDS", "DEFAULT_LOCATION"]; 18 18 19 19 const char[][] FORM_WINDOW_STATE_NAMES = ["MAXIMIZED", "MINIMIZED", "NORMAL"]; trunk/win32/entice/ddeditorstyler.d
r101 r102 4 4 5 5 private import std.string; 6 private import dfl.all, dfl. winapi;6 private import dfl.all, dfl.internal.winapi; 7 7 private import editorstyler, scistyles, util; 8 8 private import dfldesigner; trunk/win32/entice/ddexprops.d
r101 r102 3 3 4 4 5 private import dfl.all, dfl. winapi;5 private import dfl.all, dfl.internal.winapi; 6 6 7 7 import design; … … 135 135 itemNameDisp.text = "Foo"; 136 136 itemNameDisp.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 137 itemNameDisp.bounds = dfl. base.Rect(36, 7, 276, 23);137 itemNameDisp.bounds = dfl.all.Rect(36, 7, 276, 23); 138 138 itemNameDisp.parent = this; 139 139 //~DFL dfl.picturebox.PictureBox=picBox … … 141 141 picBox.name = "picBox"; 142 142 picBox.sizeMode = dfl.picturebox.PictureBoxSizeMode.CENTER_IMAGE; 143 picBox.bounds = dfl. base.Rect(8, 8, 23, 23);143 picBox.bounds = dfl.all.Rect(8, 8, 23, 23); 144 144 picBox.parent = this; 145 145 //~DFL dfl.label.Label=label1 … … 148 148 label1.text = "&Type:"; 149 149 label1.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 150 label1.bounds = dfl. base.Rect(8, 40, 76, 23);150 label1.bounds = dfl.all.Rect(8, 40, 76, 23); 151 151 label1.parent = this; 152 152 //~DFL dfl.textbox.TextBox=typeBox 153 153 typeBox = new dfl.textbox.TextBox(); 154 154 typeBox.name = "typeBox"; 155 typeBox.bounds = dfl. base.Rect(112, 40, 192, 23);155 typeBox.bounds = dfl.all.Rect(112, 40, 192, 23); 156 156 typeBox.parent = this; 157 157 //~DFL dfl.label.Label=ctorLabel … … 160 160 ctorLabel.text = "&Constructor call:"; 161 161 ctorLabel.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 162 ctorLabel.bounds = dfl. base.Rect(8, 72, 92, 23);162 ctorLabel.bounds = dfl.all.Rect(8, 72, 92, 23); 163 163 ctorLabel.parent = this; 164 164 //~DFL dfl.textbox.TextBox=ctorBox … … 166 166 ctorBox.name = "ctorBox"; 167 167 ctorBox.text = "()"; 168 ctorBox.bounds = dfl. base.Rect(112, 72, 192, 23);168 ctorBox.bounds = dfl.all.Rect(112, 72, 192, 23); 169 169 ctorBox.parent = this; 170 170 //~DFL dfl.button.CheckBox=autoScaleCheck … … 173 173 autoScaleCheck.enabled = false; 174 174 autoScaleCheck.text = "autoScale"; 175 autoScaleCheck.bounds = dfl. base.Rect(8, 104, 107, 23);175 autoScaleCheck.bounds = dfl.all.Rect(8, 104, 107, 23); 176 176 autoScaleCheck.parent = this; 177 177 //~DFL dfl.button.Button=okBtn … … 179 179 okBtn.name = "okBtn"; 180 180 okBtn.text = "OK"; 181 okBtn.bounds = dfl. base.Rect(152, 104, 75, 23);181 okBtn.bounds = dfl.all.Rect(152, 104, 75, 23); 182 182 okBtn.parent = this; 183 183 //~DFL dfl.button.Button=cancelBtn … … 185 185 cancelBtn.name = "cancelBtn"; 186 186 cancelBtn.text = "Cancel"; 187 cancelBtn.bounds = dfl. base.Rect(232, 104, 75, 23);187 cancelBtn.bounds = dfl.all.Rect(232, 104, 75, 23); 188 188 cancelBtn.parent = this; 189 189 //~Entice Designer 0.8pre8 code ends here. trunk/win32/entice/ddfindreplace.d
r101 r102 8 8 9 9 private import std.string, std.utf, std.ctype; 10 private import dfl.all, dfl. winapi;10 private import dfl.all, dfl.internal.winapi; 11 11 private import dfl.scintilla, dfl.cpp.scintilla, dfl.cpp.scilexer; 12 12 private import findreplace, dfldesigner; … … 20 20 //import std.regexp; 21 21 import myregexp; 22 } 23 24 25 interface IFindReplaceTitle 26 { 27 string findReplaceTitle(); // getter 22 28 } 23 29 … … 164 170 if(!findrep) 165 171 return; 172 173 { 174 IFindReplaceTitle ifrt = cast(IFindReplaceTitle)sci; 175 if(ifrt) 176 { 177 findrep.text = ifrt.findReplaceTitle(); 178 } 179 else 180 { 181 if(allowreplace && sci) 182 findrep.text = "Find and Replace"; 183 else 184 findrep.text = "Find"; 185 } 186 } 187 166 188 //allowreplace = !(sci && sci.sendEditor(SCI_GETREADONLY)); 167 189 allowreplace = !(!sci || sci.sendEditor(SCI_GETREADONLY)); … … 206 228 207 229 static private void _createFindrep() 208 in209 230 { 210 231 assert(findrep is null); 211 } 212 body 213 { 232 214 233 with(mainForm) 215 234 { … … 378 397 { 379 398 void doReplaceAtI() 380 in381 399 { 382 400 assert(-1 != i); 383 } 384 body 385 { 401 386 402 if(regexCheck.checked) 387 403 { … … 522 538 // if wrap is true, when hitting iend, wraps back to 0 to istart. 523 539 void findrepReplaceHere(uint istart, uint iend, uint maxreplacements = 1, bool wrap = false) 524 in525 540 { 526 541 assert(findrep !is null); 527 542 assert(istart <= iend); 528 } 529 body 530 { 543 531 544 assert(allowreplace); 532 545 … … 605 618 606 619 void doReplaceAtI() 607 in608 620 { 609 621 assert(-1 != i); 610 } 611 body 612 { 622 613 623 flen = sci.sendEditor(SCI_GETTARGETEND) - sci.sendEditor(SCI_GETTARGETSTART); 614 624 … … 1200 1210 // -findString- must be set. 1201 1211 static void doFindNext() 1202 in1203 1212 { 1204 1213 assert(findString.length); 1205 } 1206 body 1207 { 1214 1208 1215 if(!findrep) 1209 1216 _createFindrep(); … … 1281 1288 // -findString- must be set. 1282 1289 static void doFindPrevious() 1283 in1284 1290 { 1285 1291 assert(findString.length); 1286 } 1287 body 1288 { 1292 1289 1293 if(!findrep) 1290 1294 _createFindrep(); trunk/win32/entice/ddopenparser.d
r101 r102 6 6 std.intrinsic, std.utf, std.stdint; 7 7 8 private import dfl.all, dfl. winapi, dfl.utf;8 private import dfl.all, dfl.internal.winapi, dfl.internal.utf; 9 9 private import dfl.scintilla, dfl.cpp.scintilla, dfl.cpp.scilexer; 10 10 trunk/win32/entice/ddoptions.d
r101 r102 14 14 15 15 import ddoptsdesignpanel, ddoptsgeneralpanel, ddoptseditorpanel, 16 ddoptsnetworkpanel, ddoptspluginspanel, ddoptsfiletypespanel; 16 ddoptsnetworkpanel, ddoptspluginspanel, ddoptsfiletypespanel, 17 ddoptscompilerpanel; 17 18 18 19 import rgroup, rdflregistry; … … 675 676 uint32_t tabFirstShow = 0; 676 677 678 void delegate(DdOptionsForm) optionsReady = null; 679 677 680 678 681 this() … … 727 730 addTab(new KeywordsOptTab); 728 731 //addTab(new FileTypesOptTab); 732 addTab(new CompilerOptTab); 729 733 addTab(new NetworkOptTab); 730 734 version(QUICK_OPT) … … 761 765 } 762 766 } 767 768 if(optionsReady) 769 { 770 optionsReady(this); 771 } 763 772 } 764 773 765 774 766 775 final int findTabByGid(uint32_t gid) 767 in768 776 { 769 777 assert(isValidGid(gid)); 770 } 771 body 772 { 778 779 773 780 union _tab 774 781 { … … 827 834 else 828 835 { 829 RegistryValueDword regDword = void; 830 RegistryValueSz regSz = void; 831 RegistryValueBinary regBin = void; 832 833 //subKey.setValue(opt.optName(), regval); 834 regDword = cast(RegistryValueDword)regval; 836 RegistryValueDword regDword = cast(RegistryValueDword)regval; 835 837 if(regDword) 836 838 { … … 839 841 else 840 842 { 841 regSz = cast(RegistryValueSz)regval;843 RegistryValueSz regSz = cast(RegistryValueSz)regval; 842 844 if(regSz) 843 845 { … … 846 848 else 847 849 { 848 regBin = cast(RegistryValueBinary)regval;850 RegistryValueBinary regBin = cast(RegistryValueBinary)regval; 849 851 if(regBin) 850 852 { … … 853 855 else 854 856 { 855 assert(0, "Invalid option type"); 857 RegistryValueMultiSz regSzs = cast(RegistryValueMultiSz)regval; 858 if(regSzs) 859 { 860 subKey.setEntryString(opt.optName, stringsToCsv(regSzs.value)); 861 } 862 else 863 { 864 assert(0, "Invalid option type"); 865 } 856 866 } 857 867 } trunk/win32/entice/ddoptsdesignpanel.d
r101 r102 38 38 //~DFL Panel 39 39 name = "DdOptsDesignPanel"; 40 bounds = dfl. base.Rect(0, 25, 400, 296);40 bounds = dfl.all.Rect(0, 25, 400, 296); 41 41 autoScaleBaseSize = Size(5, 13); 42 42 //~DFL OptCheckBox:dfl.button.CheckBox=showGridCheck … … 44 44 showGridCheck.name = "showGridCheck"; 45 45 showGridCheck.text = "Show &grid lines with spacing of:"; 46 showGridCheck.bounds = dfl. base.Rect(8, 8, 174, 23);46 showGridCheck.bounds = dfl.all.Rect(8, 8, 174, 23); 47 47 showGridCheck.parent = this; 48 48 //~DFL OptTextBoxDword:dfl.textbox.TextBox=gridSizeBox 49 49 gridSizeBox = new OptTextBoxDword("gridsize",575913561,false,true); 50 50 gridSizeBox.name = "gridSizeBox"; 51 gridSizeBox.bounds = dfl. base.Rect(187, 8, 32, 23);51 gridSizeBox.bounds = dfl.all.Rect(187, 8, 32, 23); 52 52 gridSizeBox.parent = this; 53 53 //~DFL OptCheckBox:dfl.button.CheckBox=snapGridCheck … … 55 55 snapGridCheck.name = "snapGridCheck"; 56 56 snapGridCheck.text = "&Snap to grid"; 57 snapGridCheck.bounds = dfl. base.Rect(8, 32, 115, 23);57 snapGridCheck.bounds = dfl.all.Rect(8, 32, 115, 23); 58 58 snapGridCheck.parent = this; 59 59 //~DFL OptCheckBox:dfl.button.CheckBox=sameToolCheck … … 61 61 sameToolCheck.name = "sameToolCheck"; 62 62 sameToolCheck.text = "Always stay on the same &tool"; 63 sameToolCheck.bounds = dfl. base.Rect(8, 56, 275, 23);63 sameToolCheck.bounds = dfl.all.Rect(8, 56, 275, 23); 64 64 sameToolCheck.parent = this; 65 65 //~DFL OptCheckBox:dfl.button.CheckBox=prevSpaceCheck … … 67 67 prevSpaceCheck.name = "prevSpaceCheck"; 68 68 prevSpaceCheck.text = "Insert space when &hovering edges of docked controls"; 69 prevSpaceCheck.bounds = dfl. base.Rect(8, 80, 355, 23);69 prevSpaceCheck.bounds = dfl.all.Rect(8, 80, 355, 23); 70 70 prevSpaceCheck.parent = this; 71 71 //~Entice Designer 0.8.2pre7 code ends here. trunk/win32/entice/ddoptsnetworkpanel.d
r101 r102 39 39 //~DFL Panel 40 40 name = "DdOptsNetworkPanel"; 41 bounds = dfl. base.Rect(0, 25, 384, 272);41 bounds = dfl.all.Rect(0, 25, 384, 272); 42 42 autoScaleBaseSize = Size(5, 13); 43 43 //~DFL dfl.groupbox.GroupBox=proxyGroup 44 44 proxyGroup = new dfl.groupbox.GroupBox(); 45 45 proxyGroup.name = "proxyGroup"; 46 proxyGroup.bounds = dfl. base.Rect(8, 8, 328, 60);46 proxyGroup.bounds = dfl.all.Rect(8, 8, 328, 60); 47 47 proxyGroup.parent = this; 48 48 //~DFL OptCheckBox:dfl.button.CheckBox=useProxyCheck … … 50 50 useProxyCheck.name = "useProxyCheck"; 51 51 useProxyCheck.text = "Use &proxy server"; 52 useProxyCheck.bounds = dfl. base.Rect(10, -3, 105, 23);52 useProxyCheck.bounds = dfl.all.Rect(10, -3, 105, 23); 53 53 useProxyCheck.parent = proxyGroup; 54 54 //~DFL dfl.label.Label=proxyHttpServerLabel … … 58 58 proxyHttpServerLabel.text = "HTTP &server:"; 59 59 proxyHttpServerLabel.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 60 proxyHttpServerLabel.bounds = dfl. base.Rect(12, 25, 68, 23);60 proxyHttpServerLabel.bounds = dfl.all.Rect(12, 25, 68, 23); 61 61 proxyHttpServerLabel.parent = proxyGroup; 62 62 //~DFL OptTextBox:dfl.textbox.TextBox=proxyHttpServerBox … … 64 64 proxyHttpServerBox.name = "proxyHttpServerBox"; 65 65 proxyHttpServerBox.enabled = false; 66 proxyHttpServerBox.bounds = dfl. base.Rect(88, 25, 128, 23);66 proxyHttpServerBox.bounds = dfl.all.Rect(88, 25, 128, 23); 67 67 proxyHttpServerBox.parent = proxyGroup; 68 68 //~DFL dfl.label.Label=proxyHttpPortLabel … … 72 72 proxyHttpPortLabel.text = "Por&t:"; 73 73 proxyHttpPortLabel.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 74 proxyHttpPortLabel.bounds = dfl. base.Rect(230, 25, 28, 23);74 proxyHttpPortLabel.bounds = dfl.all.Rect(230, 25, 28, 23); 75 75 proxyHttpPortLabel.parent = proxyGroup; 76 76 //~DFL OptTextBoxDword:dfl.textbox.TextBox=proxyHttpPortBox … … 78 78 proxyHttpPortBox.name = "proxyHttpPortBox"; 79 79 proxyHttpPortBox.enabled = false; 80 proxyHttpPortBox.bounds = dfl. base.Rect(268, 25, 48, 23);80 proxyHttpPortBox.bounds = dfl.all.Rect(268, 25, 48, 23); 81 81 proxyHttpPortBox.parent = proxyGroup; 82 82 //~Entice Designer 0.8.2pre7 code ends here. … … 116 116 proxyHttpPortBox.text = "8080"; 117 117 } 118 else 119 { 120 proxyHttpPortBox.text = "8080"; 121 } 118 122 119 123 proxyHttpServerBox.focus(); … … 133 137 with(panel) 134 138 { 135 useProxy = useProxyCheck.checked ;139 useProxy = useProxyCheck.checked && proxyHttpServerBox.textLength; 136 140 } 137 141 } trunk/win32/entice/ddoptspluginspanel.d
r101 r102 119 119 120 120 121 /+ // Old plugin info.122 override void onShow(Tabber tabc, int index)123 {124 super.onShow(tabc, index);125 126 if(!_lp)127 {128 _lp = true;129 130 with(panel)131 {132 POLVItem polvi;133 char[] s;134 bool rm;135 136 const char[] REMOVING_DESC = "<Unloading>";137 138 foreach(plug; plugins.plugins)139 {140 assert(plug.fname.length);141 rm = isPluginUnloading(plug.fname);142 if(rm)143 polvi = new POLVItem(plug.fname, plug.name, REMOVING_DESC);144 else145 polvi = new POLVItem(plug.fname, plug.name, plug.desc);146 pluginView.items.add(polvi);147 polvi.checked = !rm;148 }149 150 foreach(afwe; loadeddapiplugins)151 {152 rm = isPluginUnloading(afwe);153 if(rm)154 polvi = new POLVItem(afwe, afwe, REMOVING_DESC);155 else156 polvi = new POLVItem(afwe, afwe, "API information for " ~ std.path.getName(afwe) ~ ".");157 pluginView.items.add(polvi);158 polvi.checked = !rm;159 }160 161 foreach(nlpn; notloadedplugins)162 {163 if(nlpn.length) // Ends up empty if the plugin gets loaded at some point.164 {165 polvi = new POLVItem(nlpn, nlpn, "<Not loaded>");166 pluginView.items.add(polvi);167 polvi.checked = false;168 }169 }170 171 pluginView.itemChecked ~= &pluginView_itemChecked;172 }173 }174 }175 +/176 177 121 override void onShow(Tabber tabc, int index) 178 122 { … … 211 155 { 212 156 checked = true; 213 if(ddpi.fullpath.length > 5 && !std.string.icmp(".dapi", ddpi.fullpath[$ - 5 .. $])) 157 if(ddpi.fullpath.length > 5 158 && (!std.string.icmp(".dapi", ddpi.fullpath[$ - 5 .. $]) 159 || !std.string.icmp(".json", ddpi.fullpath[$ - 5 .. $]))) 214 160 { 215 161 polvi = new POLVItem(ddpi.fname, ddpi.fname, "API information for " ~ std.path.getName(ddpi.fname) ~ "."); … … 226 172 else 227 173 { 228 polvi = new POLVItem(ddpi.fname, plug.name, "?"); // ?174 polvi = new POLVItem(ddpi.fname, std.path.getBaseName(ddpi.fname), "?"); // ? 229 175 checked = true; 230 176 } … … 265 211 } 266 212 267 268 /+ // Old plugin info.269 override void appliedOpts()270 {271 // Update dirty ones..272 with(panel)273 {274 IRGroup pigrp;275 foreach(idx, lvi; pluginView.items)276 {277 //if(lvi.tag is lvi)278 if(lvi.tag)279 {280 auto polvi = cast(POLVItem)lvi;281 if(polvi)282 {283 if(!pigrp)284 pigrp = getRkey().createSubGroup("Load");285 286 assert(polvi.fname.length);287 pigrp.setEntryInt("P:" ~ polvi.fname, polvi.checked ? 1 : 0);288 289 setPluginUnloading(polvi.fname, !polvi.checked);290 291 bool asloading = false;292 if(polvi.checked)293 {294 foreach(nlpidx, nlp; notloadedplugins)295 {296 297 // Note.. must be called AFTER done using notloadedpluginpaths[nlpidx].298 void clearNotLoadedPluginPath()299 {300 notloadedplugins[nlpidx] = null; // Easier than removing it.301 notloadedpluginpaths[nlpidx] = null; // Easier than removing it.302 }303 304 305 if(!std.string.icmp(polvi.fname, nlp))306 {307 if(!asloading)308 {309 // Show as "Loading" so that all the plugins can be loaded blocking.310 asloading = true;311 //checkchangednote.text = "";312 checkchangednote.foreColor = SystemColors.controlText.blendColor(SystemColors.highlight);313 checkchangednote.text = " Loading plugins...";314 checkchangednote.visible = true;315 //checkchangednote.update(); // Show the new text.316 Application.doEvents(); // So that dock stuff runs, etc.317 }318 319 char[] ext = std.path.getExt(nlp);320 if(!std.string.icmp(ext, "dll"))321 {322 char[] emsg;323 Plugin plug;324 int errnum;325 //msgBox(notloadedpluginpaths[nlpidx], polvi.fname);326 emsg = loadDllPlugin(notloadedpluginpaths[nlpidx], plug, false, errnum);327 if(emsg.length)328 {329 msgBox(emsg, "Plugin: " ~ polvi.fname, MsgBoxButtons.OK, MsgBoxIcon.ASTERISK);330 }331 else332 {333 if(plug)334 {335 clearNotLoadedPluginPath();336 337 registerPlugin(plug);338 signalOnePluginLoaded(plug);339 }340 }341 }342 else if(!std.string.icmp(ext, "dapi"))343 {344 // Can NOT load these in a separate thread from here, because apiinfo.isLoaded was already set,345 // and possibly has code wanting to run using it. Need to BLOCK to modify it.346 347 struct APIINFO { public import apiinfo; }348 349 //apiinfo.setUnloaded(); // Oh well, might as well prevent yet another thread...350 APIINFO.setUnloaded(); // Oh well, might as well prevent yet another thread...351 try352 {353 // Let other threads notice apiinfo.isLoaded changed, heh...354 Application.doEvents();355 struct THD { public import std.thread; }356 //Thread.yield();357 THD.Thread.yield();358 359 //loadApiInfo(notloadedpluginpaths[nlpidx]);360 //apiinfo.loadApiInfo(notloadedpluginpaths[nlpidx]); // I don't see how this works but the previous line doesn't... Maybe compiler bug.361 APIINFO.loadApiInfo(notloadedpluginpaths[nlpidx]);362 363 loadeddapiplugins ~= nlp;364 365 clearNotLoadedPluginPath();366 }367 finally368 {369 //apiinfo.setLoadedOne(); // Need to restore.370 APIINFO.setLoadedOne(); // Need to restore.371 }372 }373 else374 {375 clearNotLoadedPluginPath();376 377 msgBox("Unable to start plugin: " ~ polvi.fname);378 }379 break;380 }381 382 Application.doEvents(); // Since it's all loaded blocking...383 }384 }385 }386 }387 }388 }389 390 super.appliedOpts();391 }392 +/393 213 394 214 override void appliedOpts() … … 434 254 } 435 255 436 char[] ext = std.path.getExt(ddplugins[i].fullpath); 437 if(!std.string.icmp(ext, "dll")) 256 Plugin plug = null; 257 258 if(ddplugins[i].flags & DDPI.BUILTIN) 438 259 { 439 char[] emsg; 440 Plugin plug; 441 int errnum; 442 //msgBox(ddplugins[i].fullpath, polvi.fname); 443 emsg = loadDllPlugin(ddplugins[i].fullpath, plug, false, errnum); 444 if(emsg.length) 260 plug = getBuiltinPlugin(ddplugins[i].fullpath); 261 ddplugins[i].flags |= DDPI.LOADED; 262 registerPlugin(plug); 263 signalOnePluginLoaded(plug); 264 } 265 else 266 { 267 char[] ext = std.path.getExt(ddplugins[i].fullpath); 268 if(!std.string.icmp(ext, "dll")) 445 269 { 446 msgBox(emsg, "Plugin: " ~ ddplugins[i].fname, MsgBoxButtons.OK, MsgBoxIcon.ASTERISK); 270 char[] emsg; 271 int errnum; 272 //msgBox(ddplugins[i].fullpath, polvi.fname); 273 emsg = loadDllPlugin(ddplugins[i].fullpath, plug, false, errnum); 274 if(emsg.length) 275 { 276 msgBox(emsg, "Plugin: " ~ ddplugins[i].fname, MsgBoxButtons.OK, MsgBoxIcon.ASTERISK); 277 } 278 else 279 { 280 if(plug) 281 { 282 ddplugins[i].flags |= DDPI.LOADED; 283 284 registerPlugin(plug); 285 signalOnePluginLoaded(plug); // Needed to tell the plugin "loaded". On startup this is done on a delay all at once. 286 } 287 } 288 } 289 else if(!std.string.icmp(ext, "dapi") || !std.string.icmp(ext, "json")) 290 { 291 // Can NOT load these in a separate thread from here, because apiinfo.isLoaded was already set, 292 // and possibly has code wanting to run using it. Need to BLOCK to modify it. 293 294 struct APIINFO { public import apiinfo; } 295 296 //apiinfo.setUnloaded(); // Oh well, might as well prevent yet another thread... 297 APIINFO.setUnloaded(); // Oh well, might as well prevent yet another thread... 298 try 299 { 300 // Let other threads notice apiinfo.isLoaded changed, heh... 301 Application.doEvents(); 302 struct THD { public import std.thread; } 303 //Thread.yield(); 304 THD.Thread.yield(); 305 306 //loadApiInfo(ddplugins[i].fullpath); 307 //apiinfo.loadApiInfo(ddplugins[i].fullpath); // I don't see how this works but the previous line doesn't... Maybe compiler bug. 308 APIINFO.loadApiInfo(ddplugins[i].fullpath); 309 310 ddplugins[i].flags |= DDPI.LOADED; 311 } 312 finally 313 { 314 //apiinfo.setLoadedOne(); // Need to restore. 315 APIINFO.setLoadedOne(); // Need to restore. 316 } 447 317 } 448 318 else 449 319 { 450 if(plug) 451 { 452 ddplugins[i].flags |= DDPI.LOADED; 453 454 registerPlugin(plug); 455 signalOnePluginLoaded(plug); // Needed to tell the plugin "loaded". On startup this is done on a delay all at once. 456 } 320 ddplugins[i].flags |= DDPI.NOTLOADING; 321 322 msgBox("Unable to start plugin: " ~ polvi.fname); 457 323 } 458 324 } 459 else if(!std.string.icmp(ext, "dapi"))325 460 326 { 461 // Can NOT load these in a separate thread from here, because apiinfo.isLoaded was already set, 462 // and possibly has code wanting to run using it. Need to BLOCK to modify it. 463 464 struct APIINFO { public import apiinfo; } 465 466 //apiinfo.setUnloaded(); // Oh well, might as well prevent yet another thread... 467 APIINFO.setUnloaded(); // Oh well, might as well prevent yet another thread... 468 try 327 if(plug && (plug.flags & EnticePluginFlags.MASK_PLUGIN_UNIQUE_FEATURES)) 469 328 { 470 // Let other threads notice apiinfo.isLoaded changed, heh... 471 Application.doEvents(); 472 struct THD { public import std.thread; } 473 //Thread.yield(); 474 THD.Thread.yield(); 475 476 //loadApiInfo(ddplugins[i].fullpath); 477 //apiinfo.loadApiInfo(ddplugins[i].fullpath); // I don't see how this works but the previous line doesn't... Maybe compiler bug. 478 APIINFO.loadApiInfo(ddplugins[i].fullpath); 479 480 ddplugins[i].flags |= DDPI.LOADED; 481 } 482 finally 483 { 484 //apiinfo.setLoadedOne(); // Need to restore. 485 APIINFO.setLoadedOne(); // Need to restore. 329 foreach(Plugin onplug; plugins.plugins) 330 { 331 if(onplug.pluginid != plug.pluginid) 332 { 333 // Check for overlapping features. 334 if((onplug.flags & EnticePluginFlags.MASK_PLUGIN_UNIQUE_FEATURES) 335 & (plug.flags & EnticePluginFlags.MASK_PLUGIN_UNIQUE_FEATURES)) 336 { 337 msgBox("The plugin '" ~ plug.name ~ "' (" ~ plug.fname ~ ")\r\nmay conflict with an existing plugin;\r\nplease restart " ~ TITLE ~ " to resolve any issues", "Plugin Conflict"); 338 break; 339 } 340 } 341 } 486 342 } 487 343 } 488 else489 {490 ddplugins[i].flags |= DDPI.NOTLOADING;491 492 msgBox("Unable to start plugin: " ~ polvi.fname);493 }494 344 495 345 Application.doEvents(); // Since it's all loaded blocking... 346 496 347 } 497 348 } trunk/win32/entice/ddprojectmanager.d
r101 r102 318 318 if(pe.canContainSubEntries()) 319 319 { 320 TreeNode dn = new EProjectDirNode(pe, sort);320 TreeNode dn = createDirNode(pe, sort); 321 321 dn.nodes.add(cast(TreeNode)(new EProjectSubItemsLoadingNode())); 322 322 if(sort) … … 331 331 if(std.path.fnmatch(pe.name, filter)) 332 332 { 333 TreeNode fn = new EProjectFileNode(pe.name);333 TreeNode fn = createFileNode(pe.name); 334 334 if(sort) 335 335 nodes.add(fn); … … 341 341 } 342 342 } 343 344 343 345 344 void addProjectEntry(inout EProjectEntry pe, bool sort = true) … … 447 446 448 447 448 protected EProjectNode createFileNode(string name) 449 { 450 return new EProjectFileNode(name); 451 } 452 453 protected EProjectNode createDirNode(inout EProjectEntry pe, bool sorted) 454 { 455 return new EProjectDirNode(pe, sorted); 456 } 457 458 459 // Adds a list of files, but isn't necessarily a live dir listing. 449 460 TreeNode loadFileList(char[][] filters, bool sort = true) 450 461 { … … 459 470 //TreeNode tn = new EProjectHeaderNode(s); 460 471 EProjectEntry dpe; 472 dpe.project = project; 461 473 dpe.name = s; 462 TreeNode tn = new EProjectDirNode(dpe);474 TreeNode tn = createDirNode(dpe, sort); 463 475 if(sort) 464 476 nodes.add(tn); // Need to add it first so adding to it knows to sort. … … 478 490 479 491 480 // Only works for directory projects.481 void ensureFileAdded(char[] filepath)492 // This implementation works for directory projects by adding new files. 493 void fileOpened(char[] filepath) 482 494 { 483 495 EProjectDir pdir; … … 509 521 if(fn.length) 510 522 { 511 TreeNode nftn = new EProjectFileNode(filepath);523 TreeNode nftn = createFileNode(filepath); 512 524 tn.nodes.add(nftn); 513 525 tn.expand(); … … 520 532 } 521 533 } 522 } 523 534 535 } 536 trunk/win32/entice/design.d
r101 r102 1392 1392 1393 1393 this(char[] enumTypeName, char[][] enumValues, char[] value, int listX, int listY, int listWidth) 1394 in1395 1394 { 1396 1395 assert(enumValues.length); 1397 } 1398 body 1399 { 1396 1400 1397 lfmt = new TextFormat(TextFormatFlags.NO_PREFIX | TextFormatFlags.SINGLE_LINE 1401 1398 | TextFormatFlags.NO_CLIP | TextFormatFlags.LINE_LIMIT); … … 1532 1529 1533 1530 int r = right; 1534 int sr = Screen.primaryScreen.workingArea.right; 1531 //int sr = Screen.primaryScreen.workingArea.right; 1532 int sr = Screen.fromControl(listBox).workingArea.right; 1535 1533 if(r > sr) 1536 1534 left = left - (r - sr); trunk/win32/entice/designcontrol.d
r101 r102 750 750 return dControlSubSelected(dctrl, callback); 751 751 } 752 } 753 754 755 // if fromTopmost is true, uses dControlAllSelected, otherwise dControlSubSelected. 756 // Returns true if more than one design control is selected. 757 bool dControlMultipleSelected(IDesignControl dctrl, bool fromTopmost) 758 { 759 int count = 0; 760 761 762 bool callback(IDesignControlItem idci) 763 { 764 if(++count > 1) 765 return false; // Stop. 766 return true; // Continue. 767 } 768 769 770 if(fromTopmost) 771 dControlAllSelected(dctrl, &callback); 772 else 773 dControlSubSelected(dctrl, &callback); 774 return count > 1; 775 } 776 777 // if fromTopmost is true, uses dControlAllSelected, otherwise dControlSubSelected. 778 // Returns true if at least one design control is selected. 779 bool dControlAnySelected(IDesignControl dctrl, bool fromTopmost) 780 { 781 bool any = false; 782 783 784 bool callback(IDesignControlItem idci) 785 { 786 any = true; 787 return false; // Stop. 788 } 789 790 791 if(fromTopmost) 792 dControlAllSelected(dctrl, &callback); 793 else 794 dControlSubSelected(dctrl, &callback); 795 return any; 796 } 797 798 799 // if fromTopmost is true, uses dControlAllSelected, otherwise dControlSubSelected. 800 // Returns number of design controls selected. 801 int dControlCountSelected(IDesignControl dctrl, bool fromTopmost) 802 { 803 int count = 0; 804 805 806 bool callback(IDesignControlItem idci) 807 { 808 count++; 809 return true; // Continue. 810 } 811 812 813 if(fromTopmost) 814 dControlAllSelected(dctrl, &callback); 815 else 816 dControlSubSelected(dctrl, &callback); 817 return count; 752 818 } 753 819 … … 1165 1231 } 1166 1232 1167 dControlUpdateSelect(dctrl, true); 1233 bool clearOthers = true; 1234 bool setselected = true; 1235 version(ENTICE_MULTISEL) 1236 { 1237 if(Control.modifierKeys & Keys.CONTROL) 1238 { 1239 clearOthers = false; 1240 IDesignControlItem othersel = null; 1241 dControlAllSelected(dctrl, 1242 (IDesignControlItem idci) 1243 { 1244 if(idci is dctrl) 1245 { 1246 // Try to find one that's not this one. 1247 return true; // Continue. 1248 } 1249 othersel = idci; 1250 return false; // Break. 1251 }); 1252 if(othersel && dctrl.itemParent !is othersel.itemParent) 1253 { 1254 // Can't multi-sel if different parents. 1255 return; 1256 } 1257 if(dctrl.isItemSelected) 1258 { 1259 // If it's already selected, try to un-select, 1260 // but only if there are others selected. 1261 if(othersel) 1262 { 1263 assert(othersel !is dctrl); 1264 setselected = false; 1265 } 1266 } 1267 } 1268 } 1269 dControlUpdateSelect(dctrl, setselected, clearOthers); 1270 if(!setselected) 1271 return; 1168 1272 version(NOFOCUSDESIGNITEM) 1169 1273 { … … 1247 1351 else 1248 1352 { 1249 Rect r; 1250 dctrl.getItemBounds(r); 1251 r.x += dlastpt.x - dorigpt.x; 1252 r.y += dlastpt.y - dorigpt.y; 1253 dctrl.setItemBounds(r); 1353 int diffx = dlastpt.x - dorigpt.x; 1354 int diffy = dlastpt.y - dorigpt.y; 1355 version(ENTICE_MULTISEL) 1356 { 1357 IDesignControl dselscan = cast(IDesignControl)dctrl.itemParent; 1358 if(!dselscan) 1359 { 1360 dselscan = dctrl; 1361 } 1362 dControlSubSelected(dselscan, 1363 (IDesignControlItem idci) 1364 { 1365 Rect idciRect; 1366 idci.getItemBounds(idciRect); 1367 idciRect.x += diffx; 1368 idciRect.y += diffy; 1369 idci.setItemBounds(idciRect); 1370 return true; // Continue. 1371 }); 1372 } 1373 else 1374 { 1375 Rect r; 1376 dctrl.getItemBounds(r); 1377 r.x += diffx; 1378 r.y += diffy; 1379 dctrl.setItemBounds(r); 1380 } 1254 1381 } 1255 1382 } trunk/win32/entice/dfldesigner.d
r101 r102 8 8 std.date; 9 9 10 private import dfl.all, dfl. winapi, dfl.utf;10 private import dfl.all, dfl.internal.winapi, dfl.internal.utf; 11 11 private import dfl.scintilla, dfl.cpp.scintilla, dfl.cpp.scilexer; 12 12 13 13 import rgroup, rdflregistry, rini; 14 15 import promptbox; 14 16 15 17 private import winapi; … … 28 30 import waitmanager, dirchanges, plugins; 29 31 import projectmanager, ddprojectmanager; 32 import ddoptscompilerpanel; 30 33 version(ADVANCED_FIND) 31 34 import advfindpanel; 35 import compile; 36 import process; 32 37 33 38 … … 63 68 const char[] TITLE = "Entice Designer"; 64 69 const char[] SAVENAME = "Entice"; 65 const char[] VERSION = " X"; //"0.8.6pre4"; // Compiled with: (DMD 1.028) - (DFL 0.9.7+snapshot)70 const char[] VERSION = "0.8.6pre6"; // Compiled with: (DMD 1.060) - (DFL 0.9.8+snapshot) 66 71 const char[] FULLTITLE = TITLE ~ " " ~ VERSION; 67 const char[] COPYRIGHT_STRING_YEARS = "Copyright © 2004-20 08";72 const char[] COPYRIGHT_STRING_YEARS = "Copyright © 2004-2010"; 68 73 const char[] AUTHOR = "Christopher E. Miller"; 69 74 … … 136 141 bool reallyClosing = false; 137 142 bool apprun = false; 138 char[] localdir; // Usually AppData\Entice .143 char[] localdir; // Usually AppData\Entice 139 144 char[] configFilePath; 140 145 //bool killregstuff = false; … … 150 155 // To-do: get filter from registry, per-project, or fallback to global. 151 156 char[][] fileListFilter = ["*.d"[], "*.di", "*.txt", "*.bat", "*.c", "*.h", "*.cpp", "*.cxx", "*.hpp"]; 157 158 159 // Note: this can prompt a dialog or throw an exception. 160 void ensureCompiler(bool allowPrompt = true) 161 { 162 if(optDmdLocation.length <= 3 || dmdwindowsbindir.length <= 3) 163 { 164 if(allowPrompt) 165 { 166 if(mainForm !is null) 167 { 168 status("Please setup the compiler..."); 169 openCompilerConfig(); 170 } 171 } 172 173 if(optDmdLocation.length <= 3 || dmdwindowsbindir.length <= 3) 174 { 175 throw new Exception("Compiler not setup"); 176 } 177 178 assert(optDmdLocation.length > 0); 179 assert(dmdwindowsbindir.length > 0); 180 } 181 assert(optDmdLocation.length > 0); 182 assert(dmdwindowsbindir.length > 0); 183 } 184 185 bool isCompilerSetup() 186 { 187 if(optDmdLocation.length <= 3 || dmdwindowsbindir.length <= 3) 188 { 189 return false; 190 } 191 return true; 192 } 193 194 195 void openCompilerConfig() 196 { 197 mainForm.n(2207461002); // Compiler tab. 198 } 199 200 void openCompilerConfig(string setcompilerdir) 201 { 202 mainForm.n(2207461002, // Compiler tab. 203 (DdOptionsForm optsform) 204 { 205 int selidx = optsform.tabs.selectedIndex; 206 if(-1 != selidx) 207 { 208 auto ctab = cast(CompilerOptTab)optsform.tabs.tabs[selidx]; 209 if(ctab) 210 { 211 ctab.setDmdLocation(setcompilerdir); 212 } 213 } 214 }); 215 } 152 216 153 217 … … 306 370 307 371 void addEntity(Entity ent) 308 in309 372 { 310 373 assert(findEntity(ent) == -1); // That Entity was already added! 311 } 312 body 313 { 374 314 375 if(autoHideStartPage && !startPageClosed) 315 376 { … … 582 643 if(fp.length) 583 644 { 584 fp = dfl. utf.getFullPathName(fp);645 fp = dfl.internal.utf.getFullPathName(fp); 585 646 586 647 //filePath = fp; // Causes changes, not needed if file is closing. … … 634 695 635 696 CLOSE_ALL = 1, // Closes all tabs in this entity when just this tab is closed. 697 ALLOW_DETACH = 2, 636 698 } 637 699 … … 662 724 663 725 664 this(Entity ent, char[] text )665 { 666 super(text );726 this(Entity ent, char[] text, bool detached = false) 727 { 728 super(text, detached); 667 729 668 730 ent.etabs ~= this; … … 795 857 796 858 859 //@ 797 860 void _tsApply() 798 861 { … … 1178 1241 1179 1242 1243 // returns true if handled. 1244 // line won't be escaped. 1245 bool doubleclickedStatusOpenFile(string line) 1246 { 1247 if(mainForm) 1248 { 1249 size_t iw; 1250 size_t lparen = 0, rparen = 0, colon = 0; 1251 for(iw = 0; iw < line.length; iw++) 1252 { 1253 if('(' == line[iw]) 1254 { 1255 lparen = iw; 1256 rparen = 0; 1257 } 1258 else if(')' == line[iw]) 1259 { 1260 if(lparen) 1261 rparen = iw; 1262 } 1263 else if(':' == line[iw] && iw > 1) 1264 { 1265 string fn; 1266 uint linnum; 1267 if(lparen && rparen) 1268 { 1269 fn = line[0 .. lparen]; 1270 try 1271 { 1272 linnum = std.conv.toUint(line[lparen + 1 .. rparen]); 1273 } 1274 catch 1275 { 1276 } 1277 } 1278 else if(colon) 1279 { 1280 fn = line[0 .. colon]; 1281 } 1282 else 1283 { 1284 break; 1285 } 1286 fn = fn.dup; 1287 1288 auto altdown = Control.modifierKeys & Keys.ALT; 1289 1290 if(mainForm) 1291 { 1292 EditorTab etab; 1293 1294 mainForm.doOpen(fn, true); // wantEditor = true 1295 etab = cast(EditorTab)getCurrentTab(); 1296 if(!etab) 1297 break; 1298 //if(etab is this) 1299 // break; 1300 1301 if(linnum) 1302 { 1303 Application.doEvents(); 1304 if(altdown) 1305 { 1306 //EditorTab etab = cast(EditorTab)getCurrentTab(); 1307 //if(etab) 1308 { 1309 etab.switchToOppositeView(); 1310 Application.doEvents(); // ! 1311 } 1312 } 1313 mainForm.doGotoLine(etab.asci, linnum); 1314 //Application.doEvents(); 1315 //etab.asci.select(); 1316 etab.asci.delayInvoke( 1317 function(Control cc, size_t[] params) 1318 { 1319 cc.select(); 1320 }, null); 1321 } 1322 } 1323 1324 break; 1325 } 1326 } 1327 } 1328 return false; 1329 } 1330 1331 1180 1332 class ModalBox: TextBox 1181 1333 { … … 2207 2359 // If a file is already being notified of changes, it is removed in favor of the new one. 2208 2360 final void notifyChanges(char[] filepath) 2209 in2210 2361 { 2211 2362 assert(std.path.isabs(filepath) || r"\\" == filepath[0 .. 2]); 2212 } 2213 body 2214 { 2363 2215 2364 noNotifyChanges(); 2216 2365 … … 2219 2368 // Should it watch for FILE_NOTIFY_CHANGE_LAST_WRITE ? 2220 2369 // Note: ReadDirectoryChangesW() can tell you exactly what file/dir changed, but is only supported on NT+. 2221 hfchange = dfl. utf.findFirstChangeNotification(getDirName(filepath), FALSE,2370 hfchange = dfl.internal.utf.findFirstChangeNotification(getDirName(filepath), FALSE, 2222 2371 FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE); 2223 2372 if(INVALID_HANDLE_VALUE == hfchange) … … 2365 2514 try 2366 2515 { 2516 char[] ext = std.path.getExt(txt); 2367 2517 // To-do: cache this extension info... accessing this part of the registry is usually slow as hell. 2368 auto rk = Registry.classesRoot.openSubKey("." ~ std.path.getExt(txt));2518 auto rk = Registry.classesRoot.openSubKey("." ~ ext); 2369 2519 if(rk) 2370 2520 { … … 2382 2532 } 2383 2533 } 2534 if(!moreinfo.length) 2535 { 2536 switch(ext) 2537 { 2538 case "d": 2539 moreinfo = "D Source File"; 2540 break; 2541 case "di": 2542 moreinfo = "D Interface File"; 2543 break; 2544 case "lua", "java", "scala", "tcl": 2545 moreinfo = std.string.capitalize(ext) ~ " Source File"; 2546 break; 2547 case "c", "json", "xml", "vb", "php": 2548 moreinfo = std.string.toupper(ext) ~ " Source File"; 2549 break; 2550 case "cs": 2551 moreinfo = "C# Source File"; 2552 break; 2553 case "cpp": 2554 moreinfo = "C++ Source File"; 2555 break; 2556 case "rb": 2557 moreinfo = "Ruby Source File"; 2558 break; 2559 case "py": 2560 moreinfo = "Python Source File"; 2561 break; 2562 case "pl": 2563 moreinfo = "Perl Source File"; 2564 break; 2565 default: 2566 moreinfo = std.string.toupper(ext) ~ " File"; 2567 } 2568 } 2384 2569 } 2385 2570 catch(Object e) … … 2710 2895 2711 2896 2897 PropPanelTab[] designtabs = null; 2898 2899 2900 static class PropertiesPropPanelTab: PropPanelTab 2901 { 2902 this() 2903 { 2904 super("Properties"); 2905 } 2906 } 2907 2908 static class EventsPropPanelTab: PropPanelTab 2909 { 2910 this() 2911 { 2912 super("Events"); 2913 } 2914 } 2915 2916 2712 2917 override void onShow(Tabber tabc, int index) 2713 2918 { 2714 //_tsPropTabs = [ new PropPanelTab("Properties"), new PropPanelTab("Events") ]; 2919 /+if(designtabs is null) 2920 { 2921 designtabs = [ new PropertiesPropPanelTab(), new EventsPropPanelTab() ]; 2922 }+/ 2715 2923 _tsPropTabs = propTabs; 2924 //_tsPropTabs = designtabs; 2716 2925 2717 2926 super.onShow(tabc, index); … … 2764 2973 2765 2974 2766 private IDesignControlItem getSingleSelItem() 2767 { 2768 IDesignControlItem selItem; 2769 2770 bit onItem(IDesignControlItem idci) 2771 { 2772 if(idci.isItemSelected()) 2773 { 2774 if(selItem) // 2 items selected; abort whole thing. 2775 { 2776 selItem = null; 2777 return false; // Stop. 2778 } 2779 selItem = idci; 2780 } 2781 idci.getItems(&onItem); 2782 return true; // Continue. 2783 } 2784 2785 designControl.getItems(&onItem); 2786 return selItem; 2787 } 2788 2789 2790 private void doDelSelItem(IDesignControlItem selItem) 2791 { 2792 selItem.itemDeleteKey(); // ? 2793 } 2794 2795 2796 private IDesignControlItem doCbSelItemCopy() 2797 { 2798 IDesignControlItem selItem; 2799 selItem = getSingleSelItem(); 2800 if(selItem) 2801 { 2802 char[] cpy, s, s2, s3; 2803 2804 char[] libname = selItem.getLibName(); 2805 2806 cpy = libname // Lib name. 2807 ~ "\r\nControl" // Type of design item. 2808 ~ "\r\n" ~ designControl.getDesignTypeName(); // Top-design item. 2809 2810 auto selparent = selItem.itemParent(); 2811 if(selparent) 2812 { 2813 s = selparent.getDesignTypeName(); 2814 s2 = selparent.getOtherDesignTypeName(); 2975 private void doSelItemsDelete() 2976 { 2977 if(designControl) 2978 { 2979 // Just send the delete key to any one, 2980 // it'll delete all selected. 2981 designControl.itemDeleteKey(); 2982 } 2983 } 2984 2985 2986 private void doCbSelItemsCopy() 2987 { 2988 if(!designControl) 2989 return; 2990 char[] libname = designControl.getLibName(); 2991 char[] cpy = libname // Lib name. 2992 ~ "\r\nControl" // Type of design item. 2993 ~ "\r\n" ~ designControl.getDesignTypeName(); // Top-design item. 2994 int numselected = 0; 2995 dControlSubSelected(designControl, 2996 (IDesignControlItem selItem) 2997 { 2998 if(selItem is designControl) 2999 { 3000 return true; // Continue. 3001 } 3002 numselected++; 3003 3004 char[] s, s2, s3; 3005 3006 auto selparent = selItem.itemParent(); 3007 3008 if(numselected == 1) 3009 { 3010 if(selparent) 3011 { 3012 s = selparent.getDesignTypeName(); 3013 s2 = selparent.getOtherDesignTypeName(); 3014 if(s != s2) 3015 s = s2 ~ ":" ~ s; 3016 cpy ~= "\r\n" ~ s; // Copied item's parent type. 3017 } 3018 else 3019 { 3020 cpy ~= "\r\n"; // Shouldn't happen... 3021 } 3022 3023 cpy ~= "\r\n-"; // Separator. 3024 } 3025 3026 s = selItem.getDesignTypeName(); 3027 s2 = selItem.getOtherDesignTypeName(); 2815 3028 if(s != s2) 2816 3029 s = s2 ~ ":" ~ s; 2817 cpy ~= "\r\n" ~ s; // Copied item's parent type. 2818 } 2819 else 2820 { 2821 cpy ~= "\r\n"; // Shouldn't happen... 2822 } 2823 2824 cpy ~= "\r\n-"; // Separator. 2825 2826 s = selItem.getDesignTypeName(); 2827 s2 = selItem.getOtherDesignTypeName(); 2828 if(s != s2) 2829 s = s2 ~ ":" ~ s; 2830 s3 = selItem.getMoreTypeInfo(); 2831 if(s3.length) 2832 s = s ~ " " ~ s3; 2833 cpy ~= "\r\n" ~ s; // Copied item's type. 2834 2835 selItem.foreachPropSave( 2836 (char[] saveString) 2837 { 2838 cpy ~= "\r\n" ~ saveString; // Item properties. 2839 }, null); 2840 2841 /+ 2842 selItem.getItems( 2843 (IDesignControlItem onItem) 2844 { 2845 2846 return true; // Continue. 2847 }); 2848 +/ 2849 2850 cpy ~= "\r\n-"; // Separator. 2851 3030 s3 = selItem.getMoreTypeInfo(); 3031 if(s3.length) 3032 s = s ~ " " ~ s3; 3033 cpy ~= "\r\n" ~ s; // Copied item's type. 3034 3035 selItem.foreachPropSave( 3036 (char[] saveString) 3037 { 3038 cpy ~= "\r\n" ~ saveString; // Item properties. 3039 }, null); 3040 3041 /+ 3042 selItem.getItems( 3043 (IDesignControlItem onItem) 3044 { 3045 3046 return true; // Continue. 3047 }); 3048 +/ 3049 3050 cpy ~= "\r\n-"; // Separator. 3051 3052 return true; // Continue. 3053 }); 3054 if(numselected) 3055 { 2852 3056 DataObject clp = new DataObject; 2853 3057 clp.setData(CLIPBOARD_FORMAT, Data(cpy)); 3058 //clp.setData(dfl.data.DataFormats.text, Data(cpy)); // Testing. 2854 3059 Clipboard.setDataObject(clp); 2855 3060 } 2856 return selItem;2857 3061 } 2858 3062 … … 2860 3064 private void menu_editCut() 2861 3065 { 2862 IDesignControlItem selItem; 2863 selItem = doCbSelItemCopy(); 2864 if(selItem) 2865 { 2866 doDelSelItem(selItem); 2867 } 3066 doCbSelItemsCopy(); 3067 doSelItemsDelete(); 2868 3068 } 2869 3069 … … 2871 3071 private void menu_editCopy() 2872 3072 { 2873 doCbSelItem Copy();3073 doCbSelItemsCopy(); 2874 3074 } 2875 3075 … … 2892 3092 name = "button1"; 2893 3093 text = "OK"; 2894 bounds = dfl. base.Rect(168, 216, 75, 23);3094 bounds = dfl.all.Rect(168, 216, 75, 23); 2895 3095 - 2896 3096 … … 2906 3106 backColor = dfl.drawing.Color(0, 164, 0); 2907 3107 dock = dfl.control.DockStyle.FILL; 2908 bounds = dfl. base.Rect(4, 23, 192, 73);3108 bounds = dfl.all.Rect(4, 23, 192, 73); 2909 3109 - 2910 3110 +/ … … 2940 3140 return false; 2941 3141 2942 IDesignControlItem selItem; 2943 selItem = getSingleSelItem(); 2944 if(!selItem) 2945 { 2946 //msgBox("Cannot determine where to paste"); 2947 //return true; 2948 selItem = designControl; 2949 } 3142 IDesignControlItem selItem = designControl; 3143 dControlSubSelected(designControl, 3144 (IDesignControlItem idci) 3145 { 3146 if(selItem) 3147 { 3148 // If more than one selected, use their parent. 3149 selItem = selItem.itemParent; 3150 if(!selItem) 3151 selItem = designControl; 3152 return false; // Break. 3153 } 3154 selItem = idci; 3155 return true; // Continue. 3156 }); 2950 3157 2951 3158 IDesignControl dctrlSel; … … 2959 3166 { 2960 3167 huh: 2961 //msgBox("Cannot determine where to paste");2962 //return true;2963 3168 selItem = designControl; 2964 3169 break; … … 3028 3233 goto no_info; 3029 3234 3030 Control nc; 3031 Token tok; 3032 Token[] toks = new Token[2]; 3033 toks[0].type = TokenType.IDENT; 3034 toks[0].str = "_paste"; 3035 toks[1].type = TokenType.DOT; 3036 toks[1].str = "."; 3037 char[] tname, fcname; 3038 Parser par = new Parser("Paste", null); 3039 for(++iw; iw != plines.length; iw++) 3040 { 3041 if(!tname.length) 3042 { 3043 tname = plines[iw]; 3044 3045 int i; 3046 3047 char[] moreTypeInfo = null; 3048 i = std.string.find(tname, ' '); 3049 if(-1 != i) 3050 { 3051 moreTypeInfo = tname[i + 1 .. $]; 3052 tname = tname[0 .. i]; 3053 } 3054 3055 i = std.string.find(tname, ':'); 3056 bool by; 3057 if(-1 == i) 3058 by = op.onSubItem(libname, tname, tname, moreTypeInfo, "Pasted" ~ getIdentifier(tname)); 3235 int numpasted = 0; 3236 paste_all: 3237 while(iw < plines.length) 3238 { 3239 Control nc; 3240 Token tok; 3241 Token[] toks = new Token[2]; 3242 toks[0].type = TokenType.IDENT; 3243 toks[0].str = "_paste"; 3244 toks[1].type = TokenType.DOT; 3245 toks[1].str = "."; 3246 char[] tname, fcname; 3247 Parser par = new Parser("Paste", null); 3248 for(++iw;; iw++) 3249 { 3250 if(iw >= plines.length) 3251 break; 3252 if(!tname.length) 3253 { 3254 tname = plines[iw]; 3255 3256 int i; 3257 3258 char[] moreTypeInfo = null; 3259 i = std.string.find(tname, ' '); 3260 if(-1 != i) 3261 { 3262 moreTypeInfo = tname[i + 1 .. $]; 3263 tname = tname[0 .. i]; 3264 } 3265 3266 i = std.string.find(tname, ':'); 3267 bool by; 3268 if(-1 == i) 3269 by = op.onSubItem(libname, tname, tname, moreTypeInfo, "Pasted" ~ getIdentifier(tname)); 3270 else 3271 by = op.onSubItem(libname, tname[i + 1 .. tname.length], tname[0 .. i], moreTypeInfo, "Pasted" ~ getIdentifier(tname[0 .. i])); 3272 if(!by) 3273 { 3274 msgBox("Unable to paste unknown design item"); 3275 return true; 3276 } 3277 3278 nc = op.dctrl; 3279 nc.visible = false; 3280 nc.parent = selDfl.getControl(); 3281 } 3059 3282 else 3060 by = op.onSubItem(libname, tname[i + 1 .. tname.length], tname[0 .. i], moreTypeInfo, "Pasted" ~ getIdentifier(tname[0 .. i])); 3061 if(!by) 3062 { 3063 msgBox("Unable to paste unknown design item"); 3064 return true; 3065 } 3066 3067 nc = op.dctrl; 3068 nc.visible = false; 3069 nc.parent = selDfl.getControl(); 3070 } 3071 else 3072 { 3073 if("-" == plines[iw]) 3074 break; 3075 3076 par.reset(); 3077 par.source = plines[iw]; 3078 3079 toks = toks[0 .. 2]; 3080 for(;;) 3081 { 3082 par.getToken(tok); 3083 if(TokenType.EOF == tok.type || TokenType.EOS == tok.type) 3283 { 3284 if("-" == plines[iw]) 3084 3285 break; 3085 toks ~= tok;3086 }3087 3088 if(toks.length)3089 {3090 switch(toks[2].str)3286 3287 par.reset(); 3288 par.source = plines[iw]; 3289 3290 toks = toks[0 .. 2]; 3291 for(;;) 3091 3292 { 3092 case "name":3093 fcname = toks[4].str;3293 par.getToken(tok); 3294 if(TokenType.EOF == tok.type || TokenType.EOS == tok.type) 3094 3295 break; 3095 3096 case "dock": 3097 //case "bounds", "size", "clientSize", "location": 3098 break; 3099 3100 default: ; 3101 if(toks[2].str.length && toks[2].str[0] != '@') // Ones starting with @ are special for forward compatible. 3102 { 3103 op.onSubItemPropTokens(toks); 3104 } 3296 toks ~= tok; 3105 3297 } 3106 } 3107 } 3108 } 3109 3110 if(nc) 3111 { 3112 //if(pasteX >= int.max && pasteY >= int.max) 3113 if(pasteX >= short.max && pasteY >= short.max) 3114 { 3115 pasteX = nc.left; 3116 pasteY = nc.top; 3117 } 3118 3119 int postries = 0; 3120 //bool atzero; 3121 bool samepos; 3122 trythispos: 3123 //atzero = false; 3124 samepos = false; 3125 selItem.getItems( 3126 (IDesignControlItem idci) 3127 { 3128 if(idci != cast(IDesignControlItem)op.idctrl) 3298 3299 if(toks.length) 3129 3300 { 3130 Rect sr; 3131 idci.getItemBounds(sr); 3132 /+ 3133 if(sr.x < 16 && sr.y < 16 3134 && sr.x >= -16 && sr.y >= -16) 3135 atzero = true; 3136 +/ 3137 if(sr.x < pasteX + 16 && sr.y < pasteY + 16 3138 && sr.x > pasteX - 16 && sr.y > pasteY - 16) 3139 samepos = true; 3140 if(/+ atzero && +/ samepos) 3141 return false; // Stop. 3142 } 3143 return true; // Continue. 3144 }); 3145 int j = gridSize; 3146 if(j <= 0) // Shouldn't happen. 3147 j = 1; 3148 if(samepos) 3149 { 3150 /+if(atzero) 3151 { 3152 } 3153 else+/ 3154 { 3155 //nc.location = Point(pasteX, pasteY); 3156 if(isGridValueDisabled(gridSize)) 3157 { 3158 pasteX += 24; 3159 pasteY += 24; 3160 } 3161 else 3162 { 3163 int _x = pasteX + 24, _y = pasteY + 24; 3164 while(pasteX < _x) 3301 switch(toks[2].str) 3165 3302 { 3166 pasteX += j; 3167 } 3168 while(pasteY < _y) 3169 { 3170 pasteY += j; 3303 case "name": 3304 fcname = toks[4].str; 3305 break; 3306 3307 case "dock": 3308 //case "bounds", "size", "clientSize", "location": 3309 break; 3310 3311 default: ; 3312 if(toks[2].str.length && toks[2].str[0] != '@') // Ones starting with @ are special for forward compatible. 3313 { 3314 op.onSubItemPropTokens(toks); 3315 } 3171 3316 } 3172 3317 } 3173 3318 } 3319 } 3320 3321 if(nc) 3322 { 3323 //if(pasteX >= int.max && pasteY >= int.max) 3324 if(pasteX >= short.max && pasteY >= short.max) 3325 { 3326 pasteX = nc.left; 3327 pasteY = nc.top; 3328 } 3174 3329 3175 if(++postries < 32) 3176 goto trythispos; 3177 } 3178 Rect cr; 3179 selItem.getItemBounds(cr); 3180 if(pasteX > cr.width - nc.width || pasteY > cr.height - nc.width) 3181 { 3182 //pasteX = 0; 3183 //pasteY = 0; 3184 int px = pasteX - j, py = pasteY - j; 3185 pasteX -= j << 1; 3186 pasteY -= j << 1; 3187 for(;;) 3188 { 3189 if(pasteX < 0) 3330 int postries = 0; 3331 //bool atzero; 3332 bool samepos; 3333 trythispos: 3334 //atzero = false; 3335 samepos = false; 3336 selItem.getItems( 3337 (IDesignControlItem idci) 3190 3338 { 3339 if(idci != cast(IDesignControlItem)op.idctrl) 3340 { 3341 Rect sr; 3342 idci.getItemBounds(sr); 3343 /+ 3344 if(sr.x < 16 && sr.y < 16 3345 && sr.x >= -16 && sr.y >= -16) 3346 atzero = true; 3347 +/ 3348 if(sr.x < pasteX + 16 && sr.y < pasteY + 16 3349 && sr.x > pasteX - 16 && sr.y > pasteY - 16) 3350 samepos = true; 3351 if(/+ atzero && +/ samepos) 3352 return false; // Stop. 3353 } 3354 return true; // Continue. 3355 }); 3356 int j = gridSize; 3357 if(j <= 0) // Shouldn't happen. 3358 j = 1; 3359 if(samepos) 3360 { 3361 /+if(atzero) 3362 { 3363 } 3364 else+/ 3365 { 3366 //nc.location = Point(pasteX, pasteY); 3367 if(isGridValueDisabled(gridSize)) 3368 { 3369 pasteX += 24; 3370 pasteY += 24; 3371 } 3372 else 3373 { 3374 int _x = pasteX + 24, _y = pasteY + 24; 3375 while(pasteX < _x) 3376 { 3377 pasteX += j; 3378 } 3379 while(pasteY < _y) 3380 { 3381 pasteY += j; 3382 } 3383 } 3384 } 3385 3386 if(++postries < 32) 3387 goto trythispos; 3388 } 3389 Rect cr; 3390 selItem.getItemBounds(cr); 3391 if(pasteX > cr.width - nc.width || pasteY > cr.height - nc.width) 3392 { 3393 //pasteX = 0; 3394 //pasteY = 0; 3395 int px = pasteX - j, py = pasteY - j; 3396 pasteX -= j << 1; 3397 pasteY -= j << 1; 3398 for(;;) 3399 { 3400 if(pasteX < 0) 3401 { 3402 if(pasteY < 0) 3403 { 3404 pasteX = px; 3405 pasteY = py; 3406 break; 3407 } 3408 py = pasteY; 3409 pasteY -= j; 3410 continue; 3411 } 3191 3412 if(pasteY < 0) 3192 3413 { 3193 p asteX = px;3194 paste Y = py;3195 break;3414 px = pasteX; 3415 pasteX -= j; 3416 continue; 3196 3417 } 3418 px = pasteX; 3197 3419 py = pasteY; 3420 pasteX -= j; 3198 3421 pasteY -= j; 3199 continue;3200 3422 } 3201 if(pasteY < 0) 3202 { 3203 px = pasteX; 3204 pasteX -= j; 3205 continue; 3206 } 3207 px = pasteX; 3208 py = pasteY; 3209 pasteX -= j; 3210 pasteY -= j; 3423 3424 if(++postries < 32) 3425 goto trythispos; 3426 } 3427 if(pasteX < 0) 3428 { 3429 pasteX = 0; 3430 } 3431 if(pasteY < 0) 3432 { 3433 pasteY = 0; 3434 } 3435 if(nc.left != pasteX || nc.top != pasteY) 3436 { 3437 //nc.location = Point(pasteX, pasteY); 3438 Prop pprop; 3439 pprop = op.pbox.props.findProp("left"); 3440 if(pprop) 3441 pprop.value = std.string.toString(pasteX); 3442 pprop = op.pbox.props.findProp("top"); 3443 if(pprop) 3444 pprop.value = std.string.toString(pasteY); 3211 3445 } 3212 3446 3213 if(++postries < 32) 3214 goto trythispos; 3215 } 3216 if(nc.left != pasteX || nc.top != pasteY) 3217 { 3218 //nc.location = Point(pasteX, pasteY); 3219 Prop pprop; 3220 pprop = op.pbox.props.findProp("left"); 3221 if(pprop) 3222 pprop.value = std.string.toString(pasteX); 3223 pprop = op.pbox.props.findProp("top"); 3224 if(pprop) 3225 pprop.value = std.string.toString(pasteY); 3226 } 3227 3228 IdentProp idprop = cast(IdentProp)op.pbox.props.findProp(PropCollection.OBJECT_NAME_PROP_NAME); 3229 if(idprop) 3230 { 3231 if(!isValidIdentifier(fcname) || idprop.isIdentInUse(fcname)) 3232 fcname = op.idctrl.getUniqueName(); 3447 IdentProp idprop = cast(IdentProp)op.pbox.props.findProp(PropCollection.OBJECT_NAME_PROP_NAME); 3448 if(idprop) 3449 { 3450 if(!isValidIdentifier(fcname) || idprop.isIdentInUse(fcname)) 3451 fcname = op.idctrl.getUniqueName(); 3452 3453 idprop.value = fcname; 3454 } 3233 3455 3234 idprop.value = fcname; 3235 } 3236 3456 nc.visible = true; 3457 version(NOFOCUSDESIGNITEM) 3458 { 3459 } 3460 else 3461 { 3462 nc.focus(); 3463 } 3464 numpasted++; 3465 dControlUpdateSelect(op.idctrl, true, numpasted == 1); 3466 } 3467 } 3468 if(numpasted) 3469 { 3237 3470 op.onEnd(); 3238 nc.visible = true;3239 version(NOFOCUSDESIGNITEM)3240 {3241 }3242 else3243 {3244 nc.focus();3245 }3246 dControlUpdateSelect(op.idctrl, true);3247 3248 3471 updateVariableNames(this); 3249 3472 regenDesignSource(this); 3250 3251 3473 return true; 3252 3474 } 3475 return false; 3253 3476 } 3254 3477 … … 3256 3479 private void menu_editDelete() 3257 3480 { 3258 IDesignControlItem selItem; 3259 selItem = getSingleSelItem(); 3260 if(selItem) 3261 { 3262 doDelSelItem(selItem); 3263 } 3481 doSelItemsDelete(); 3264 3482 } 3265 3483 … … 4809 5027 auto tlen = statusBox.textLength; 4810 5028 4811 if(tlen > 1024 * 2) 5029 //if(tlen > 1024 * 2) 5030 if(tlen > 1024 * 8) 4812 5031 { 4813 5032 try … … 4823 5042 4824 5043 if(tlen) 4825 statusBox.appendText( \r\n);5044 statusBox.appendText("\r\n"); 4826 5045 statusBox.selectedText = s; 4827 5046 } … … 4839 5058 statusBox.clear(); 4840 5059 } 5060 _morestatus = null; 4841 5061 } 4842 5062 … … 4845 5065 { 4846 5066 status("Error: " ~ errmsg); 5067 } 5068 5069 5070 private string[] _morestatus; 5071 private TextBox _morestatusview = null; 5072 private int _morestatusviewidx = -1; 5073 5074 void moreStatusStart() 5075 { 5076 _morestatus ~= ""; 5077 if(_morestatus.length > 1) 5078 status(" (double-click for more) " ~ std.string.toString(_morestatus.length)); 5079 else 5080 status(" (double-click for more)"); 5081 } 5082 5083 void moreStatus(string s) 5084 { 5085 if(_morestatus.length) 5086 { 5087 if(_morestatus[$ - 1].length) 5088 { 5089 _morestatus[$ - 1] ~= "\r\n"; 5090 if(_morestatusview !is null && _morestatusviewidx == _morestatus.length - 1) 5091 _morestatusview.appendText("\r\n"); 5092 } 5093 _morestatus[$ - 1] ~= s; 5094 if(_morestatusview !is null && _morestatusviewidx == _morestatus.length - 1) 5095 _morestatusview.appendText(s); 5096 } 5097 } 5098 5099 private struct _morestatusform_info 5100 { 5101 void _morestatusform_closed(Object sender, EventArgs ea) 5102 { 5103 _morestatusview = null; 5104 _morestatusviewidx = -1; 5105 } 5106 } 5107 private _morestatusform_info i_morestatusform_info; 5108 5109 void showMoreStatus(int idx) 5110 { 5111 _morestatusviewidx = idx; 5112 if(_morestatusview !is null) 5113 { 5114 _morestatusview.focus(); 5115 } 5116 else 5117 { 5118 Form f = new Form(); 5119 f.closed ~= &i_morestatusform_info._morestatusform_closed; 5120 f.font = new Font("Courier New", 11); 5121 f.size = Size(450, 340); 5122 f.text = "More Status"; 5123 f.showInTaskbar = false; 5124 f.startPosition = FormStartPosition.CENTER_PARENT; 5125 f.owner = mainForm; 5126 _morestatusview = new TextBox(); 5127 _morestatusview.scrollBars = ScrollBars.VERTICAL; 5128 _morestatusview.multiline = true; 5129 _morestatusview.readOnly = true; 5130 _morestatusview.dock = DockStyle.FILL; 5131 _morestatusview.parent = f; 5132 f.show(); 5133 } 5134 _morestatusview.text = _morestatus[idx]; 5135 } 5136 5137 bool doubleclickedStatusMoreStatus(string ln) 5138 { 5139 if(-1 != std.string.find(ln, "(double-click for more)")) 5140 { 5141 string snum = std.string.strip(ln[std.string.rfind(ln, ')') + 1 .. $]); 5142 ushort idx = 0; 5143 if(snum.length) 5144 { 5145 try 5146 { 5147 idx = std.conv.toUshort(snum) - 1; 5148 } 5149 catch 5150 { 5151 return false; 5152 } 5153 } 5154 if(idx >= _morestatus.length) 5155 return false; 5156 showMoreStatus(idx); 5157 return true; 5158 } 5159 return false; 4847 5160 } 4848 5161 … … 5362 5675 parent = propHolder; 5363 5676 5677 alignment = TabberAlignment.BOTTOM; 5678 5364 5679 //addTab(new Tab("Entice")); // Testing. 5365 5680 } … … 5408 5723 5409 5724 doubleClick ~= &statusBox_doubleClick; 5725 //mouseUp ~= &statusBox_mouseUp; 5410 5726 } 5411 5727 } … … 6007 6323 addShortcut(Keys.SHIFT | Keys.F2, &shortcut_shiftF2); 6008 6324 addShortcut(Keys.CONTROL | Keys.F2, &shortcut_ctrlF2); 6325 6326 addShortcut(Keys.CONTROL | Keys.OEM_CLOSE_BRACKETS, &shortcut_ctrlRightBracket); 6327 6009 6328 } 6010 6329 … … 6012 6331 void loadMainFormInitValues() 6013 6332 { 6333 auto rkey = getRkey(); 6014 6334 int xi; 6015 auto rkey = getRkey(); 6016 6017 // Set the window bounds. Try to load from registry. 6018 xi = rkey.getEntryInt("X", -1); 6019 if(-1 == xi) 6020 { 6021 // Bounds not in registry. 6022 6023 /+ 6024 // Let windows set it. 6025 startPosition = FormStartPosition.WINDOWS_DEFAULT_BOUNDS; 6026 +/ 6027 6028 // Set the bounds to something a bit bigger. 6029 //startPosition = FormStartPosition.CENTER_SCREEN; 6030 RECT workArea; 6031 if(SystemParametersInfoA(SPI_GETWORKAREA, 0, &workArea, 0)) 6032 { 6335 6336 { 6337 startPosition = FormStartPosition.MANUAL; 6338 // Set the window bounds. Try to load from config. 6339 xi = rkey.getEntryInt("X", -111111111); 6340 bool needdefbounds = true; 6341 Rect workArea; 6342 if(-111111111 == xi) 6343 { 6344 workArea = Screen.primaryScreen.workingArea; 6345 } 6346 else 6347 { 6348 // Bounds in config. 6349 { 6350 int cX, cY, cDX, cDY; 6351 cX = xi; 6352 cY = rkey.getEntryInt("Y", -1); 6353 cDX = rkey.getEntryInt("DX", -1); 6354 cDY = rkey.getEntryInt("DY", -1); 6355 bounds = Rect(cX, cY, cDX, cDY); 6356 } 6357 workArea = Screen.fromRectangle(bounds).workingArea; 6358 if(workArea.contains(bounds)) 6359 { 6360 needdefbounds = false; 6361 } 6362 } 6363 if(needdefbounds) 6364 { 6365 assert(workArea.width && workArea.height); 6033 6366 int sw, sh; 6034 6367 6035 sw = workArea.right - workArea. left;6036 sh = workArea.bottom - workArea. top;6368 sw = workArea.right - workArea.x; 6369 sh = workArea.bottom - workArea.y; 6037 6370 6038 /+if(sw <= 800 || sh <= 600) 6039 { 6040 startPosition = FormStartPosition.WINDOWS_DEFAULT_BOUNDS; 6041 } 6042 else+/ 6043 { 6044 //width = sw - sw / 8; // Proportional gap. 6045 width = sw - sh / 8; // Same gap. 6046 height = sh - sh / 8; 6047 } 6371 //width = sw - sw / 8; // Proportional gap. 6372 width = sw - sh / 8; // Same gap. 6373 height = sh - sh / 8; 6048 6374 6049 6375 centerToScreen(); 6050 6376 } 6051 else6052 {6053 //startPosition = FormStartPosition.WINDOWS_DEFAULT_BOUNDS;6054 }6055 }6056 else6057 {6058 startPosition = FormStartPosition.MANUAL;6059 6060 left = xi;6061 xi = rkey.getEntryInt("Y", -1);6062 if(-1 != xi)6063 top = xi;6064 xi = rkey.getEntryInt("DX", -1);6065 if(-1 != xi && xi > width)6066 width = xi;6067 xi = rkey.getEntryInt("DY", -1);6068 if(-1 != xi && xi > height)6069 height = xi;6070 6377 } 6071 6378 … … 6452 6759 6453 6760 static ContextMenu cmTabDown; 6454 static MenuItem tmdExtendedPropsMenu, tmdSaveMenu, tmdSaveAsMenu; 6761 static MenuItem tmdExtendedPropsMenu, tmdSaveMenu, tmdSaveAsMenu, 6762 tmdDetachMenu; 6455 6763 6456 6764 … … 6458 6766 { 6459 6767 closeCurrent(); 6768 } 6769 6770 6771 private void tmdDetachMenu_click(Object sender, EventArgs ea) 6772 { 6773 int selidx = tabs.selectedIndex; 6774 if(-1 != selidx) 6775 tabs.detachTab(selidx); 6460 6776 } 6461 6777 … … 6502 6818 cmTabDown.menuItems.add(mi); 6503 6819 6820 /+ 6821 with(tmdDetachMenu = new MenuItem()) 6822 { 6823 text = "&Detach"; 6824 click ~= &tmdDetachMenu_click; 6825 } 6826 cmTabDown.menuItems.add(tmdDetachMenu); 6827 +/ 6828 6504 6829 with(mi = new MenuItem()) 6505 6830 { … … 6555 6880 byes = ent.canSave; 6556 6881 6882 if(tmdDetachMenu) 6883 tmdDetachMenu.enabled = et && (et.flags & ETabFlags.ALLOW_DETACH); 6557 6884 tmdSaveMenu.enabled = byes; 6558 6885 tmdSaveAsMenu.enabled = byes; 6559 6886 6560 6887 cmTabDown.show(tabs, tabs.pointToScreen(Point(ea.x, ea.y))); 6888 } 6889 else if(ea.button == MouseButtons.MIDDLE) 6890 { 6891 assert(ea.tab is getCurrentTab()); 6892 6893 closeCurrent(); 6561 6894 } 6562 6895 } … … 6731 7064 6732 7065 7066 bool _showingopts = false; 7067 6733 7068 // -tabshow- is the GID of the tab to show, or the index of the tab to show. 6734 final void n(uint32_t tabshow = 0) 6735 { 7069 final void n(uint32_t tabshow = 0, void delegate(DdOptionsForm) optsReady = null) 7070 { 7071 if(_showingopts) 7072 return; 6736 7073 DdOptionsForm foo; 6737 7074 with(foo = new DdOptionsForm) 6738 7075 { 7076 if(optsReady) 7077 foo.optionsReady = optsReady; 6739 7078 icon = this.icon; 6740 7079 tabFirstShow = tabshow; 7080 _showingopts = true; 6741 7081 showDialog(this); 7082 _showingopts = false; 6742 7083 dispose(); 6743 7084 } … … 6767 7108 foreach(inout ApiEntry onae; *an) 6768 7109 { 7110 if(onae.flags & ApiFlags.UNDOCUMENTED) // Skip undocumented ones. 7111 continue; 7112 if(onae.flags & ApiFlags.PRIVATE) // Skip private ones. 7113 continue; 6769 7114 if(onae.flags & ApiFlags.PACKAGE) // Skip package ones in this view (e.g. ControlSuperClass). 6770 7115 continue; … … 7173 7518 7174 7519 7520 private void shortcut_ctrlRightBracket(Object sender, FormShortcutEventArgs ea) 7521 { 7522 EditorTab etab; 7523 etab = cast(EditorTab)getCurrentTab(); 7524 if(etab) 7525 { 7526 int istart, iend; 7527 if(etab.asci.findBraceMatch(istart, iend)) 7528 { 7529 etab.asci.sendEditor(SCI_GOTOPOS, iend); 7530 } 7531 } 7532 } 7533 7534 7535 private void shortcut_F5(Object sender, FormShortcutEventArgs ea) 7536 { 7537 EditorTab etab; 7538 etab = cast(EditorTab)getCurrentTab(); 7539 if(etab) 7540 { 7541 msgBox("Debugger not enabled.\r\n" 7542 "Proceeding to compile and run without debugger...\r\n" 7543 "Use Ctrl+F5 next time to avoid attempting to use a debugger.\r\n"); 7544 shortcut_ctrlF5(sender, ea); 7545 } 7546 } 7547 7548 7549 private void shortcut_ctrlF5(Object sender, FormShortcutEventArgs ea) 7550 { 7551 // Compile and run without debugging... 7552 7553 EditorTab etab; 7554 etab = cast(EditorTab)getCurrentTab(); 7555 if(etab) 7556 { 7557 string fp = etab.entity.filePath; 7558 if(fp.length > 2 7559 && ".d" == fp[$ - 2 .. $]) 7560 { 7561 clearStatus(); 7562 7563 try 7564 { 7565 ensureCompiler(); 7566 7567 //status("Building..."); 7568 status("Building current file without project..."); 7569 7570 //Process cproc = callCompilerWithSc("-c -o- -deps=con " ~ fp); 7571 Process cproc = callCompilerWithSc(fp); 7572 int nlines = 0; 7573 while(!cproc.stdout.eof()) 7574 { 7575 string ln = std.string.strip(cproc.stdout.readLine()); 7576 if(ln.length) 7577 { 7578 if(nlines < 10) 7579 { 7580 status(ln); 7581 } 7582 else 7583 { 7584 if(10 == nlines) 7585 moreStatusStart(); 7586 moreStatus(ln); 7587 } 7588 nlines++; 7589 } 7590 } 7591 cproc.waitForExit(); 7592 cproc.stdout.close(); 7593 { 7594 int status = cproc.exitCode; 7595 if(0 != status) 7596 throw new Exception("Returned status code " 7597 ~ std.string.toString(status)); 7598 } 7599 cproc.close(); 7600 status("Compiled successfully"); 7601 } 7602 catch(Exception e) 7603 { 7604 status("Compile error: " ~ e.toString()); 7605 } 7606 7607 doDelayGc(); 7608 7609 } 7610 } 7611 } 7612 7613 7175 7614 private void shortcut_ctrlSpace(Object sender, FormShortcutEventArgs ea) 7176 7615 { … … 7352 7791 for(;;) 7353 7792 { 7354 //if(!dfl. utf.getMessage(&msg, null, 0, 0)) // Makes it not work right..7793 //if(!dfl.internal.utf.getMessage(&msg, null, 0, 0)) // Makes it not work right.. 7355 7794 if(!GetMessageA(&msg, null, 0, 0)) 7356 7795 break; … … 7359 7798 { 7360 7799 TranslateMessage(&msg); 7361 dfl. utf.dispatchMessage(&msg);7800 dfl.internal.utf.dispatchMessage(&msg); 7362 7801 break; 7363 7802 } … … 7410 7849 default: process_msg: 7411 7850 //TranslateMessage(&msg); // No need. 7412 dfl. utf.dispatchMessage(&msg);7851 dfl.internal.utf.dispatchMessage(&msg); 7413 7852 } 7414 7853 } … … 7523 7962 //msgBox(`"` ~ dclickedLineString ~ `"`, "dclickedLineString"); 7524 7963 7525 firePluginEvent!(PluginEventProc_str_int, PluginEventIgnoreResult, char*, int) 7526 (PluginEventType.OUTPUTDCLICK, dclickedLineString.ptr, dclickedLineString.length); 7527 } 7528 } 7529 } 7964 if(!doubleclickedStatusOpenFile(dclickedLineString) 7965 && !doubleclickedStatusMoreStatus(dclickedLineString)) 7966 { 7967 firePluginEvent!(PluginEventProc_str_int, PluginEventIgnoreResult, char*, int) 7968 (PluginEventType.OUTPUTDCLICK, dclickedLineString.ptr, dclickedLineString.length); 7969 } 7970 } 7971 } 7972 } 7973 7974 7975 /+ 7976 private void statusBox_mouseUp(Control sender, MouseEventArgs ea) 7977 { 7978 if(ea.button == MouseButtons.LEFT) 7979 { 7980 if(statusBox.selectionLength < 1) 7981 { 7982 int selstart = statusBox.selectionStart; 7983 if(selstart >= 0) 7984 { 7985 auto line0idx = statusBox.getLineFromCharIndex(selstart); // 0 based. 7986 auto lines = statusBox.lines; 7987 if(line0idx < lines.length) 7988 { 7989 auto lineString = lines[line0idx]; 7990 statusBox.select(statusBox.getFirstCharIndexFromLine(line0idx), 7991 lineString.length); 7992 } 7993 } 7994 } 7995 } 7996 } 7997 +/ 7530 7998 7531 7999 … … 7824 8292 if(filepath.length) 7825 8293 { 7826 filepath = dfl. utf.getFullPathName(filepath);8294 filepath = dfl.internal.utf.getFullPathName(filepath); 7827 8295 7828 8296 if(!std.string.icmp(ent.filePath, filepath)) // Required with below already-open check. … … 7922 8390 7923 8391 curi = tabs.selectedIndex; 8392 if(-1 == curi) 8393 { 8394 if(tabs.tabs.length) 8395 { 8396 //tabs.attachTab(0); 8397 curi = 0; 8398 } 8399 } 7924 8400 if(-1 != curi) 7925 8401 { … … 7965 8441 final void doOpen(char[] filepath, bool wantEditor = false) 7966 8442 { 7967 filepath = dfl. utf.getFullPathName(filepath);8443 filepath = dfl.internal.utf.getFullPathName(filepath); 7968 8444 7969 8445 if(!canAddEntity()) … … 8198 8674 if(proj) // Should always be true. 8199 8675 { 8200 proj. ensureFileAdded(filepath);8676 proj.fileOpened(filepath); 8201 8677 } 8202 8678 … … 8315 8791 { 8316 8792 if(!canAddEntity()) 8317 return false; 8793 // return false; 8794 return; 8318 8795 8319 8796 char[] itemtype; … … 8624 9101 { 8625 9102 Application.doEvents(); // ? 8626 proj. ensureFileAdded(filepath);9103 proj.fileOpened(filepath); 8627 9104 } 8628 9105 … … 8658 9135 { 8659 9136 if(!canAddEntity()) 8660 return false; 9137 // return false; 9138 return; 8661 9139 8662 9140 auto ent = new Entity(Entity.UNTITLED); … … 8807 9285 8808 9286 8809 package static void tellPluginsLoaded() 8810 { 8811 if(anyPlugins()) 8812 { 8813 //delayInvoke(function(Control ctrl, size_t[] params) { signalPluginsLoaded(); }); 8814 signalPluginsLoaded(); 9287 // Calls the plugins' "loaded"! 9288 // This handles 'default' plugins, etc. 9289 // and conflicting features. 9290 package static void finishPluginsLoaded() 9291 { 9292 //if(anyPlugins()) // Always going to be some due to built-in ones. 9293 { 9294 //signalPluginsLoaded(); 9295 _handlePluginConflict(EnticePluginFlags.PLUGIN_PROJECT_LIST, "project listing (project management)"); 9296 _handlePluginConflict(EnticePluginFlags.PLUGIN_PROJECT_COMPILE, "project compile (project management)"); 9297 _handlePluginConflict(EnticePluginFlags.PLUGIN_CODECOMPLETION, "source code autocompletion"); 9298 _handlePluginConflict(EnticePluginFlags.PLUGIN_CODELAYOUTTAB, "code layout (code overviews)"); 9299 foreach(Plugin plug; plugins.plugins) 9300 { 9301 signalOnePluginLoaded(plug); 9302 } 9303 } 9304 } 9305 } 9306 9307 9308 private void _handlePluginConflict(uint checkflag, string type) 9309 { 9310 Plugin[] plugs_lo, plugs_med, plugs_hi; // High is non-default normal. 9311 foreach(Plugin plug; plugins.plugins) 9312 { 9313 if(plug.flags & checkflag) 9314 { 9315 if(plug.flags & EnticePluginFlags.PLUGIN_DEFAULT) 9316 plugs_lo ~= plug; 9317 else if(plug.flags & EnticePluginFlags.PLUGIN_DEFAULT2) 9318 plugs_med ~= plug; 9319 else 9320 plugs_hi ~= plug; 9321 } 9322 } 9323 if(plugs_hi.length > 1 9324 || (plugs_hi.length == 0 && plugs_med.length > 1) 9325 || (plugs_hi.length == 0 && plugs_med.length == 0 && plugs_lo.length > 1) 9326 ) 9327 { 9328 // Conflict. 9329 scope pf = (new PromptForm("Plugin Conflict")) 9330 .addLabel("Conflicts found while loading plugin of type " ~ type).ret() 9331 .addLabel("Please resolve the conflict by selecting which plugin to load:").ret() 9332 ; 9333 foreach(Plugin plug; plugs_hi ~ plugs_med ~ plugs_lo) 9334 { 9335 pf.addRadioButton(plug.name, plug.name ~ " - " ~ plug.desc, false).ret(); 9336 } 9337 pf.validate( 9338 (PromptForm _pf) 9339 { 9340 int numchecked = 0; 9341 foreach(Plugin plug; plugs_hi ~ plugs_med ~ plugs_lo) 9342 { 9343 RadioButton ctrl = cast(RadioButton)_pf.get(plug.name); 9344 if(ctrl && ctrl.checked) 9345 { 9346 //whichctrl = ctrl; 9347 numchecked++; 9348 } 9349 } 9350 if(numchecked != 1) 9351 { 9352 msgBox(_pf, "Please select which plugin to load", _pf.text); 9353 return false; 9354 } 9355 return true; 9356 }); 9357 string which = null; 9358 bool ok = DialogResult.OK == pf.showDialog(); 9359 foreach(Plugin plug; plugs_hi ~ plugs_med ~ plugs_lo) 9360 { 9361 RadioButton ctrl = cast(RadioButton)pf.get(plug.name); 9362 if(ok && ctrl && ctrl.checked) 9363 { 9364 continue; 9365 } 9366 ddUnloadPlugin(plug); 9367 if(ok) // Stop the others from loading in the future. 9368 setShouldLoadPlugin(plug.fname, 0); 9369 } 9370 pf.dispose(); 9371 } 9372 else 9373 { 9374 // No conflict. 9375 if(1 == plugs_hi.length) 9376 { 9377 foreach(Plugin plug; plugs_lo) 9378 { 9379 ddUnloadPlugin(plug); 9380 } 9381 foreach(Plugin plug; plugs_med) 9382 { 9383 ddUnloadPlugin(plug); 9384 } 9385 } 9386 else if(1 == plugs_med.length) 9387 { 9388 foreach(Plugin plug; plugs_lo) 9389 { 9390 ddUnloadPlugin(plug); 9391 } 9392 foreach(Plugin plug; plugs_hi) 9393 { 9394 ddUnloadPlugin(plug); 9395 } 9396 } 9397 else if(1 == plugs_lo.length) 9398 { 9399 foreach(Plugin plug; plugs_med) 9400 { 9401 ddUnloadPlugin(plug); 9402 } 9403 foreach(Plugin plug; plugs_hi) 9404 { 9405 ddUnloadPlugin(plug); 9406 } 8815 9407 } 8816 9408 } … … 9088 9680 +/ 9089 9681 loadExtraOptions(rkeysub); // Might be null. 9682 9683 rkeysub = rkey.openSubGroup("Compiler"); 9684 loadCompileSettings(rkeysub); // Might be null. 9090 9685 } 9091 9686 … … 9133 9728 } 9134 9729 } 9135 9136 9137 /+ // This mess was replaced.9138 char[][] notloadedplugins; // Just file names. Strings end up null if the plugins end up getting loaded.9139 char[][] notloadedpluginpaths; // Full paths for above; indices correspond. Strings end up null if the plugins end up getting loaded.9140 char[][] loadeddapiplugins; // Just file names.9141 char[][] unloadingplugins; // Plugins scheduled for unloading via user in options.9142 // ... loaded plugins are in plugins.9143 9144 9145 bool isPluginUnloading(char[] fname)9146 {9147 foreach(un; unloadingplugins)9148 {9149 if(!std.string.icmp(un, fname))9150 return true;9151 }9152 return false;9153 }9154 9155 9156 void setPluginUnloading(char[] fname, bool byes = true)9157 {9158 foreach(idx, un; unloadingplugins)9159 {9160 if(!std.string.icmp(un, fname))9161 {9162 if(!byes)9163 {9164 if(!idx)9165 unloadingplugins = unloadingplugins[1 .. $];9166 else if(idx == unloadingplugins.length - 1)9167 unloadingplugins = unloadingplugins[1 .. idx];9168 else9169 unloadingplugins = unloadingplugins[0 .. idx] ~ unloadingplugins[idx + 1 .. $];9170 }9171 return;9172 }9173 }9174 9175 if(byes)9176 unloadingplugins ~= fname;9177 }9178 9179 9180 void loadPlugins()9181 {9182 assert(!notloadedplugins.length);9183 assert(!notloadedpluginpaths.length);9184 assert(!loadeddapiplugins.length);9185 9186 DWORD numPluginThreads = 1;9187 int xi;9188 9189 xi = getRkey().getEntryInt("PluginThreads", -1);9190 if(-1 != xi)9191 {9192 numPluginThreads = xi;9193 if(numPluginThreads > 8)9194 numPluginThreads = 8;9195 }9196 9197 char[] plugindir;9198 char[][] dapis; // dapi files in plugin dir.9199 char[][] dlls; // dll files in plugin dir.9200 auto pigrp = getRkey().openSubGroup("Load"); // Plugin info config. Might be null! In this case, plShouldLoadPlugin always returns 1.9201 9202 plugindir = pathJoinAbsolute(Application.startupPath, "Plugins");9203 9204 // Returns 1 if yes, 0 if no, or 2 only if version permits it (if not, be silent); default is 1; returns negative for error.9205 int plShouldLoadPlugin(char[] name)9206 {9207 if(!pigrp)9208 return 1;9209 return pigrp.getEntryInt("P:" ~ name, 1);9210 }9211 9212 void plSetShouldLoadPlugin(char[] name, int should)9213 {9214 if(!pigrp)9215 pigrp = getRkey().createSubGroup("Load");9216 pigrp.setEntryInt("P:" ~ name, should);9217 }9218 9219 listdir(plugindir,9220 (DirEntry* de)9221 {9222 if(de.isfile())9223 {9224 char[] ext, fname;9225 ext = std.path.getExt(de.name);9226 fname = std.path.getBaseName(de.name);9227 9228 if(!std.string.icmp("dapi", ext))9229 {9230 if(plShouldLoadPlugin(fname) > 0)9231 {9232 loadeddapiplugins ~= fname.dup; // Need dup?9233 //dapis ~= pathJoinAbsolute(plugindir, de.name);9234 dapis ~= pathJoinAbsolute(plugindir, fname);9235 }9236 else9237 {9238 //notloadedpluginpaths ~= pathJoinAbsolute(plugindir, de.name);9239 notloadedpluginpaths ~= pathJoinAbsolute(plugindir, fname);9240 9241 notloadedplugins ~= fname.dup; // Need dup?9242 }9243 }9244 else if(!std.string.icmp("dll", ext))9245 {9246 if(plShouldLoadPlugin(fname) > 0)9247 {9248 //dlls ~= pathJoinAbsolute(plugindir, de.name);9249 dlls ~= pathJoinAbsolute(plugindir, fname);9250 }9251 else9252 {9253 //notloadedpluginpaths ~= pathJoinAbsolute(plugindir, de.name);9254 notloadedpluginpaths ~= pathJoinAbsolute(plugindir, fname);9255 9256 notloadedplugins ~= fname.dup; // Need dup?9257 }9258 }9259 }9260 return true; // Continue.9261 });9262 9263 // To-do: repeat the above for files in ApplicationData/Entice/Plugins9264 9265 try9266 {9267 if(dapis.length)9268 {9269 if(!numPluginThreads)9270 {9271 apiinfo.setUnloaded();9272 _loadDapiFiles(dapis);9273 apiinfo.setLoadedOne();9274 }9275 else9276 {9277 Thread thd;9278 apiinfo.setUnloaded(1); // 1 thread for now.9279 thd = new _DoDapiThread(dapis);9280 dapis = null;9281 thd.start();9282 }9283 }9284 else9285 {9286 apiinfo.setUnloaded();9287 apiinfo.setLoadedOne();9288 }9289 }9290 catch(Object o)9291 {9292 writeErrorLog(o);9293 9294 dapiError(o);9295 }9296 9297 if(dlls.length)9298 {9299 try9300 {9301 char[][] dllerrs;9302 Plugin plug;9303 char[] emsg;9304 9305 foreach(char[] dllf; dlls)9306 {9307 int errnum;9308 emsg = loadDllPlugin(dllf, plug, true, errnum);9309 if(emsg.length)9310 {9311 char[] plfn = std.path.getBaseName(dllf);9312 9313 notloadedpluginpaths ~= dllf;9314 9315 notloadedplugins ~= plfn;9316 9317 if(8 == errnum) // Version mismatch.9318 {9319 if(2 == plShouldLoadPlugin(plfn)) // Version mismatch silenced previously.9320 continue;9321 msgBox(emsg, "Plugin: " ~ plfn, MsgBoxButtons.OK, MsgBoxIcon.ASTERISK);9322 plSetShouldLoadPlugin(plfn, 2); // Silence for next time.9323 }9324 else9325 {9326 dllerrs ~= emsg;9327 }9328 }9329 else9330 {9331 if(plug)9332 registerPlugin(plug);9333 }9334 }9335 9336 if(dllerrs.length)9337 {9338 if(1 == dllerrs.length)9339 emsg = "1 error";9340 else9341 emsg = std.string.format("%d errors", dllerrs.length);9342 emsg ~= " occured while loading plugins:";9343 foreach(size_t idxmsg, char[] smsg; dllerrs)9344 {9345 emsg ~= "\r\n ";9346 emsg ~= smsg;9347 }9348 throw new Exception(emsg);9349 }9350 }9351 catch(Object e)9352 {9353 writeErrorLog(e);9354 9355 Application.onThreadException(e);9356 Application.onThreadException(new Exception("Unable to finish loading plugins; functionality may be limited until this is remedied"));9357 }9358 }9359 }9360 +/9361 9730 9362 9731 … … 9369 9738 LOADED = 0x2, 9370 9739 UNLOADING = 0x4, 9740 BUILTIN = 0x8, 9371 9741 } 9372 9742 … … 9382 9752 char[] fullpath() // getter 9383 9753 { 9754 //assert(_fullpath !is null, "DdPluginInfo._fullpath is null"); 9384 9755 return _fullpath[0 .. _fullpathlen]; 9385 9756 } … … 9389 9760 char[] fname() // getter 9390 9761 { 9391 return _fullpath[_fullpathlen - _nameoffsetr .. _fullpathlen];9762 return fullpath[$ - _nameoffsetr .. $]; 9392 9763 } 9393 9764 … … 9420 9791 9421 9792 9793 void ddUnloadPlugin(Plugin plug) 9794 { 9795 foreach(ref DdPluginInfo ddpi; ddplugins) 9796 { 9797 if(0 == std.string.icmp(ddpi.fname, plug.fname)) 9798 { 9799 if(ddpi.flags & DDPI.LOADED) 9800 { 9801 ddpi.flags |= DDPI.NOTLOADING; 9802 } 9803 else 9804 { 9805 ddpi.flags |= DDPI.UNLOADING; 9806 } 9807 ddpi.flags &= ~DDPI.LOADED; 9808 break; 9809 } 9810 } 9811 plug.dispose(); 9812 plugins.plugins.remove(plug.pluginid); 9813 } 9814 9815 9422 9816 int findPluginInfo(char[] fname, DdPluginInfo* info = null) 9423 9817 { … … 9440 9834 char[] plugindir; 9441 9835 9836 if(!startlen) 9837 { 9838 // Add built-in plugins. 9839 { 9840 DdPluginInfo ddpi; 9841 ddpi.setFile("Projects", 0); 9842 ddpi.flags = DDPI.BUILTIN; 9843 ddplugins ~= ddpi; 9844 onNewPluginFound(ddplugins[$ - 1]); 9845 } 9846 } 9847 9442 9848 plugindir = pathJoinAbsolute(Application.startupPath, "Plugins"); 9443 9849 listdir(plugindir, … … 9448 9854 char[] ext = std.path.getExt(de.name); 9449 9855 9450 if(!std.string.icmp("dapi", ext) || !std.string.icmp("dll", ext)) 9856 if(!std.string.icmp("dapi", ext) || !std.string.icmp("json", ext) 9857 || !std.string.icmp("dll", ext)) 9451 9858 { 9452 9859 char[] fname = std.path.getBaseName(de.name); … … 9500 9907 9501 9908 9502 void loadPlugins() 9909 class ProjectsPlugin: Plugin 9910 { 9911 this() 9912 { 9913 name = "Projects"; 9914 fname = name; 9915 desc = "Built-in project management and compile features."; 9916 majorVersion = CURMAJORVERSION; 9917 minorVersion = CURMINORVERSION; 9918 flags = EnticePluginFlags.PLUGIN_DEFAULT2 9919 | EnticePluginFlags.PLUGIN_SAFEUNLOAD 9920 | EnticePluginFlags.PLUGIN_PROJECT_COMPILE 9921 //| EnticePluginFlags.PLUGIN_PROJECT_LIST // Not yet, heh 9922 ; 9923 } 9924 9925 9926 9927 bool addedCtrlF5 = false; 9928 bool addedF5 = false; 9929 9930 protected override void loaded() 9931 { 9932 super.loaded(); 9933 9934 try 9935 { 9936 mainForm.addShortcut(Keys.CONTROL | Keys.F5, &mainForm.shortcut_ctrlF5); 9937 addedCtrlF5 = true; 9938 } 9939 catch 9940 { 9941 } 9942 9943 try 9944 { 9945 mainForm.addShortcut(Keys.F5, &mainForm.shortcut_F5); 9946 addedF5 = true; 9947 } 9948 catch 9949 { 9950 } 9951 9952 //addShortcut(Keys.F7, &shortcut_ctrlF7); 9953 9954 /* 9955 pluginid this plugin ID. 9956 name pointer to the name displayed on the menu item, or a single dash for a menu separator. 9957 namelen length of bytes at name. 9958 menuid menu ID unique to this plugin. Must be positive. May include menu options with eidOptions(). 9959 tomenuid the parent menu to add to, -1 to remove, or one of EMENU_* constants. 9960 callback called back on click: menuCallback(EnticeFunctions* efuncs, int menuid); 9961 */ 9962 //EMENU_PROJECT 9963 //efuncs.registerMenuItem() 9964 9965 } 9966 9967 9968 protected override void unloading() 9969 { 9970 if(addedCtrlF5) 9971 { 9972 addedCtrlF5 = false; 9973 try 9974 { 9975 mainForm.removeShortcut(Keys.CONTROL | Keys.F5); 9976 } 9977 catch 9978 { 9979 } 9980 } 9981 if(addedF5) 9982 { 9983 addedF5 = false; 9984 try 9985 { 9986 mainForm.removeShortcut(Keys.F5); 9987 } 9988 catch 9989 { 9990 } 9991 } 9992 9993 super.unloading(); 9994 } 9995 9996 } 9997 9998 9999 Plugin getBuiltinPlugin(char[] name) 10000 { 10001 switch(name) 10002 { 10003 case "Projects": return new ProjectsPlugin(); 10004 default: assert(0); return null; 10005 } 10006 } 10007 10008 10009 // 1 if yes, 0 if no, or 2 only if version permits it 10010 void setShouldLoadPlugin(IRGroup pigrp, char[] name, int should) 10011 { 10012 if(!pigrp) 10013 pigrp = getRkey().createSubGroup("Load"); 10014 pigrp.setEntryInt("P:" ~ name, should); 10015 } 10016 10017 void setShouldLoadPlugin(char[] name, int should) 10018 { 10019 setShouldLoadPlugin(null, name, should); 10020 } 10021 10022 10023 void setupPlugins() 9503 10024 { 9504 10025 assert(!ddplugins.length); … … 9539 10060 return pigrp.getEntryInt("P:dwt.dapi", 0); // Default for this is no-load. 9540 10061 } 10062 if(!std.string.icmp("dfl.dapi", name)) 10063 { 10064 if(!pigrp) 10065 return 0; 10066 // Default for this is no-load because of the new dfl.json! 10067 return pigrp.getEntryInt("P:dfl.dapi", 0); 10068 } 10069 /+if(!std.string.icmp("dirproj.dll", name)) 10070 { 10071 if(!pigrp) 10072 return 0; 10073 // Favor the built-in projects first. 10074 // Actually don't need to do this 10075 // because it's marked as EPF_PLUGIN_DEFAULT (last resort) 10076 return pigrp.getEntryInt("P:dirproj.dll", 0); 10077 }+/ 9541 10078 9542 10079 if(!pigrp) … … 9547 10084 void plSetShouldLoadPlugin(char[] name, int should) 9548 10085 { 9549 if(!pigrp) 9550 pigrp = getRkey().createSubGroup("Load"); 9551 pigrp.setEntryInt("P:" ~ name, should); 10086 setShouldLoadPlugin(pigrp, name, should); 9552 10087 } 9553 10088 … … 9557 10092 { 9558 10093 char[] ext = std.path.getExt(ddpi.fullpath); 9559 if(!std.string.icmp(ext, "dapi")) 10094 if(!std.string.icmp(ext, "dapi") 10095 || !std.string.icmp(ext, "json")) 9560 10096 { 9561 10097 dapis ~= ddpi.fullpath; … … 9602 10138 } 9603 10139 9604 //if(dlls.length)9605 10140 { 9606 10141 try … … 9612 10147 foreach(inout DdPluginInfo ddpi; ddplugins) 9613 10148 { 9614 if(!(ddpi.flags & DDPI.NOTLOADING) 9615 && (ddpi.fullpath.length < 5 || std.string.icmp(".dapi", ddpi.fullpath[$ - 5 .. $])) ) 10149 if(ddpi.flags & DDPI.NOTLOADING) 10150 { 10151 continue; 10152 } 10153 //msgBox("loading plugin: " ~ ddpi.fullpath); 10154 if(ddpi.flags & DDPI.BUILTIN) 10155 { 10156 Plugin plug = getBuiltinPlugin(ddpi.fullpath); 10157 ddpi.flags |= DDPI.LOADED; 10158 registerPlugin(plug); 10159 continue; 10160 } 10161 if(ddpi.fullpath.length < 5 10162 || !(!std.string.icmp(".dapi", ddpi.fullpath[$ - 5 .. $]) 10163 || !std.string.icmp(".json", ddpi.fullpath[$ - 5 .. $])) 10164 ) 9616 10165 { 9617 10166 int errnum; 10167 // Doesn't call plugin's "loaded" yet. 9618 10168 emsg = loadDllPlugin(ddpi.fullpath, plug, true, errnum); 9619 10169 if(emsg.length) … … 9639 10189 ddpi.flags |= DDPI.LOADED; 9640 10190 10191 // Doesn't call plugin's "loaded" yet. 10192 // Only registers with Entice internals (e.g. w/ plugin ID) 9641 10193 registerPlugin(plug); 9642 10194 } … … 9678 10230 9679 10231 // Can't use DflCompat.FORM_DIALOGRESULT_096 (zorderform and perhaps others depend on the new impl) 10232 10233 debug(Entice_fakeMultipleScreens) 10234 { 10235 Screen.fakeMultipleScreens = true; 10236 } 9680 10237 9681 10238 try … … 9855 10412 } 9856 10413 config_found: ; 10414 //compile.compileConfigDir = localdir; 9857 10415 9858 10416 if(_install) … … 9900 10458 9901 10459 // Want the plugins to be there for the file loading. 9902 loadPlugins();10460 setupPlugins(); 9903 10461 pluginsloaded = true; 9904 10462 … … 9908 10466 Application.doEvents(); 9909 10467 9910 mainForm.tellPluginsLoaded(); 10468 // Calls the plugins' "loaded"! 10469 // This handles 'default' plugins, etc. 10470 mainForm.finishPluginsLoaded(); 9911 10471 9912 10472 Application.doEvents(); // In case the plugins post messages. … … 9925 10485 Application.onThreadException(e); 9926 10486 } 10487 10488 /+ 10489 { 10490 struct fff { import promptbox; } 10491 scope pf = (new fff.PromptForm("Plugins Loaded")) 10492 .enableButtons(false); 10493 foreach(Plugin plug; plugins.plugins) 10494 { 10495 pf.addLabel("Plugin: " ~ plug.fname); 10496 } 10497 pf.showDialog(); 10498 pf.dispose(); 10499 } 10500 +/ 9927 10501 9928 10502 apprun = true; trunk/win32/entice/dfldesigner.rc
r101 r102 79 79 VALUE "FileVersion", "0.8.6\0" 80 80 VALUE "InternalName", "entice" 81 VALUE "LegalCopyright", "Copyright (C) 2004-200 8Christopher E. Miller"81 VALUE "LegalCopyright", "Copyright (C) 2004-2009 Christopher E. Miller" 82 82 VALUE "OriginalFilename", "entice.exe" 83 83 VALUE "ProductName", "Entice Designer\0" trunk/win32/entice/dirchanges.d
r101 r102 154 154 } 155 155 156 HANDLE hwait = dfl. utf.findFirstChangeNotification(dir, FALSE,156 HANDLE hwait = dfl.internal.utf.findFirstChangeNotification(dir, FALSE, 157 157 FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE 158 158 | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME); trunk/win32/entice/drawing.d
r101 r102 3 3 4 4 5 private import dfl.all, dfl. winapi;5 private import dfl.all, dfl.internal.winapi; 6 6 7 7 trunk/win32/entice/dscale.d
r101 r102 3 3 4 4 5 private import dfl.all, dfl. winapi;5 private import dfl.all, dfl.internal.winapi; 6 6 7 7 trunk/win32/entice/editorexprops.d
r101 r102 98 98 picBox.name = "picBox"; 99 99 picBox.sizeMode = dfl.picturebox.PictureBoxSizeMode.CENTER_IMAGE; 100 picBox.bounds = dfl. base.Rect(8, 8, 23, 23);100 picBox.bounds = dfl.all.Rect(8, 8, 23, 23); 101 101 picBox.parent = this; 102 102 //~DFL dfl.groupbox.GroupBox=groupBox1 … … 104 104 groupBox1.name = "groupBox1"; 105 105 groupBox1.text = "Encoding"; 106 groupBox1.bounds = dfl. base.Rect(8, 40, 296, 92);106 groupBox1.bounds = dfl.all.Rect(8, 40, 296, 92); 107 107 groupBox1.parent = this; 108 108 //~DFL dfl.button.RadioButton=utf8radio … … 110 110 utf8radio.name = "utf8radio"; 111 111 utf8radio.text = "UTF-8 (Recommended)"; 112 utf8radio.bounds = dfl. base.Rect(12, 17, 171, 23);112 utf8radio.bounds = dfl.all.Rect(12, 17, 171, 23); 113 113 utf8radio.parent = groupBox1; 114 114 //~DFL dfl.button.RadioButton=utf16leRadio … … 116 116 utf16leRadio.name = "utf16leRadio"; 117 117 utf16leRadio.text = "UTF-16 LE (Windows Unicode)"; 118 utf16leRadio.bounds = dfl. base.Rect(12, 41, 171, 23);118 utf16leRadio.bounds = dfl.all.Rect(12, 41, 171, 23); 119 119 utf16leRadio.parent = groupBox1; 120 120 //~DFL dfl.button.RadioButton=utf32leRadio … … 122 122 utf32leRadio.name = "utf32leRadio"; 123 123 utf32leRadio.text = "UTF-32 LE"; 124 utf32leRadio.bounds = dfl. base.Rect(12, 65, 171, 23);124 utf32leRadio.bounds = dfl.all.Rect(12, 65, 171, 23); 125 125 utf32leRadio.parent = groupBox1; 126 126 //~DFL dfl.button.RadioButton=utf16beRadio … … 128 128 utf16beRadio.name = "utf16beRadio"; 129 129 utf16beRadio.text = "UTF-16 BE"; 130 utf16beRadio.bounds = dfl. base.Rect(196, 41, 83, 23);130 utf16beRadio.bounds = dfl.all.Rect(196, 41, 83, 23); 131 131 utf16beRadio.parent = groupBox1; 132 132 //~DFL dfl.button.RadioButton=utf32beRadio … … 134 134 utf32beRadio.name = "utf32beRadio"; 135 135 utf32beRadio.text = "UTF-32 BE"; 136 utf32beRadio.bounds = dfl. base.Rect(196, 65, 83, 23);136 utf32beRadio.bounds = dfl.all.Rect(196, 65, 83, 23); 137 137 utf32beRadio.parent = groupBox1; 138 138 //~DFL dfl.button.Button=okBtn … … 140 140 okBtn.name = "okBtn"; 141 141 okBtn.text = "OK"; 142 okBtn.bounds = dfl. base.Rect(152, 144, 75, 23);142 okBtn.bounds = dfl.all.Rect(152, 144, 75, 23); 143 143 okBtn.parent = this; 144 144 //~DFL dfl.button.Button=cancelBtn … … 146 146 cancelBtn.name = "cancelBtn"; 147 147 cancelBtn.text = "Cancel"; 148 cancelBtn.bounds = dfl. base.Rect(232, 144, 75, 23);148 cancelBtn.bounds = dfl.all.Rect(232, 144, 75, 23); 149 149 cancelBtn.parent = this; 150 150 //~DFL EEXP_PathLabel:dfl.textbox.TextBox=itemNameDisp … … 154 154 itemNameDisp.text = "Foo"; 155 155 itemNameDisp.borderStyle = dfl.base.BorderStyle.NONE; 156 itemNameDisp.bounds = dfl. base.Rect(34, 12, 268, 23);156 itemNameDisp.bounds = dfl.all.Rect(34, 12, 268, 23); 157 157 itemNameDisp.parent = this; 158 158 //~Entice Designer 0.8.2pre6 code ends here. trunk/win32/entice/editorstyler.d
r101 r102 3 3 4 4 5 private import dfl.all, dfl. winapi;5 private import dfl.all, dfl.internal.winapi; 6 6 7 7 trunk/win32/entice/etabber.d
r101 r102 24 24 25 25 26 bool allowDetach = false; 27 28 26 29 /// 27 30 final bool showSplit() // getter trunk/win32/entice/findreplace.d
r101 r102 4 4 5 5 private import std.string, std.path; 6 private import dfl.all, dfl. winapi;6 private import dfl.all, dfl.internal.winapi; 7 7 8 8 … … 453 453 label1.text = "Fi&nd what:"; 454 454 label1.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 455 label1.bounds = dfl. base.Rect(8, 8, 76, 23);455 label1.bounds = dfl.all.Rect(8, 8, 76, 23); 456 456 label1.parent = this; 457 457 //~DFL dfl.combobox.ComboBox=findBox 458 458 findBox = new dfl.combobox.ComboBox(); 459 459 findBox.name = "findBox"; 460 findBox.bounds = dfl. base.Rect(88, 8, 200, 21);460 findBox.bounds = dfl.all.Rect(88, 8, 200, 21); 461 461 findBox.parent = this; 462 462 //~DFL dfl.label.Label=replaceLabel … … 465 465 replaceLabel.text = "Re&place with:"; 466 466 replaceLabel.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 467 replaceLabel.bounds = dfl. base.Rect(8, 40, 76, 23);467 replaceLabel.bounds = dfl.all.Rect(8, 40, 76, 23); 468 468 replaceLabel.parent = this; 469 469 //~DFL dfl.combobox.ComboBox=replaceBox 470 470 replaceBox = new dfl.combobox.ComboBox(); 471 471 replaceBox.name = "replaceBox"; 472 replaceBox.bounds = dfl. base.Rect(88, 40, 200, 21);472 replaceBox.bounds = dfl.all.Rect(88, 40, 200, 21); 473 473 replaceBox.parent = this; 474 474 //~DFL dfl.button.CheckBox=wholeWordCheck … … 476 476 wholeWordCheck.name = "wholeWordCheck"; 477 477 wholeWordCheck.text = "Match &whole word only"; 478 wholeWordCheck.bounds = dfl. base.Rect(8, 72, 243, 23);478 wholeWordCheck.bounds = dfl.all.Rect(8, 72, 243, 23); 479 479 wholeWordCheck.parent = this; 480 480 //~DFL dfl.button.CheckBox=caseCheck … … 482 482 caseCheck.name = "caseCheck"; 483 483 caseCheck.text = "Match &case"; 484 caseCheck.bounds = dfl. base.Rect(8, 92, 243, 23);484 caseCheck.bounds = dfl.all.Rect(8, 92, 243, 23); 485 485 caseCheck.parent = this; 486 486 //~DFL dfl.button.CheckBox=regexCheck … … 488 488 regexCheck.name = "regexCheck"; 489 489 regexCheck.text = "Regular &expression"; 490 regexCheck.bounds = dfl. base.Rect(8, 112, 243, 23);490 regexCheck.bounds = dfl.all.Rect(8, 112, 243, 23); 491 491 regexCheck.parent = this; 492 492 //~DFL dfl.button.CheckBox=wrapCheck … … 494 494 wrapCheck.name = "wrapCheck"; 495 495 wrapCheck.text = "Wrap aroun&d"; 496 wrapCheck.bounds = dfl. base.Rect(8, 132, 243, 23);496 wrapCheck.bounds = dfl.all.Rect(8, 132, 243, 23); 497 497 wrapCheck.parent = this; 498 498 //~DFL dfl.button.CheckBox=escapeCharCheck … … 500 500 escapeCharCheck.name = "escapeCharCheck"; 501 501 escapeCharCheck.text = "Transform &backslash expressions"; 502 escapeCharCheck.bounds = dfl. base.Rect(8, 152, 243, 23);502 escapeCharCheck.bounds = dfl.all.Rect(8, 152, 243, 23); 503 503 escapeCharCheck.parent = this; 504 504 //~DFL dfl.button.CheckBox=transCheck … … 506 506 transCheck.name = "transCheck"; 507 507 transCheck.text = "Dialog &Transparency"; 508 transCheck.bounds = dfl. base.Rect(8, 172, 211, 23);508 transCheck.bounds = dfl.all.Rect(8, 172, 211, 23); 509 509 transCheck.parent = this; 510 510 //~DFL dfl.button.Button=findNextBtn … … 512 512 findNextBtn.name = "findNextBtn"; 513 513 findNextBtn.text = "&Find Next"; 514 findNextBtn.bounds = dfl. base.Rect(296, 8, 123, 23);514 findNextBtn.bounds = dfl.all.Rect(296, 8, 123, 23); 515 515 findNextBtn.parent = this; 516 516 //~DFL dfl.button.Button=replaceBtn … … 518 518 replaceBtn.name = "replaceBtn"; 519 519 replaceBtn.text = "&Replace"; 520 replaceBtn.bounds = dfl. base.Rect(296, 40, 123, 23);520 replaceBtn.bounds = dfl.all.Rect(296, 40, 123, 23); 521 521 replaceBtn.parent = this; 522 522 //~DFL dfl.button.Button=replaceAllBtn … … 524 524 replaceAllBtn.name = "replaceAllBtn"; 525 525 replaceAllBtn.text = "Replace &All"; 526 replaceAllBtn.bounds = dfl. base.Rect(296, 72, 123, 23);526 replaceAllBtn.bounds = dfl.all.Rect(296, 72, 123, 23); 527 527 replaceAllBtn.parent = this; 528 528 //~DFL dfl.button.Button=replaceInSelectionBtn … … 530 530 replaceInSelectionBtn.name = "replaceInSelectionBtn"; 531 531 replaceInSelectionBtn.text = "Replace in &Selection"; 532 replaceInSelectionBtn.bounds = dfl. base.Rect(296, 104, 123, 23);532 replaceInSelectionBtn.bounds = dfl.all.Rect(296, 104, 123, 23); 533 533 replaceInSelectionBtn.parent = this; 534 534 //~DFL dfl.button.Button=closeBtn … … 536 536 closeBtn.name = "closeBtn"; 537 537 closeBtn.text = "Close"; 538 closeBtn.bounds = dfl. base.Rect(296, 136, 123, 23);538 closeBtn.bounds = dfl.all.Rect(296, 136, 123, 23); 539 539 closeBtn.parent = this; 540 540 //~DFL dfl.label.Label=tempText … … 542 542 tempText.name = "tempText"; 543 543 tempText.textAlign = dfl.base.ContentAlignment.BOTTOM_RIGHT; 544 tempText.bounds = dfl. base.Rect(224, 168, 192, 23);544 tempText.bounds = dfl.all.Rect(224, 168, 192, 23); 545 545 tempText.parent = this; 546 546 //~Entice Designer 0.8.2.1 code ends here. trunk/win32/entice/inputform.d
r101 r102 69 69 inputBox = new dfl.textbox.TextBox(); 70 70 inputBox.name = "inputBox"; 71 inputBox.bounds = dfl. base.Rect(8, 64, 280, 23);71 inputBox.bounds = dfl.all.Rect(8, 64, 280, 23); 72 72 inputBox.parent = this; 73 73 //~DFL dfl.label.Label=inputLabel 74 74 inputLabel = new dfl.label.Label(); 75 75 inputLabel.name = "inputLabel"; 76 inputLabel.bounds = dfl. base.Rect(8, 8, 276, 47);76 inputLabel.bounds = dfl.all.Rect(8, 8, 276, 47); 77 77 inputLabel.parent = this; 78 78 //~DFL dfl.button.Button=okBtn … … 80 80 okBtn.name = "okBtn"; 81 81 okBtn.text = "OK"; 82 okBtn.bounds = dfl. base.Rect(128, 96, 75, 23);82 okBtn.bounds = dfl.all.Rect(128, 96, 75, 23); 83 83 okBtn.parent = this; 84 84 //~DFL dfl.button.Button=cancelBtn … … 86 86 cancelBtn.name = "cancelBtn"; 87 87 cancelBtn.text = "Cancel"; 88 cancelBtn.bounds = dfl. base.Rect(208, 96, 75, 23);88 cancelBtn.bounds = dfl.all.Rect(208, 96, 75, 23); 89 89 cancelBtn.parent = this; 90 90 //~Entice Designer 0.8.1 code ends here. trunk/win32/entice/mak.bat
r101 r102 1 1 @cls 2 3 set dmdpath=c:\dmd 4 set dimports=f:\christop\d\import 5 6 set dfl_options=-version=DFL_MULTIPLE_SCREENS 2 7 3 8 4 9 rcc -32 dfldesigner.rc 5 dfl -d -gui -version=START_PAGE -version=DESIGN_PROP_INFO %dfl_flags% -Jimages -ofentice.exe dfldesigner %1 %2 %3 %4 %5 -version=ETABSCROLL -version=ONLYFOCUSDESIGNITEMPARENT -version=ADVANCED_FIND advfindpanel ddfiletypes projectmanager ddprojectmanager aboutform apiviewer apiinfo waitmanager dirchanges startpage ddopenparser inputform inputnumber scistyles options dscale editorstyler ddeditorstyler ddoptions ddoptsfiletypespanel ddoptsdesignpanel ddoptsgeneralpanel ddoptspluginspanel ddoptseditorpanel ddoptsnetworkpanel findreplace ddfindreplace util drawing sourcegen parse dflparse tabber proppanel etabber toolbox dddesignform dddesigncontrol ddcontrolchildren newform design designform designcontrol dockstyleform ddcontrolspace scintilladlex checkup ddexprops editorexprops ddwininet zorderform plugins filterfindbox resource shell32.lib c:\dmd\import\dfl\scintilla.d dfldesigner.res dfldesigner.def -Id:\d\import d:\d\import\rgroup.d d:\d\import\rdflregistry.d d:\d\import\rini.d d:\d\import\ini.d 10 11 @set entice_mode=-debug -gui 12 @rem @set entice_mode=-O -inline -gui 13 @rem @set entice_mode=-debug=Entice_fakeMultipleScreens -debug -unittest -gui 14 15 dfl %entice_mode% -d -version=START_PAGE -version=TABBER_NO_DETACH -version=ENTICE_MULTISEL -version=DESIGN_PROP_INFO %dfl_flags% -Jimages -ofentice.exe dfldesigner -version=ETABSCROLL -version=ONLYFOCUSDESIGNITEMPARENT -version=ADVANCED_FIND advfindpanel ddfiletypes usereditlistbox promptbox downloaderpanel projectmanager ddprojectmanager aboutform apiviewer apiinfo waitmanager dirchanges startpage ddopenparser inputform inputnumber scistyles options dscale editorstyler ddeditorstyler ddoptions ddoptsfiletypespanel ddoptsdesignpanel ddoptsgeneralpanel ddoptspluginspanel ddoptseditorpanel ddoptsnetworkpanel ddoptscompilerpanel findreplace ddfindreplace util drawing sourcegen parse dflparse tabber proppanel etabber toolbox dddesignform dddesigncontrol ddcontrolchildren newform design designform designcontrol dockstyleform ddcontrolspace scintilladlex checkup ddexprops editorexprops ddwininet zorderform plugins filterfindbox compile firstsetupstartpagepanel dlangselectorpanel dinstallform dmdversionselectorpanel savetodirpanel resource winapi shell32.lib %dmdpath%\import\dfl\scintilla.d %dmdpath%\import\dfl\cpp\scintilla.d dfldesigner.res process -I%dimports% %dimports%\rgroup.d %dimports%\rdflregistry.d %dimports%\rini.d %dimports%\ini.d 16 6 17 7 18 trunk/win32/entice/newform.d
r101 r102 4 4 5 5 private import std.path, std.file, std.string; 6 private import dfl.all, dfl. winapi;6 private import dfl.all, dfl.internal.winapi; 7 7 8 8 private import dfldesigner, design, util; … … 736 736 nameLabel.text = "&Name:"; 737 737 nameLabel.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 738 nameLabel.bounds = dfl. base.Rect(144, 8, 92, 23);738 nameLabel.bounds = dfl.all.Rect(144, 8, 92, 23); 739 739 nameLabel.parent = this; 740 740 //~DFL dfl.textbox.TextBox=myFormBox 741 741 myFormBox = new dfl.textbox.TextBox(); 742 742 myFormBox.name = "myFormBox"; 743 myFormBox.bounds = dfl. base.Rect(240, 8, 184, 23);743 myFormBox.bounds = dfl.all.Rect(240, 8, 184, 23); 744 744 myFormBox.parent = this; 745 745 //~DFL dfl.label.Label=fileNameLabel … … 748 748 fileNameLabel.text = "&File name:"; 749 749 fileNameLabel.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 750 fileNameLabel.bounds = dfl. base.Rect(144, 40, 92, 23);750 fileNameLabel.bounds = dfl.all.Rect(144, 40, 92, 23); 751 751 fileNameLabel.parent = this; 752 752 //~DFL dfl.textbox.TextBox=fileBox 753 753 fileBox = new dfl.textbox.TextBox(); 754 754 fileBox.name = "fileBox"; 755 fileBox.bounds = dfl. base.Rect(240, 40, 184, 23);755 fileBox.bounds = dfl.all.Rect(240, 40, 184, 23); 756 756 fileBox.parent = this; 757 757 //~DFL dfl.label.Label=label6 … … 760 760 label6.text = "Save &in:"; 761 761 label6.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 762 label6.bounds = dfl. base.Rect(144, 72, 92, 23);762 label6.bounds = dfl.all.Rect(144, 72, 92, 23); 763 763 label6.parent = this; 764 764 //~DFL dfl.textbox.TextBox=dirBox 765 765 dirBox = new dfl.textbox.TextBox(); 766 766 dirBox.name = "dirBox"; 767 dirBox.bounds = dfl. base.Rect(240, 72, 184, 23);767 dirBox.bounds = dfl.all.Rect(240, 72, 184, 23); 768 768 dirBox.parent = this; 769 769 //~DFL dfl.button.Button=dirBrowseBtn … … 771 771 dirBrowseBtn.name = "dirBrowseBtn"; 772 772 dirBrowseBtn.text = "&Browse..."; 773 dirBrowseBtn.bounds = dfl. base.Rect(352, 104, 75, 23);773 dirBrowseBtn.bounds = dfl.all.Rect(352, 104, 75, 23); 774 774 dirBrowseBtn.parent = this; 775 775 //~DFL dfl.label.Label=label7 … … 778 778 label7.text = "Save as:"; 779 779 label7.autoSize = true; 780 label7.bounds = dfl. base.Rect(144, 112, 42, 13);780 label7.bounds = dfl.all.Rect(144, 112, 42, 13); 781 781 label7.parent = this; 782 782 //~DFL dfl.button.Button=createBtn … … 784 784 createBtn.name = "createBtn"; 785 785 createBtn.text = "&Create"; 786 createBtn.bounds = dfl. base.Rect(272, 168, 75, 23);786 createBtn.bounds = dfl.all.Rect(272, 168, 75, 23); 787 787 createBtn.parent = this; 788 788 //~DFL dfl.button.Button=cancelBtn … … 790 790 cancelBtn.name = "cancelBtn"; 791 791 cancelBtn.text = "Cancel"; 792 cancelBtn.bounds = dfl. base.Rect(352, 168, 75, 23);792 cancelBtn.bounds = dfl.all.Rect(352, 168, 75, 23); 793 793 cancelBtn.parent = this; 794 794 //~DFL dfl.listbox.ListBox=itemList … … 797 797 itemList.drawMode = dfl.base.DrawMode.OWNER_DRAW_FIXED; 798 798 itemList.integralHeight = false; 799 itemList.bounds = dfl. base.Rect(8, 8, 120, 184);799 itemList.bounds = dfl.all.Rect(8, 8, 120, 184); 800 800 itemList.parent = this; 801 801 //~DFL FileDispLabel:dfl.label.Label=saveDisp … … 804 804 saveDisp.borderStyle = dfl.base.BorderStyle.FIXED_3D; 805 805 saveDisp.textAlign = dfl.base.ContentAlignment.MIDDLE_LEFT; 806 saveDisp.bounds = dfl. base.Rect(136, 136, 292, 23);806 saveDisp.bounds = dfl.all.Rect(136, 136, 292, 23); 807 807 saveDisp.parent = this; 808 808 //~Entice Designer 0.8pre8 code ends here. trunk/win32/entice/options.d
r101 r102 6 6 private import dfl.all; 7 7 private import tabber, winapi; 8 9 import usereditlistbox; 8 10 9 11 import dscale; … … 714 716 715 717 718 class OptListBox: ListBox, IOpt 719 { 720 mixin ApplyOpt; 721 722 723 this(char[] optName, uint32_t optId) 724 { 725 optname = optName; 726 optid = optId; 727 } 728 729 730 bit isOptDirty() // getter 731 { 732 return isdirty; 733 } 734 735 736 char[] optName() // getter 737 { 738 return optname; 739 } 740 741 742 uint32_t gid() // getter 743 { 744 return optid; 745 } 746 747 748 RegistryValue getOptValue() 749 { 750 char[][] x = new char[][this.items.length]; 751 for(int i = 0; i < x.length; i++) 752 { 753 x[i] = this.items[i].toString(); 754 } 755 RegistryValueMultiSz rval = new RegistryValueMultiSz(); 756 rval.value = x; 757 return rval; 758 } 759 760 761 // Sets the value and makes it not dirty. 762 bit setOptValue(RegistryValue regval) 763 { 764 RegistryValueMultiSz rval; 765 rval = cast(RegistryValueMultiSz)regval; 766 if(rval) 767 { 768 this.items.clear(); 769 for(int i = 0; i < rval.value.length; i++) 770 { 771 this.items.add(rval.value[i]); 772 } 773 isdirty = false; 774 return true; 775 } 776 return false; 777 } 778 779 780 // This is here because this list can't get dirty by itself. 781 // Need user handling code to dirty it (e.g. OptUserEditListBox). 782 void setDirty() 783 { 784 isdirty = true; 785 } 786 787 788 char[] optname; 789 uint32_t optid; 790 bit isdirty = false; 791 } 792 793 794 class OptUserEditListBox: UserEditListBox, IOpt 795 { 796 mixin ApplyOpt; 797 798 OptListBox optlist; 799 800 801 this(char[] optName, uint32_t optId) 802 { 803 optlist = new OptListBox(optName, optId); 804 super(); 805 } 806 807 808 bit isOptDirty() // getter 809 { 810 return optlist.isOptDirty; 811 } 812 813 814 char[] optName() // getter 815 { 816 return optlist.optName; 817 } 818 819 820 uint32_t gid() // getter 821 { 822 return optlist.gid; 823 } 824 825 826 RegistryValue getOptValue() 827 { 828 return optlist.getOptValue(); 829 } 830 831 832 // Sets the value and makes it not dirty. 833 bit setOptValue(RegistryValue regval) 834 { 835 return optlist.setOptValue(regval); 836 } 837 838 839 protected override ListBox createListBox() 840 { 841 return optlist; 842 } 843 844 845 protected override void onUserEdited(EventArgs ea) 846 { 847 super.onUserEdited(ea); 848 849 optlist.setDirty(); 850 } 851 852 } 853 854 716 855 class OptTab: Tab, IId 717 856 { … … 820 959 maximizeBox = false; 821 960 sizingGrip = true; 822 //size = Size(400 + 30, 320 + 30); // Tad bigger than least. 823 size = Size(500, 400); // Tad bigger than least. 961 size = Size(480, 420); // Tad bigger than least. 824 962 startPosition = FormStartPosition.CENTER_PARENT; 825 963 showInTaskbar = false; … … 853 991 addShortcut(Keys.CONTROL | Keys.TAB, &shortcut_ctrlTab); 854 992 993 //closing ~= &form_closing; 994 855 995 resumeLayout(false); 856 996 } 997 998 999 /* 1000 void form_closing(Object sender, CancelEventArgs ea) 1001 { 1002 tabs.removeAllTabs(); 1003 } 1004 */ 857 1005 858 1006 trunk/win32/entice/parse.d
r101 r102 877 877 878 878 default: 879 if(!std. string.isspace(ch))879 if(!std.ctype.isspace(ch)) 880 880 { 881 881 warnOrErr("Expected end of line."); … … 947 947 // Returns null dchar at end instead of throwing exception. 948 948 final dchar getc() 949 in950 949 { 951 950 assert(ungettok.type == TokenType.NONE); 952 } 953 body 954 { 951 955 952 dchar result; 956 953 … … 1002 999 // Single unget only. 1003 1000 final void ungetc(dchar ch) 1004 in1005 1001 { 1006 1002 assert(!unget); 1007 } 1008 body 1009 { 1003 1010 1004 unget = ch; 1011 1005 } … … 1344 1338 1345 1339 final void ungetToken(Token tok) 1346 in1347 1340 { 1348 1341 assert(ungettok.type == TokenType.NONE); 1349 1342 assert(!ungettok.str.length); 1350 1343 assert(tok.type != TokenType.NONE); 1351 } 1352 body 1353 { 1344 1354 1345 ungettok = tok; 1355 1346 … … 1370 1361 //protected Token getNewToken() 1371 1362 protected void getNewToken(out Token result) 1372 in 1373 { 1374 assert(ungettok.type == TokenType.NONE); 1375 } 1376 body 1377 { 1363 { 1364 assert(ungettok.type == TokenType.NONE, 1365 "getNewToken: (ungettok.type == TokenType.NONE)"); 1366 1378 1367 //Token result; 1379 1368 dchar ch; trunk/win32/entice/plugins.d
r101 r102 3 3 4 4 5 import winapi, dfl.all, dfl. utf;5 import winapi, dfl.all, dfl.internal.utf; 6 6 7 7 import std.gc, std.path, std.string, std.c.stdlib, … … 645 645 if(ent.filePath.length) 646 646 { 647 auto dcmd= new DoCmd(plug.name, (cast(char*)getinfo)[0 .. getinfosize], getDirName(ent.filePath), true);647 DoCmd dcmd = new DoCmd(plug.name, (cast(char*)getinfo)[0 .. getinfosize], getDirName(ent.filePath), true); 648 648 dcmd.start(); 649 649 // Note: don't stop, delete (or auto) dcmd because it's still running! … … 666 666 if(ent.filePath.length) 667 667 { 668 auto dcmd= new DoCmd(plug.name, (cast(char*)getinfo)[0 .. getinfosize], getDirName(ent.filePath), true);668 DoCmd dcmd = new DoCmd(plug.name, (cast(char*)getinfo)[0 .. getinfosize], getDirName(ent.filePath), true); 669 669 dcmd.cmdpause = false; 670 670 dcmd.start(); … … 1533 1533 extern(Windows) 1534 1534 { 1535 alias int function(EnticePluginInfo*) EnticePlugin LoadProc;1535 alias int function(EnticePluginInfo*) EnticePluginInfoProc; 1536 1536 alias void function(EnticeFunctions*) EnticePluginLoadedProc; 1537 1537 alias void function(EnticeFunctions* efuncs, int n) EnticePluginUnloadedProc; … … 1956 1956 1957 1957 HMODULE hmod; 1958 bool hasPluginLoaded = false; // Plugin loaded signaled. 1958 1959 1959 1960 PluginMenuItem[] menus; … … 2026 2027 protected void registered() 2027 2028 { 2028 2029 } 2030 2031 2032 void dispose(bool unloadDLL = true) 2033 { 2034 if(hmod.init != hmod) 2035 { 2036 auto unloadedproc = cast(EnticePluginUnloadedProc)getPluginProcAddr(hmod, "enticePluginUnloaded", 2); 2037 if(unloadedproc) 2029 } 2030 2031 2032 // Called by pluginLoad(). 2033 protected void loaded() 2034 { 2035 } 2036 2037 2038 // Called by dispose(). 2039 protected void unloading() 2040 { 2041 } 2042 2043 2044 // Called by signalOnePluginLoaded(). 2045 protected final void pluginLoad() 2046 { 2047 hasPluginLoaded = true; 2048 2049 // Using "new" to get completely new address. 2050 efuncs = new EnticeFunctions; 2051 efuncs.pluginid = pluginid; 2052 2053 if(hmod) 2054 { 2055 EnticePluginLoadedProc loadedproc; 2056 loadedproc = cast(EnticePluginLoadedProc)getPluginProcAddr(hmod, "enticePluginLoaded", 1); 2057 // OK if not there, they just don't care about the loaded event. 2058 if(loadedproc) 2038 2059 { 2039 2060 try 2040 2061 { 2041 unloadedproc(efuncs, unloadDLL ? 1 : 2); 2042 2043 if(unloadDLL) 2044 FreeLibrary(hmod); // Only if successfully returned from unload proc. 2062 loadedproc(efuncs); 2045 2063 } 2046 2064 catch 2047 2065 { 2048 // If unloadedproc threw, leak the DLL, otherwise bad things could happen. 2066 } 2067 } 2068 } 2069 2070 loaded(); 2071 2072 } 2073 2074 2075 void dispose(bool unloadDLL = true) 2076 { 2077 unloading(); 2078 2079 bool prev_hasPluginLoaded = hasPluginLoaded; 2080 hasPluginLoaded = false; 2081 if(hmod.init != hmod) 2082 { 2083 if(prev_hasPluginLoaded) 2084 { 2085 auto unloadedproc = cast(EnticePluginUnloadedProc)getPluginProcAddr(hmod, "enticePluginUnloaded", 2); 2086 if(unloadedproc) 2087 { 2088 try 2089 { 2090 unloadedproc(efuncs, unloadDLL ? 1 : 2); 2091 2092 if(unloadDLL) 2093 FreeLibrary(hmod); // Only if successfully returned from unload proc. 2094 } 2095 catch 2096 { 2097 // If unloadedproc threw, leak the DLL, otherwise bad things could happen. 2098 } 2099 } 2100 else 2101 { 2102 if(unloadDLL) 2103 FreeLibrary(hmod); 2049 2104 } 2050 2105 } … … 2132 2187 } 2133 2188 2134 pluginid = rand() & 0x FFFFFFF;2189 pluginid = rand() & 0x0FFFFFFF; 2135 2190 if(!(pluginid in plugins)) 2136 2191 break; … … 2144 2199 2145 2200 2201 /+ 2202 void signalPluginsLoaded() 2203 { 2204 foreach(Plugin plug in plugins) 2205 { 2206 signalOnePluginLoaded(plug); 2207 } 2208 } 2209 +/ 2210 2211 2146 2212 void signalOnePluginLoaded(Plugin plug) 2147 2213 { 2148 EnticePluginLoadedProc loadedproc; 2149 loadedproc = cast(EnticePluginLoadedProc)getPluginProcAddr(plug.hmod, "enticePluginLoaded", 1); 2150 if(!loadedproc) // OK, they just don't care about the loaded event. 2151 return; 2152 2153 try 2154 { 2155 // Using "new" to get completely new address. 2156 plug.efuncs = new EnticeFunctions; 2157 plug.efuncs.pluginid = plug.pluginid; 2158 loadedproc(plug.efuncs); 2159 } 2160 catch 2161 { 2162 } 2163 } 2164 2165 2166 void signalPluginsLoaded() 2167 { 2168 foreach(Plugin plug; plugins) 2169 { 2170 signalOnePluginLoaded(plug); 2171 } 2214 plug.pluginLoad(); 2172 2215 } 2173 2216 … … 2229 2272 PLUGIN_CODECOMPLETION = 0x00040000, /// EnticePluginInfo flag: A plugin sets this if it provides code autocompletion. 2230 2273 PLUGIN_CODELAYOUTTAB = 0x00080000, /// EnticePluginInfo flag: A plugin sets this if it provides code layout for open files. 2274 2275 PLUGIN_DEFAULT2 = 0x00100000, /// EnticePluginInfo flag: A plugin sets this to be between a PLUGIN_DEFAULT plugin and a normal one. Built-in plugins set this. 2276 2277 PLUGIN_SAFEUNLOAD = 0x00200000, /// EnticePluginInfo flag: A plugin sets this if it can be unloaded safely while Entice continues to run. 2278 2279 /// Mask of all bits that indicate a unique feature. 2280 MASK_PLUGIN_UNIQUE_FEATURES = PLUGIN_PROJECT_COMPILE 2281 | PLUGIN_PROJECT_LIST 2282 | PLUGIN_CODECOMPLETION 2283 | PLUGIN_CODELAYOUTTAB 2284 , 2285 2231 2286 } 2232 2287 … … 2244 2299 } 2245 2300 2246 auto loadproc = cast(EnticePluginLoadProc)getPluginProcAddr(hmod, "enticePluginLoad", 1); 2247 if(!loadproc) 2301 auto infoproc = cast(EnticePluginInfoProc)getPluginProcAddr(hmod, "enticePluginInfo", 1); 2302 if(!infoproc) 2303 infoproc = cast(EnticePluginInfoProc)getPluginProcAddr(hmod, "enticePluginLoad", 1); 2304 if(!infoproc) 2248 2305 { 2249 2306 FreeLibrary(hmod); … … 2261 2318 try 2262 2319 { 2263 switch( loadproc(&ep))2320 switch(infoproc(&ep)) 2264 2321 { 2265 2322 case 0: … … 2334 2391 { 2335 2392 if(modalPlugin) 2393 { 2394 FreeLibrary(hmod); 2395 errnum = 10; 2336 2396 return "Unable to load plugin; already a modal plugin"; 2397 } 2337 2398 } 2338 2399 … … 2340 2401 { 2341 2402 if(codeLayoutTabPlugin) 2403 { 2404 FreeLibrary(hmod); 2405 errnum = 10; 2342 2406 return "Unable to load plugin; already a code layout tab plugin"; 2407 } 2343 2408 } 2344 2409 trunk/win32/entice/projectmanager.d
r101 r102 9 9 { 10 10 char[] name; 11 EProject project; 11 12 12 13 // null if cannot contain sub entries. … … 91 92 { 92 93 EProjectEntry pe; 94 pe.project = this; 93 95 //pe.name = std.path.join(projectName, de.name); 94 96 pe.name = de.name.dup; … … 109 111 { 110 112 EProjectEntry pe; 113 pe.project = tthis.project; 111 114 pe.name = std.path.join(tthis.name, de.name); 112 115 if(de.isdir()) trunk/win32/entice/proppanel.d
r101 r102 671 671 this.clientSize.width - TEXT_PADDING * 2, 13), tfmtTitle); 672 672 673 char[] infotxt; 674 infotxt = info; 675 if(!info.length) 676 infotxt = "No information provided."; 677 678 ea.graphics.drawText(infotxt, this.font, this.foreColor, Rect(TEXT_PADDING, INFO_TEXT_OFFSET_Y, 679 this.clientSize.width - TEXT_PADDING * 2, this.clientSize.height - INFO_TEXT_OFFSET_Y - TEXT_PADDING * 2), 680 tfmtInfo); 673 if(info.length) 674 { 675 ea.graphics.drawText(info, this.font, this.foreColor, Rect(TEXT_PADDING, INFO_TEXT_OFFSET_Y, 676 this.clientSize.width - TEXT_PADDING * 2, this.clientSize.height - INFO_TEXT_OFFSET_Y - TEXT_PADDING * 2), 677 tfmtInfo); 678 } 681 679 } 682 680 trunk/win32/entice/scintilladlex.d
r101 r102 605 605 void addItem(ApiEntry* ae) 606 606 { 607 if(ae.flags & ApiFlags.PRIVATE) 608 return; 609 if(ae.flags & ApiFlags.UNDOCUMENTED) 610 return; 611 607 612 char[] aename; 608 613 aename = ae.name; // cache … … 1898 1903 1899 1904 1905 bool findBraceMatch(out int istart, out int iend) 1906 { 1907 bit again = true; 1908 istart = sendEditor(SCI_GETCURRENTPOS); 1909 if(!istart) 1910 again = false; 1911 else 1912 istart--; 1913 iend = sendEditor(SCI_BRACEMATCH, istart); 1914 if(-1 != iend) 1915 { 1916 return true; 1917 } 1918 else 1919 { 1920 if(again) 1921 { 1922 again = false; 1923 istart++; 1924 iend = sendEditor(SCI_BRACEMATCH, istart); 1925 if(-1 != iend) 1926 { 1927 return true; 1928 } 1929 } 1930 } 1931 return false; 1932 } 1933 1934 1900 1935 // Called when WM_NOTIFY is sent to the parent for this control. 1901 1936 /+ package +/ final void notified(inout Message m) … … 1911 1946 case SCN_UPDATEUI: 1912 1947 { 1913 bit again = true;1948 1914 1949 int istart, iend; 1915 istart = sendEditor(SCI_GETCURRENTPOS); 1916 if(!istart) 1917 again = false; 1918 else 1919 istart--; 1920 iend = sendEditor(SCI_BRACEMATCH, istart); 1921 if(-1 != iend) 1950 if(findBraceMatch(istart, iend)) 1922 1951 { 1923 found_match_brace:1924 1952 sendEditor(SCI_BRACEHIGHLIGHT, istart, iend); 1925 1953 … … 1934 1962 else 1935 1963 { 1936 if(again)1937 {1938 again = false;1939 istart++;1940 iend = sendEditor(SCI_BRACEMATCH, istart);1941 if(-1 != iend)1942 goto found_match_brace;1943 }1944 1945 1964 // Clear. 1946 1965 sendEditor(SCI_BRACEHIGHLIGHT, -1, -1); … … 2593 2612 needScan = false; // Done! No need to re-scan! 2594 2613 2595 sendEditor(SCI_EMPTYUNDOBUFFER); // Since it can't be undone yet... 2614 version(ENTICE_DESIGNUNDO) 2615 { 2616 } 2617 else 2618 { 2619 sendEditor(SCI_EMPTYUNDOBUFFER); // Since it can't be undone. 2620 } 2596 2621 2597 2622 /+ … … 2601 2626 } 2602 2627 +/ 2628 } 2629 2630 2631 final void beginDesignUpdate() 2632 { 2633 version(ENTICE_DESIGNUNDO) 2634 { 2635 sendEditor(SCI_BEGINUNDOACTION); 2636 } 2637 } 2638 2639 2640 final void endDesignUpdate() 2641 { 2642 version(ENTICE_DESIGNUNDO) 2643 { 2644 sendEditor(SCI_ENDUNDOACTION); 2645 } 2603 2646 } 2604 2647 … … 2869 2912 needScan = true; 2870 2913 2871 sendEditor(SCI_EMPTYUNDOBUFFER); // Since it can't be undone yet... 2914 version(ENTICE_DESIGNUNDO) 2915 { 2916 } 2917 else 2918 { 2919 sendEditor(SCI_EMPTYUNDOBUFFER); // Since it can't be undone. 2920 } 2872 2921 } 2873 2922 trunk/win32/entice/scistyles.d
r101 r102 4 4 5 5 private import std.string, std.ctype, std.conv; 6 private import dfl.all, dfl. winapi;6 private import dfl.all, dfl.internal.winapi; 7 7 private import dfl.scintilla, dfl.cpp.scintilla, dfl.cpp.scilexer; 8 8 private import util, drawing; trunk/win32/entice/startpage.d
r101 r102 9 9 std.gc, std.utf, std.stdint; 10 10 11 private import dfl.all, dfl. winapi, dfl.utf;11 private import dfl.all, dfl.internal.winapi, dfl.internal.utf; 12 12 private import dfl.scintilla, dfl.cpp.scintilla, dfl.cpp.scilexer; 13 13 … … 23 23 import ddprojectmanager, projectmanager; 24 24 25 import compile, firstsetupstartpagepanel; 26 25 27 import rgroup; 26 28 … … 108 110 109 111 int addStartPage() 110 in111 112 { 112 113 //assert(showStartPage); // NO... user must have manually requested it. 113 114 //assert(!startPageClosed); 114 } 115 body 116 { 115 117 116 skipStartPage = false; 118 117 getStartPage(); // Create startent. … … 143 142 144 143 145 class StartPageLabel: Label144 class StartPageLabel: Panel //: Label 146 145 { 147 146 const char[] FONT_NAME = "Tahoma"; … … 158 157 char[] tipFileName; 159 158 bool clickMoreTips = true; 159 160 FirstSetupStartPagePanel fsspp; 160 161 161 162 … … 194 195 stepZEROfmt = TextFormat.genericDefault; 195 196 stepZEROfmt.formatFlags = stepZEROfmt.formatFlags & ~TextFormatFlags.WORD_BREAK; 197 198 /*{ 199 struct imp { public import dlangselectorpanel; } 200 auto panel = new imp.DLangSelectorPanel(); 201 panel.backColor = SystemColors.control; 202 panel.foreColor = SystemColors.controlText; 203 panel.location = Point(10, 300); 204 panel.parent = this; 205 }*/ 206 207 setStyle(ControlStyles.ALL_PAINTING_IN_WM_PAINT | ControlStyles.USER_PAINT, true); 196 208 } 197 209 … … 207 219 protected override void onPaintBackground(PaintEventArgs ea) 208 220 { 209 //super.onPaintBackground(ea);221 super.onPaintBackground(ea); 210 222 } 211 223 … … 245 257 246 258 247 const int TIPS_TOP = 1 80;248 const int TIPS_HEIGHT = 140;259 const int TIPS_TOP = 110; 260 const int TIPS_HEIGHT = 32; 249 261 250 262 … … 504 516 curTip = loadRandomLine(tipFileName, false); 505 517 if(parent) 506 parent.invalidate(Rect(0, TIPS_TOP - 30, this.clientSize.width, TIPS_HEIGHT + 60), true); 507 } 508 } 518 parent.invalidate(Rect(0, TIPS_TOP - 30, this.clientSize.width + 80, TIPS_HEIGHT + 60), true); 519 } 520 } 521 509 522 } 510 523 … … 591 604 EProjectControl proj; 592 605 606 FirstSetupStartPagePanel fsspp = null; 607 593 608 594 609 // IHasEProjectControl … … 718 733 propInfo.setInfo("Recently Used Files", "Double click on a file from the above list to open it."); 719 734 } 735 736 _compilercheck(); 737 } 738 739 740 private void _compilercheck() 741 { 742 if(isCompilerSetup()) 743 { 744 if(fsspp) 745 { 746 fsspp.dispose(); 747 fsspp = null; 748 } 749 } 750 else 751 { 752 if(!fsspp) 753 { 754 string thiscompilerpath = ""; 755 foreachLocateDMD( 756 (string path) 757 { 758 // Just get first one (if any). 759 thiscompilerpath = path; 760 return false; // Break. 761 }); 762 fsspp = new FirstSetupStartPagePanel(thiscompilerpath); 763 fsspp.backColor = SystemColors.control; 764 fsspp.foreColor = SystemColors.controlText; 765 fsspp.location = Point(10, 150); 766 fsspp.parent = ctrl; 767 } 768 } 720 769 } 721 770 trunk/win32/entice/tabber.d
r101 r102 2 2 // See the included enticesourcelicense.txt for copyright and license details. 3 3 4 5 private import dfl.all, dfl.winapi; 4 // Tab detaching hasn't been fully tested. 5 6 version(TABBER_SIMPLE) 7 { 8 version = TABBER_NO_DETACH; 9 version = TABBER_NO_FIT_TEXT; 10 } 11 12 13 private import dfl.all, dfl.internal.winapi; 6 14 7 15 … … 21 29 } 22 30 31 this(char[] text, bool detached) 32 { 33 _txt = text; 34 version(TABBER_NO_DETACH) 35 { 36 if(detached) 37 throw new Exception("Cannot detach this tab"); 38 } 39 else 40 { 41 _detached = detached; 42 } 43 } 44 23 45 24 46 final char[] text() // getter … … 40 62 41 63 42 // Called whenever this tab should be hidden. 43 // It is also called before removing it from the Tabber. 44 // If this function throws an exception, the removal will fail. 64 final bool detached() // getter 65 { 66 return _detached; 67 } 68 69 70 /// Called whenever this tab should be hidden. 71 /// It is also called before removing it from the Tabber. 72 /// If this function throws an exception, the removal will fail. 45 73 void onHide(Tabber tabc, int index) 46 74 { … … 48 76 49 77 50 // Called when this tab should be shown.51 // It is also called after adding it to the Tabber.78 /// Called when this tab should be shown. 79 /// It is also called after adding it to the Tabber. 52 80 void onShow(Tabber tabc, int index) 81 { 82 } 83 84 85 /// Called when this tab is being detached. 86 /// This is also called when a detached tab is added. 87 void onDetach(Tabber tabc, int index) 88 { 89 } 90 91 92 /// Called when this tab is being re-attached. 93 /// This is also called when an attached tab is added. 94 void onAttach(Tabber tabc, int index) 53 95 { 54 96 } … … 59 101 Object _tag = null; 60 102 int _width = 0; // Includes padding, so 0 is uninitialized. 103 version(TABBER_NO_DETACH) 104 const bool _detached = false; 105 else 106 bool _detached = false; 61 107 } 62 108 … … 67 113 { 68 114 setStyle(ControlStyles.CONTAINER_CONTROL, true); 115 //setStyle(ControlStyles.ALL_PAINTING_IN_WM_PAINT | ControlStyles.USER_PAINT, true); 69 116 70 117 calcTheight(); … … 227 274 { 228 275 return _allowuserdrag; 276 } 277 278 279 final bool detachTab(int index) 280 { 281 version(TABBER_NO_DETACH) 282 { 283 throw new Exception("Cannot detach this tab"); 284 } 285 else 286 { 287 if(!_tabs[index]._detached) 288 { 289 _tabs[index]._detached = true; 290 if(index != selidx) 291 { 292 showing(_tabs[index], index); 293 } 294 295 if(index == selidx) 296 { 297 selTabGone(); 298 299 onSelectedIndexAffected(EventArgs.empty); 300 if(-1 != selidx) // Can happen. 301 showing(_tabs[selidx], selidx); 302 } 303 304 _tabs[index].onDetach(this, index); 305 306 if(isHandleCreated) 307 { 308 recalcTabs(); 309 310 redrawTabs(); 311 } 312 313 return true; 314 } 315 } 316 return false; 317 } 318 319 320 final bool attachTab(int index) 321 { 322 version(TABBER_NO_DETACH) 323 { 324 } 325 else 326 { 327 if(_tabs[index]._detached) 328 { 329 _tabs[index]._detached = false; 330 if(-1 == selidx) 331 { 332 selidx = index; 333 onSelectedIndexAffected(EventArgs.empty); 334 } 335 if(index != selidx) 336 { 337 hiding(_tabs[index], index); 338 } 339 340 _tabs[index].onAttach(this, index); 341 342 if(isHandleCreated) 343 { 344 recalcTabs(); 345 346 redrawTabs(); 347 } 348 349 return true; 350 } 351 } 352 return false; 229 353 } 230 354 … … 247 371 onTabAdded(ea); 248 372 249 if(1 == _tabs.length) 250 { 251 assert(!i); 252 selidx = 0; 253 254 onSelectedIndexAffected(EventArgs.empty); 255 showing(t, 0); //showing(_tabs[0], i); 373 if(-1 == selidx) 374 { 375 if(!t._detached) 376 { 377 selidx = i; 378 onSelectedIndexAffected(EventArgs.empty); 379 showing(t, i); 380 } 256 381 } 257 382 else if(i <= selidx) … … 262 387 } 263 388 264 if(isHandleCreated) 389 if(t._detached) 390 _tabs[i].onDetach(this, i); 391 else 392 _tabs[i].onAttach(this, i); 393 394 if(t._detached) 395 { 396 showing(t, i); 397 } 398 399 if(isHandleCreated && !t._detached) 265 400 { 266 401 recalcTabs(); … … 276 411 { 277 412 return insertTab(i, new Tab(text)); 413 } 414 415 416 private void selTabGone() 417 { 418 // Current tab is gone so make sure newly selected one isn't detached. 419 // Check current or scan back to find non-detached tab. 420 bool foundgoodtab = false; 421 for(int i = selidx; i >= 0; i--) 422 { 423 if(!_tabs[i]._detached) 424 { 425 selidx = i; 426 foundgoodtab = true; 427 break; 428 } 429 } 430 if(!foundgoodtab) 431 { 432 // No non-detached ones before, so look after. 433 for(int i = selidx + 1; i < _tabs.length; i++) 434 { 435 if(!_tabs[i]._detached) 436 { 437 selidx = i; 438 foundgoodtab = true; 439 break; 440 } 441 } 442 if(!foundgoodtab) 443 { 444 // No non-detached tabs, no selection. 445 selidx = -1; 446 } 447 } 278 448 } 279 449 … … 287 457 288 458 Tab rtab = _tabs[index]; 289 if(selaff )459 if(selaff || rtab._detached) 290 460 { 291 461 hiding(rtab, index); … … 316 486 } 317 487 488 if(selaff) 489 { 490 selTabGone(); 491 } 492 318 493 scope ea = new TabEventArgs(rtab); 319 494 onTabRemoved(ea); … … 326 501 } 327 502 328 if(isHandleCreated )503 if(isHandleCreated && !rtab._detached) 329 504 { 330 505 recalcTabs(); … … 337 512 final void replaceAllTabs(Tab[] newTabs, int newSelectedIndex = -1) 338 513 { 339 bool selaff = false; 340 if(_tabs.length) 341 { 342 assert(-1 != selidx); 343 selaff = true; 344 hiding(_tabs[selidx], selidx); 514 bool selaff = -1 != selidx; 515 for(int i = 0; i < _tabs.length; i++) 516 { 517 if(selidx == i || _tabs[i]._detached) 518 { 519 hiding(_tabs[i], i); 520 } 345 521 } 346 522 … … 359 535 _tabs = newTabs; 360 536 361 //assert(newSelectedIndex >= 0);362 //assert(newSelectedIndex < newTabs.length);363 537 if(newSelectedIndex < 0 || newSelectedIndex >= newTabs.length) 364 newSelectedIndex = 0; 538 { 539 // No explicit selection set. 540 // Default select first non-detached tab. 541 // If all detached, leave -1 542 newSelectedIndex = -1; 543 for(int i = 0; i < _tabs.length; i++) 544 { 545 if(!_tabs[i]._detached) 546 { 547 newSelectedIndex = i; 548 break; 549 } 550 } 551 } 365 552 selidx = newSelectedIndex; 366 selaff = true; 367 showing(_tabs[selidx], selidx); 553 if(-1 != selidx) 554 { 555 selaff = true; 556 showing(_tabs[selidx], selidx); 557 } 558 559 // Show all detached tabs. 560 // Not selidx in case user selected a detached one, 561 // it would be shown above already. 562 for(int i = 0; i < _tabs.length; i++) 563 { 564 if(_tabs[i]._detached && i != selidx) 565 { 566 showing(_tabs[i], i); 567 } 568 } 368 569 } 369 570 … … 393 594 _tabs[i]._txt = newText; 394 595 395 if(isHandleCreated )596 if(isHandleCreated && !_tabs[i].detached) 396 597 { 397 598 recalcTabs(); … … 447 648 448 649 449 version(TABBER_ SIMPLE)650 version(TABBER_NO_FIT_TEXT) 450 651 { 451 652 private void recalcTabs() 452 in453 653 { 454 654 assert(isHandleCreated); 455 } 456 body 457 { 655 458 656 Graphics g; 459 657 g = createGraphics(); … … 461 659 foreach(Tab t; _tabs) 462 660 { 463 tab._width = calcTextWidth(g, t.text) + TAB_PADDING * 2; 661 if(t._detached) 662 { 663 tab._width = 0; 664 } 665 else 666 { 667 tab._width = calcTextWidth(g, t.text) + TAB_PADDING * 2; 668 } 464 669 } 465 670 … … 470 675 { 471 676 private void recalcTabs() 472 in473 677 { 474 678 assert(isHandleCreated); 475 } 476 body 477 { 679 478 680 if(!_tabs.length || !clientSize.width) 479 681 return; … … 487 689 foreach(Tab t; _tabs) 488 690 { 489 t._width = calcTextWidth(g, t.text) + TAB_PADDING * 2; 490 491 x += t._width + TAB_PADDING; 691 if(t._detached) 692 { 693 t._width = 0; 694 } 695 else 696 { 697 t._width = calcTextWidth(g, t.text) + TAB_PADDING * 2; 698 699 x += t._width + TAB_PADDING; 700 } 492 701 } 493 702 … … 502 711 foreach(Tab t; _tabs) 503 712 { 504 if(t._width > aw)713 //if(!t._detached) // Detached t._width is always 0 for next comparison. 505 714 { 506 int less; 507 less = t._width - aw; // Take away the excess of the above average. 508 509 t._width -= less; // Smaller tab. 510 511 x -= less; // For next trip around. 715 if(t._width > aw) 716 { 717 int less; 718 less = t._width - aw; // Take away the excess of the above average. 719 720 t._width -= less; // Smaller tab. 721 722 x -= less; // For next trip around. 723 } 512 724 } 513 725 } … … 524 736 final void getAllTabRects(void delegate(int index, inout Rect tabRect) callback) 525 737 { 526 //Rect getTabsRect()527 738 Rect r, tabRect; 528 739 r = getTabsRect(); 529 740 // Using position -1 for detached tabs, 741 // this way the point doesn't match with other tabs (e.g. findTabFromPoint) 530 742 if(tright) 531 743 { … … 533 745 foreach_reverse(int i, Tab tab; _tabs) 534 746 { 535 r.x -= tab._width + TAB_PADDING; 536 537 tabRect.x = r.x; 538 tabRect.y = r.y; 539 tabRect.width = tab._width; 540 tabRect.height = r.height; 541 747 if(tab._detached) 748 { 749 tabRect = Rect(-1, 0, 0, 0); 750 } 751 else 752 { 753 r.x -= tab._width + TAB_PADDING; 754 tabRect.x = r.x; 755 tabRect.y = r.y; 756 tabRect.width = tab._width; 757 tabRect.height = r.height; 758 } 542 759 callback(i, tabRect); 543 760 } … … 547 764 foreach(int i, Tab tab; _tabs) 548 765 { 549 tabRect.x = r.x; 550 tabRect.y = r.y; 551 tabRect.width = tab._width; 552 tabRect.height = r.height; 553 766 if(tab._detached) 767 { 768 tabRect = Rect(-1, 0, 0, 0); 769 } 770 else 771 { 772 tabRect.x = r.x; 773 tabRect.y = r.y; 774 tabRect.width = tab._width; 775 tabRect.height = r.height; 776 r.x += tabRect.width + TAB_PADDING; 777 } 554 778 callback(i, tabRect); 555 556 r.x += tabRect.width + TAB_PADDING;557 779 } 558 780 } … … 561 783 562 784 final void getAllTabRects(Rect[] buf) 563 in564 785 { 565 786 assert(buf.length >= _tabs.length); 566 } 567 body 568 { 787 569 788 getAllTabRects( 570 789 (int i, inout Rect r) … … 702 921 (int i, inout Rect tabRect) 703 922 { 923 if(_tabs[i].detached) 924 return; 704 925 txt = _tabs[i].text; 705 926 tw = tabRect.width - TAB_PADDING * 2; … … 974 1195 975 1196 auto newtabs = _tabs.dup; 1197 int imovebegin, imoveend; 976 1198 if(iovernow > _userMovingTab) 977 1199 { 1200 imovebegin = _userMovingTab; 1201 imoveend = iovernow; 978 1202 for(auto mi = _userMovingTab; mi != iovernow; mi++) 979 1203 { … … 985 1209 else //if(_userMovingTab > iovernow) 986 1210 { 1211 imovebegin = iovernow; 1212 imoveend = _userMovingTab; 987 1213 for(auto mi = _userMovingTab; mi != iovernow; mi--) 988 1214 { … … 997 1223 selidx = _userMovingTab; // ! 998 1224 999 //invalidate(getTabsRect(), false); // Not good enough; doesn't fix the line under the tabs. 1000 invalidate(Rect(0, tbottom ? (clientSize.height - theight) : 0, getTabsRect().width + 4, theight), false); 1225 // Whole bar: 1226 //invalidate(Rect(0, tbottom ? (clientSize.height - theight) : 0, getTabsRect().width + 4, theight), false); 1227 // Just the tabs involved in the move: 1228 { 1229 int movebeginx = 0, movewidth = 0; 1230 getAllTabRects( 1231 (int i, inout Rect tabRect) 1232 { 1233 if(i == imovebegin) 1234 { 1235 movebeginx = tabRect.x; 1236 } 1237 if(i >= imovebegin && i <= imoveend) 1238 { 1239 movewidth += tabRect.width; 1240 } 1241 }); 1242 invalidate(Rect(movebeginx - 6, tbottom ? (clientSize.height - theight) : 0, movewidth + 6 + 6, theight), false); 1243 } 1001 1244 1002 1245 scope udea = new TabIndexEventArgs(_userMovingTab, tabs[_userMovingTab]); … … 1117 1360 1118 1361 private void redrawTabs() 1119 in1120 1362 { 1121 1363 assert(isHandleCreated); 1122 } 1123 body 1124 { 1364 1125 1365 Rect r; 1126 1366 … … 1411 1651 { 1412 1652 this(int fromIndex, int toIndex) 1413 in1414 1653 { 1415 1654 assert(fromIndex >= 0); 1416 1655 assert(toIndex >= 0); 1417 } 1418 body 1419 { 1656 1420 1657 this._fromindex = fromIndex; 1421 1658 this._toindex = toIndex; … … 1439 1676 } 1440 1677 1678 1679 class DetachedTabForm: Form 1680 { 1681 this() 1682 { 1683 clientSize = Size(500, 400); 1684 } 1685 1686 1687 this(Tabber tabc, Tab tab) 1688 { 1689 this(); 1690 text = tab.text; 1691 if(!tab._detached) 1692 throw new Exception("Tab is not detached"); 1693 debug 1694 { 1695 if(-1 == tabc.findTab(tab)) 1696 throw new Exception("Tab not found"); 1697 } 1698 version(TABBER_NO_DETACH) 1699 { 1700 } 1701 else 1702 { 1703 this.tabc = tabc; 1704 this.tab = tab; 1705 } 1706 } 1707 1708 1709 version(TABBER_NO_DETACH) 1710 { 1711 } 1712 else 1713 { 1714 1715 override void onClosing(CancelEventArgs ea) 1716 { 1717 super.onClosing(ea); 1718 1719 if(!ea.cancel) 1720 { 1721 int ti = tabc.findTab(tab); 1722 if(-1 != ti) 1723 tabc.attachTab(ti); 1724 } 1725 } 1726 1727 1728 private Tabber tabc; 1729 private Tab tab; 1730 1731 } 1732 1733 } 1734 trunk/win32/entice/toolbox.d
r101 r102 5 5 private import std.string; 6 6 7 private import dfl.all, dfl. winapi;7 private import dfl.all, dfl.internal.winapi; 8 8 9 9 private import dfldesigner, design; … … 514 514 // Only the pointer tool gets a null type name. 515 515 this(Icon icon, char[] typeName, char[] toolName) 516 in517 516 { 518 517 assert(toolName.length); 519 } 520 body 521 { 518 522 519 _icon = icon; 523 520 _typeName = typeName; … … 528 525 529 526 this(Icon icon, char[] typeName) 530 in531 527 { 532 528 assert(typeName.length); 533 } 534 body 535 { 529 536 530 int i; 537 531 i = std.string.rfind(typeName, '.'); trunk/win32/entice/usercomment.d
r101 r102 5 5 import std.string; 6 6 7 private import dfl.all, dfl. winapi;7 private import dfl.all, dfl.internal.winapi; 8 8 9 9 import dfldesigner, resource; … … 334 334 commentGroup.name = "commentGroup"; 335 335 commentGroup.text = "Send Application Developers a Comment About:"; 336 commentGroup.bounds = dfl. base.Rect(8, 40, 520, 312);336 commentGroup.bounds = dfl.all.Rect(8, 40, 520, 312); 337 337 commentGroup.parent = this; 338 338 //~DFL dfl.button.RadioButton=likeRadio … … 341 341 likeRadio.text = "Something you &like"; 342 342 likeRadio.checkState = dfl.button.CheckState.CHECKED; 343 likeRadio.bounds = dfl. base.Rect(28, 17, 283, 23);343 likeRadio.bounds = dfl.all.Rect(28, 17, 283, 23); 344 344 likeRadio.parent = commentGroup; 345 345 //~DFL dfl.button.RadioButton=hateRadio … … 347 347 hateRadio.name = "hateRadio"; 348 348 hateRadio.text = "Something you &dislike"; 349 hateRadio.bounds = dfl. base.Rect(28, 41, 283, 23);349 hateRadio.bounds = dfl.all.Rect(28, 41, 283, 23); 350 350 hateRadio.parent = commentGroup; 351 351 //~DFL dfl.button.RadioButton=bugRadio … … 353 353 bugRadio.name = "bugRadio"; 354 354 bugRadio.text = "An improper &behavior of this application"; 355 bugRadio.bounds = dfl. base.Rect(28, 65, 283, 23);355 bugRadio.bounds = dfl.all.Rect(28, 65, 283, 23); 356 356 bugRadio.parent = commentGroup; 357 357 //~DFL dfl.button.RadioButton=requestRadio … … 359 359 requestRadio.name = "requestRadio"; 360 360 requestRadio.text = "A new &feature you desire"; 361 requestRadio.bounds = dfl. base.Rect(28, 89, 283, 23);361 requestRadio.bounds = dfl.all.Rect(28, 89, 283, 23); 362 362 requestRadio.parent = commentGroup; 363 363 //~DFL dfl.textbox.TextBox=commentBox … … 369 369 commentBox.acceptsReturn = true; 370 370 commentBox.scrollBars = dfl.base.ScrollBars.VERTICAL; 371 commentBox.bounds = dfl. base.Rect(12, 116, 496, 184);371 commentBox.bounds = dfl.all.Rect(12, 116, 496, 184); 372 372 commentBox.parent = commentGroup; 373 373 //~DFL dfl.label.Label=topLabel … … 375 375 topLabel.name = "topLabel"; 376 376 topLabel.text = "Please provide a brief opinion of %s so that we will be able to improve your user experience. Positive and negative comments are welcome. Bug reports are especially helpful."; 377 topLabel.bounds = dfl. base.Rect(8, 8, 520, 32);377 topLabel.bounds = dfl.all.Rect(8, 8, 520, 32); 378 378 topLabel.parent = this; 379 379 //~DFL dfl.button.Button=emailBtn … … 381 381 emailBtn.name = "emailBtn"; 382 382 emailBtn.text = "&E-mail Address..."; 383 emailBtn.bounds = dfl. base.Rect(8, 360, 115, 23);383 emailBtn.bounds = dfl.all.Rect(8, 360, 115, 23); 384 384 emailBtn.parent = this; 385 385 //~DFL dfl.button.Button=sendBtn … … 388 388 sendBtn.enabled = false; 389 389 sendBtn.text = "&Send Comment"; 390 sendBtn.bounds = dfl. base.Rect(336, 360, 107, 23);390 sendBtn.bounds = dfl.all.Rect(336, 360, 107, 23); 391 391 sendBtn.parent = this; 392 392 //~DFL dfl.button.Button=cancelBtn … … 394 394 cancelBtn.name = "cancelBtn"; 395 395 cancelBtn.text = "Cancel"; 396 cancelBtn.bounds = dfl. base.Rect(456, 360, 75, 23);396 cancelBtn.bounds = dfl.all.Rect(456, 360, 75, 23); 397 397 cancelBtn.parent = this; 398 398 //~Entice Designer 0.8pre5 code ends here. trunk/win32/entice/usercommentemail.d
r101 r102 81 81 preface.name = "preface"; 82 82 preface.text = "Please provide your &e-mail address so that we may contact you in response to your comment if needed. We will not contact you for any other reason and your e-mail address will not be sold or given away. However, you do not need to provide your e-mail address for anonymous comments."; 83 preface.bounds = dfl. base.Rect(8, 8, 288, 69);83 preface.bounds = dfl.all.Rect(8, 8, 288, 69); 84 84 preface.parent = this; 85 85 //~DFL dfl.textbox.TextBox=emailBox … … 87 87 emailBox.name = "emailBox"; 88 88 emailBox.maxLength = 500; 89 emailBox.bounds = dfl. base.Rect(8, 80, 288, 23);89 emailBox.bounds = dfl.all.Rect(8, 80, 288, 23); 90 90 emailBox.parent = this; 91 91 //~DFL dfl.button.Button=okBtn … … 93 93 okBtn.name = "okBtn"; 94 94 okBtn.text = "OK"; 95 okBtn.bounds = dfl. base.Rect(144, 112, 75, 23);95 okBtn.bounds = dfl.all.Rect(144, 112, 75, 23); 96 96 okBtn.parent = this; 97 97 //~DFL dfl.button.Button=cancelBtn … … 99 99 cancelBtn.name = "cancelBtn"; 100 100 cancelBtn.text = "Cancel"; 101 cancelBtn.bounds = dfl. base.Rect(224, 112, 75, 23);101 cancelBtn.bounds = dfl.all.Rect(224, 112, 75, 23); 102 102 cancelBtn.parent = this; 103 103 //~DFL dfl.button.Button=clearBtn … … 105 105 clearBtn.name = "clearBtn"; 106 106 clearBtn.text = "Clear"; 107 clearBtn.bounds = dfl. base.Rect(8, 112, 75, 23);107 clearBtn.bounds = dfl.all.Rect(8, 112, 75, 23); 108 108 clearBtn.parent = this; 109 109 //~Entice Designer 0.8pre4 code ends here. trunk/win32/entice/util.d
r101 r102 6 6 private import dfl.all; 7 7 8 9 /// Returns: the next word and updates line to exclude it. 10 char[] nextWord(inout char[] line) 11 { 12 if(!line.length) 13 return null; 14 15 char[] result; 16 uint i; 17 18 for(i = 0; i != line.length; i++) 19 { 20 if(line[i] == ' ') 21 { 22 // Found a word. 23 result = line[0 .. i]; 24 line = line[i + 1 .. line.length]; 25 return result; 26 } 27 } 28 29 // Fell through, last word. 30 result = line; 31 line = null; 32 return result; 8 private import dfl.internal.winapi : ShellExecuteA; 9 10 11 void resizeCenterForm(Form form, Size size, bool onlyGrow = false) 12 { 13 int wdiff = size.width - form.clientSize.width; 14 int hdiff = size.height - form.clientSize.height; 15 if(onlyGrow) 16 { 17 if(wdiff < 0) 18 { 19 wdiff = 0; 20 size = Size(form.clientSize.width, size.height); 21 } 22 if(hdiff < 0) 23 { 24 hdiff = 0; 25 size = Size(size.width, form.clientSize.height); 26 } 27 } 28 if(wdiff || hdiff) 29 { 30 form.bounds = Rect( 31 form.left + wdiff / 2, form.top + hdiff / 2, 32 size.width, size.height 33 ); 34 form.clientSize = size; 35 } 36 } 37 38 39 void launchUrl(char[] url) 40 { 41 if(cast(int)ShellExecuteA(null, "open", myStringz(url), null, null, 0) <= 32) 42 { 43 msgBox("Unable to open URL"); 44 } 45 46 /+ 47 ShellExecuteA(null, "open", "rundll32.exe", 48 std.string.toStringz("url.dll,FileProtocolHandler " ~ url), 49 null, SW_SHOWDEFAULT); 50 +/ 33 51 } 34 52 … … 80 98 } 81 99 assert(0); 82 }83 84 85 // s is the string to get modified; rep are char pairs, a char is mapped to the next one.86 char[] replacechars(char[] s, char[] rep ...)87 in88 {89 assert(0 == (rep.length % 2));90 }91 body92 {93 size_t irep;94 size_t iw;95 char[] result;96 for(iw = 0; iw != s.length; iw++)97 {98 for(irep = 0; irep < rep.length; irep += 2)99 {100 if(s[iw] == rep[irep])101 {102 result = s.dup;103 goto do_rep;104 }105 }106 }107 return s;108 for(; iw != s.length; iw++)109 {110 for(irep = 0; irep < rep.length; irep += 2)111 {112 if(s[iw] == rep[irep])113 {114 do_rep: // Jump in with valid iw and irep.115 result[iw] = rep[irep + 1];116 break;117 }118 }119 }120 return result;121 }122 123 unittest124 {125 assert("foobar" == replacechars("buuqar", 'u','o', 'q','b', 'b','f'));126 assert("foobar" == replacechars("foobar"));127 assert("foobar" == replacechars("foobar", 'x','y', 'a','a'));128 assert("foobar" == replacechars("foobaz", 'x','y', 'z','r'));129 }130 131 132 bool startswith(char[] str, char[] swith)133 {134 return swith.length <= str.length && str[0 .. swith.length] == swith;135 }136 137 unittest138 {139 assert(startswith("foobar", "foo"));140 assert(startswith("foobar", "f"));141 assert(startswith("foobar", "foobar"));142 143 assert(!startswith("foobar", "F"));144 assert(!startswith("foobar", "Foobar"));145 assert(!startswith("foobar", "oobar"));146 assert(!startswith("foobar", "ffoobar"));147 assert(!startswith("foobar", "foobare"));148 assert(!startswith("foobar", "foobarr"));149 }150 151 152 // s is the string to get modified; rep are string pairs, a string is mapped to the next one.153 char[] replacestrings(char[] s, char[][] rep ...)154 in155 {156 assert(0 == (rep.length % 2));157 }158 body159 {160 char[] result;161 size_t startiw, iw;162 for(iw = startiw = 0;; iw++)163 {164 at_iw: ;165 if(iw == s.length)166 break;167 for(size_t irep = 0; irep < rep.length; irep += 2)168 {169 if(0 == rep[irep].length)170 continue;171 if(startswith(s[iw .. $], rep[irep]))172 {173 if(iw)174 result ~= s[startiw .. iw];175 result ~= rep[irep + 1];176 iw += rep[irep].length;177 startiw = iw;178 goto at_iw;179 }180 }181 }182 if(0 == startiw)183 return s;184 if(startiw != iw)185 result ~= s[startiw .. $];186 return result;187 }188 189 unittest190 {191 assert("foobar" == replacestrings("foou", "","X", "u","bar"));192 assert("foobar" == replacestrings("foobar", "f","f"));193 assert("foobar" == replacestrings("foobar"));194 assert("foobar" == replacestrings("foobar"));195 assert("foobar" == replacestrings("foobar", "r","r"));196 assert("foobar" == replacestrings("FOOBAR", "FOOBAR","foobar"));197 assert("foobar" == replacestrings("foobar", "bare","X"));198 assert("foobar" == replacestrings("foobar", "F","X"));199 assert("foobar" == replacestrings("buuqar", "u","o", "q","b", "b","f"));200 }201 202 203 int isEolChar(char ch)204 {205 return '\r' == ch || '\n' == ch;206 100 } 207 101 … … 367 261 368 262 369 char* myStringz(char[] s)370 {371 if(!s.length)372 return "";373 374 // Check if already null terminated.375 if(!s.ptr[s.length]) // Disables bounds checking.376 return s.ptr;377 378 // Need to duplicate with null terminator.379 char[] result;380 result = new char[s.length + 1];381 result[s.length] = 0;382 result = result[0 .. s.length];383 result[] = s;384 return result.ptr;385 }386 387 388 263 // Allows you to create a bunch of nesting directories all at once. 389 264 // Make sure -dirpath- does not include a file on the end … … 544 419 545 420 // Other forms of path joins aren't for "absolute" paths. 546 // In those cases (and std.path.join), joining "C:" with "foo.txt" gives "C:foo.txt", 547 // this version gives "C:\foo.txt", an appropriate absolute path. 548 char[] pathJoinAbsolute(char[] first, char[] second) 549 { 550 if(!first.length) 551 return second; 552 if(!second.length) 553 return first; 554 555 if('/' == first[$ - 1]) 556 { 557 first_slash: ; 558 559 if('/' == second[0]) 560 { 561 firstsecond_slash: ; 562 return first ~ second[1 .. $]; 421 // In those cases (and std.path.join), joining "X:" with "foo.txt" gives "X:foo.txt", 422 // this version gives "X:\foo.txt", an appropriate absolute path. 423 // If currentDir is empty, the environment's current directory is used. 424 char[] pathJoinAbsolute(char[] first, char[] second, string currentDir = null) 425 { 426 first = getAbsolutePath(first, currentDir); 427 return std.path.join(first, second); 428 } 429 430 unittest 431 { 432 string curdir = r"d:\foo"; 433 assert(pathJoinAbsolute("", "", curdir) == r"d:\foo"); 434 assert(pathJoinAbsolute("bar", "", curdir) == r"d:\foo\bar"); 435 assert(pathJoinAbsolute("", "baz", curdir) == r"d:\foo\baz"); 436 assert(pathJoinAbsolute("X:", "foo.txt", curdir) == r"X:\foo.txt"); 437 assert(pathJoinAbsolute("bar", "baz", curdir) == r"d:\foo\bar\baz"); 438 } 439 440 441 bool isPathAbsolute(string p) 442 { 443 version(Windows) 444 { 445 if(p.length > 2 && p[1] == ':' 446 && (p[2] == '\\' || p[2] == '/')) 447 return true; 448 if(p.length >= 2 && p[0] == '\\' && p[1] == '\\') 449 return true; 450 return false; 451 } 452 else 453 { 454 return p.length && '/' == p[0]; 455 } 456 } 457 458 459 // If currentDir is empty, the environment's current directory is used. 460 string getAbsolutePath(string p, string currentDir = null) 461 { 462 if(isPathAbsolute(p)) 463 return p; 464 if(!currentDir.length) 465 currentDir = std.file.getcwd(); 466 if(!p.length) 467 return currentDir; 468 version(Windows) 469 { 470 if(p.length > 1 && p[1] == ':') 471 { 472 assert(p.length < 3 || (p[2] != '\\' && p[2] != '/')); 473 // Relative to current directory of specified drive. 474 // Could use env var "=X:" 475 if(currentDir.length > 1 && currentDir[1] == ':') 476 { 477 //return p[0 .. 2] ~ currentDir[2 .. $] ~ "\\" ~ p[2 .. $]; // Alt. 478 // Relative to current directory if current drive. 479 // Relative to drive root if not current drive. 480 if(rawlower(p[0]) == rawlower(currentDir[0])) 481 return currentDir ~ "\\" ~ p[2 .. $]; 482 return p[0 .. 2] ~ "\\" ~ p[2 .. $]; 483 } 484 throw new Exception("Unexpected current directory: " ~ currentDir); 485 } 486 else if(p.length > 0 487 && (p[0] == '/' || p[0] == '\\')) 488 { 489 // Relative to current drive. 490 if(currentDir.length > 1 && currentDir[1] == ':') 491 { 492 return currentDir[0 .. 2] ~ p; 493 } 494 throw new Exception("Unexpected current directory: " ~ currentDir); 563 495 } 564 496 else 565 497 { 566 version(Windows) 567 { 568 if('\\' == second[0]) 569 goto firstsecond_slash; 570 } 571 572 // First_slash, not firstsecond_slash.. 573 return first ~ second; 498 return std.path.join(currentDir, p); 574 499 } 575 500 } 576 501 else 577 502 { 578 version(Windows) 579 { 580 if('\\' == first[$ - 1]) 581 goto first_slash; 582 } 583 584 // Not first_slash.. 585 if('/' == second[0]) 586 { 587 second_slash: ; 588 return first ~ second; 589 } 590 else 591 { 592 version(Windows) 593 { 594 if('\\' == second[0]) 595 goto second_slash; 596 } 597 598 return first ~ std.path.sep ~ second; 599 } 600 } 503 return std.path.join(currentDir, p); 504 } 505 } 506 507 unittest 508 { 509 string curdir = r"d:\foo"; 510 assert(getAbsolutePath(r"C:\Bar", curdir) == r"C:\Bar"); 511 assert(getAbsolutePath(r"", curdir) == r"d:\foo"); 512 assert(getAbsolutePath(r"bar", curdir) == r"d:\foo\bar"); 513 assert(getAbsolutePath(r"bar\file.x", curdir) == r"d:\foo\bar\file.x"); 514 assert(getAbsolutePath(r"\all\your", curdir) == r"d:\all\your"); 515 //assert(getAbsolutePath(r"C:Bar", curdir) == r"C:\foo\Bar"); // Alt. 516 assert(getAbsolutePath(r"C:Bar", curdir) == r"C:\Bar"); 517 assert(getAbsolutePath(r"D:Bar", curdir) == r"d:\foo\Bar"); 601 518 } 602 519 … … 773 690 } 774 691 692 693 // s is the string to get modified; rep are char pairs, a char is mapped to the next one. 694 char[] replacechars(char[] s, char[] rep ...) 695 in 696 { 697 assert(0 == (rep.length % 2)); 698 } 699 body 700 { 701 size_t irep; 702 size_t iw; 703 char[] result; 704 for(iw = 0; iw != s.length; iw++) 705 { 706 for(irep = 0; irep < rep.length; irep += 2) 707 { 708 if(s[iw] == rep[irep]) 709 { 710 result = s.dup; 711 goto do_rep; 712 } 713 } 714 } 715 return s; 716 for(; iw != s.length; iw++) 717 { 718 for(irep = 0; irep < rep.length; irep += 2) 719 { 720 if(s[iw] == rep[irep]) 721 { 722 do_rep: // Jump in with valid iw and irep. 723 result[iw] = rep[irep + 1]; 724 break; 725 } 726 } 727 } 728 return result; 729 } 730 731 unittest 732 { 733 assert("foobar" == replacechars("buuqar", 'u','o', 'q','b', 'b','f')); 734 assert("foobar" == replacechars("foobar")); 735 assert("foobar" == replacechars("foobar", 'x','y', 'a','a')); 736 assert("foobar" == replacechars("foobaz", 'x','y', 'z','r')); 737 } 738 739 740 bool startswith(char[] str, char[] swith) 741 { 742 return swith.length <= str.length && str[0 .. swith.length] == swith; 743 } 744 745 unittest 746 { 747 assert(startswith("foobar", "foo")); 748 assert(startswith("foobar", "f")); 749 assert(startswith("foobar", "foobar")); 750 751 assert(!startswith("foobar", "F")); 752 assert(!startswith("foobar", "Foobar")); 753 assert(!startswith("foobar", "oobar")); 754 assert(!startswith("foobar", "ffoobar")); 755 assert(!startswith("foobar", "foobare")); 756 assert(!startswith("foobar", "foobarr")); 757 } 758 759 760 dchar rawlower(dchar ch) 761 { 762 if(ch >= 'A' && ch <= 'Z') 763 return 'a' + (ch - 'A'); 764 return ch; 765 } 766 767 unittest 768 { 769 assert(rawlower('a') == 'a'); 770 assert(rawlower('A') == 'a'); 771 assert(rawlower('f') == 'f'); 772 assert(rawlower('F') == 'f'); 773 assert(rawlower('w') == 'w'); 774 assert(rawlower('W') == 'w'); 775 assert(rawlower('5') == '5'); 776 assert(rawlower('!') == '!'); 777 assert(rawlower(' ') == ' '); 778 assert(rawlower('\0') == '\0'); 779 assert(rawlower('\u00FC') == '\u00FC'); 780 } 781 782 783 int findraw(void[] str, void[] find) 784 { 785 if(!find.length) 786 return 0; 787 byte[] s = cast(byte[])str; 788 byte[] f = cast(byte[])find; 789 findloop: 790 for(; s.length >= f.length; s = s[1 .. $]) 791 { 792 if(s[0] == f[0]) 793 { 794 for(int i = 1; i < f.length; i++) 795 { 796 if(s[i] != f[i]) 797 continue findloop; 798 } 799 return s.ptr - str.ptr; 800 } 801 } 802 return -1; 803 } 804 805 unittest 806 { 807 assert(findraw("foo", "bar") == -1); 808 assert(findraw("Foo", "BAR") == -1); 809 assert(findraw("foo", "O") == -1); 810 assert(findraw("foo", "oo") == 1); 811 assert(findraw("foo", "ou") == -1); 812 assert(findraw("foo", "ooo") == -1); 813 } 814 815 816 int ifindraw(void[] str, void[] find) 817 { 818 if(!find.length) 819 return 0; 820 ubyte[] s = cast(ubyte[])str; 821 ubyte[] f = cast(ubyte[])find; 822 findloop: 823 for(; s.length >= f.length; s = s[1 .. $]) 824 { 825 //printf("r = %x == %x ", (s[0]), (f[0]) ); 826 //printf("i = %x == %x ", (s[0] & ~32), (f[0] & ~32) ); 827 //printf("c = %c == %c \n", (s[0]), (f[0]) ); 828 if( 829 ((s[0] & ~32) == (f[0] & ~32) 830 && (s[0] == f[0] 831 || rawlower(s[0]) == rawlower(f[0]) 832 ) 833 ) 834 ) 835 { 836 for(int i = 1; i < f.length; i++) 837 { 838 if(rawlower(s[i]) != rawlower(f[i])) 839 continue findloop; 840 } 841 return s.ptr - str.ptr; 842 } 843 } 844 return -1; 845 } 846 847 unittest 848 { 849 assert(ifindraw("foo", "bar") == -1); 850 assert(ifindraw("Foo", "BAR") == -1); 851 assert(ifindraw("foo", "O") == 1); 852 assert(ifindraw("foo", "oo") == 1); 853 assert(ifindraw("foo", "OO") == 1); 854 assert(ifindraw("foo", "fOO") == 0); 855 assert(ifindraw("foo", "ou") == -1); 856 assert(ifindraw("foo", "ooo") == -1); 857 assert(ifindraw("foo", "fooo") == -1); 858 } 859 860 861 int findany(string s, string[] lookfor ...) 862 { 863 for(string ss = s; ss.length; ss = ss[1 .. $]) 864 { 865 for(int i = 0; i < lookfor.length; i++) 866 { 867 if(startswith(ss, lookfor[i])) 868 { 869 return ss.ptr - s.ptr; 870 } 871 } 872 } 873 return -1; 874 } 875 876 unittest 877 { 878 assert(findany("foobar", "foo") == 0); 879 assert(findany("foobar", "oo") == 1); 880 assert(findany("foobar", "b", "bar") == 3); 881 assert(findany("foobar", "b", "foo") == 0); 882 assert(findany("foobar", "foo", "b") == 0); 883 assert(findany("foobar", "x") == -1); 884 assert(findany("foobar", "x", "y", "x") == -1); 885 assert(findany("foobar", "x", "b") == 3); 886 assert(findany("foobar", "b", "b", "b", "b") == 3); 887 } 888 889 890 // s is the string to get modified; rep are string pairs, a string is mapped to the next one. 891 char[] replacestrings(char[] s, char[][] rep ...) 892 in 893 { 894 assert(0 == (rep.length % 2)); 895 } 896 body 897 { 898 char[] result; 899 size_t startiw, iw; 900 for(iw = startiw = 0;; iw++) 901 { 902 at_iw: ; 903 if(iw == s.length) 904 break; 905 for(size_t irep = 0; irep < rep.length; irep += 2) 906 { 907 if(0 == rep[irep].length) 908 continue; 909 if(startswith(s[iw .. $], rep[irep])) 910 { 911 if(iw) 912 result ~= s[startiw .. iw]; 913 result ~= rep[irep + 1]; 914 iw += rep[irep].length; 915 startiw = iw; 916 goto at_iw; 917 } 918 } 919 } 920 if(0 == startiw) 921 return s; 922 if(startiw != iw) 923 result ~= s[startiw .. $]; 924 return result; 925 } 926 927 unittest 928 { 929 assert("foobar" == replacestrings("foou", "","X", "u","bar")); 930 assert("foobar" == replacestrings("foobar", "f","f")); 931 assert("foobar" == replacestrings("foobar")); 932 assert("foobar" == replacestrings("foobar")); 933 assert("foobar" == replacestrings("foobar", "r","r")); 934 assert("foobar" == replacestrings("FOOBAR", "FOOBAR","foobar")); 935 assert("foobar" == replacestrings("foobar", "bare","X")); 936 assert("foobar" == replacestrings("foobar", "F","X")); 937 assert("foobar" == replacestrings("buuqar", "u","o", "q","b", "b","f")); 938 } 939 940 941 int isEolChar(char ch) 942 { 943 return '\r' == ch || '\n' == ch; 944 } 945 946 947 /// Returns: the next word and updates line to exclude it. 948 char[] nextWord(inout char[] line) 949 { 950 if(!line.length) 951 return null; 952 953 char[] result; 954 uint i; 955 956 for(i = 0; i != line.length; i++) 957 { 958 if(line[i] == ' ') 959 { 960 // Found a word. 961 result = line[0 .. i]; 962 line = line[i + 1 .. line.length]; 963 return result; 964 } 965 } 966 967 // Fell through, last word. 968 result = line; 969 line = null; 970 return result; 971 } 972 973 974 char* myStringz(char[] s) 975 { 976 if(!s.length) 977 return ""; 978 979 // Check if already null terminated. 980 if(!s.ptr[s.length]) // Disables bounds checking. 981 return s.ptr; 982 983 // Need to duplicate with null terminator. 984 char[] result; 985 result = new char[s.length + 1]; 986 result[s.length] = 0; 987 result = result[0 .. s.length]; 988 result[] = s; 989 return result.ptr; 990 } 991 992 993 // Makes path relative to the specialDir if possible. 994 // This version expects path and specialDir to be clean (cleanPath) 995 string getRelativePath_clean(string path, string specialDir) 996 { 997 int igooddir = 0; 998 int numparentdirs = 0; 999 for(int i = 0;; i++) 1000 { 1001 if(i == specialDir.length) 1002 { 1003 if(i == path.length) 1004 igooddir = i; 1005 else if('\\' == path[i]) 1006 igooddir = i + 1; 1007 break; 1008 } 1009 if(i == path.length) 1010 break; 1011 if(!fncharmatch(path[i], specialDir[i])) 1012 { 1013 if(igooddir) 1014 numparentdirs = 1; 1015 break; 1016 } 1017 // (i > 1) to exclude \\ from network path. 1018 if(i > 1 && '\\' == specialDir[i]) 1019 { 1020 igooddir = i + 1; 1021 } 1022 } 1023 if(igooddir) 1024 { 1025 // path[0 .. igooddir] are the common directories with specialDir 1026 for(int i = igooddir; i < specialDir.length; i++) 1027 { 1028 if('\\' == specialDir[i]) 1029 numparentdirs++; 1030 } 1031 if(numparentdirs) 1032 { 1033 char[] dots; 1034 for(int i = 0; i < numparentdirs; i++) 1035 { 1036 dots ~= r"..\"; 1037 } 1038 path = dots ~ path[igooddir .. $]; 1039 } 1040 else 1041 { 1042 path = path[igooddir .. $]; 1043 } 1044 } 1045 if(path.length == 2 && path[1] == ':') 1046 return path ~ "\\"; 1047 return path; 1048 } 1049 1050 // Makes path relative to the specialDir if possible. 1051 string getRelativePath(string path, string specialDir) 1052 { 1053 return getRelativePath_clean(cleanPath(path), cleanPath(specialDir)); 1054 } 1055 1056 unittest 1057 { 1058 assert(getRelativePath(r"C:\foo\bar", r"c:\foo") == r"bar"); 1059 assert(getRelativePath(r"C:\baz", r"c:\") == r"baz"); 1060 assert(getRelativePath(r"C:\FOO\Cat", r"c:\foo\bar\baz") == r"..\..\Cat"); 1061 assert(getRelativePath(r"C:\FOO\Cat", r"d:\foo\bar\baz") == r"C:\FOO\Cat"); 1062 assert(getRelativePath(r"C:\baz\", r"c:\") == r"baz"); 1063 //mixin(assertexpr!(`getRelativePath(r"C:\", r"c:\baz\") == r"..\"`)); 1064 mixin(assertexpr!(`getRelativePath(r"C:\", r"c:") == r""`)); 1065 } 1066 1067 1068 // Removes extra slashes/backslashes, 1069 // translates "." and "..". 1070 string cleanPath(string path) 1071 { 1072 if(!path.length) 1073 return ""; 1074 // Handle first char separately so it 1075 // allows network paths with two backslashes. 1076 char[] result = (new char[path.length])[0 .. 1]; 1077 { 1078 char ch = path[0]; 1079 if(ch == '/') 1080 ch = '\\'; 1081 result[0] = ch; 1082 } 1083 char prevchar = 0; 1084 int numdirdots = 0; 1085 if(result[0] == '.') 1086 numdirdots++; 1087 1088 void handledots() 1089 { 1090 mixin(assertexpr!((`numdirdots > 0`)));; 1091 int origdots = numdirdots; 1092 void baddots() 1093 { 1094 char[] dotchars = new char[origdots]; 1095 dotchars[] = '.'; 1096 throw new Exception("Unable to resolve '" ~ dotchars ~ "' in '" ~ path ~ "'"); 1097 } 1098 for(numdirdots--;; numdirdots--) 1099 { 1100 prevchar = 0; 1101 for(;;) 1102 { 1103 if(!result.length) 1104 break; 1105 if('\\' == result[$ - 1]) 1106 { 1107 result = result[0 .. $ - 1]; 1108 prevchar = '\\'; 1109 break; 1110 } 1111 result = result[0 .. $ - 1]; 1112 } 1113 if(numdirdots == 0) 1114 break; 1115 } 1116 if('\\' == prevchar) 1117 result ~= '\\'; 1118 if((!result.length || r"\\" == result) && origdots > 1) // e.g. `.\` was fine 1119 baddots(); 1120 } 1121 1122 for(int i = 1;; i++) 1123 { 1124 char ch; 1125 if(i >= path.length) 1126 { 1127 if(numdirdots > 0) 1128 handledots(); 1129 break; 1130 } 1131 ch = path[i]; 1132 if(ch == '/') 1133 ch = '\\'; 1134 if('.' == ch 1135 && (numdirdots > 0 || '\\' == prevchar)) 1136 { 1137 numdirdots++; 1138 } 1139 if(ch == '\\') 1140 { 1141 if(numdirdots) 1142 { 1143 handledots(); 1144 } 1145 else 1146 { 1147 if(prevchar != '\\') 1148 result ~= '\\'; 1149 } 1150 } 1151 else 1152 { 1153 if('.' != ch) 1154 numdirdots = 0; 1155 result ~= ch; 1156 } 1157 prevchar = ch; 1158 } 1159 // If trailing backslash, trim it off, as long as 1160 // it's not part of leading network path two backslashes. 1161 if(prevchar == '\\' && result.length > 2) 1162 result = result[0 .. $ - 1]; 1163 return result; 1164 } 1165 1166 template assertexpr(string EXPR, string TEXT = "") 1167 { 1168 debug 1169 { 1170 const string assertexpr = "if(!(" ~ EXPR ~ "))" 1171 ~ "{" 1172 ~ "scope _stdasserterror = new class { public import std.asserterror; };" 1173 ~ "throw new _stdasserterror.AssertError(__FILE__, __LINE__, `" ~ EXPR ~ " " ~ TEXT ~ "`);" 1174 ~ "}"; 1175 } 1176 else 1177 { 1178 const string assertexpr = ""; 1179 } 1180 } 1181 1182 unittest 1183 { 1184 mixin(assertexpr!(`cleanPath(r"\\foo\bar") == r"\\foo\bar"`)); 1185 mixin(assertexpr!(`cleanPath(r"//foo/\bar") == r"\\foo\bar"`)); 1186 mixin(assertexpr!(`cleanPath(r"\\") == r"\\"`)); 1187 1188 mixin(assertexpr!(`cleanPath(r"c:\all\your\base") == r"c:\all\your\base"`)); 1189 mixin(assertexpr!(`cleanPath(r"c:\/\all/\/\\your//\\\\base") == r"c:\all\your\base"`)); 1190 mixin(assertexpr!(`cleanPath(r"c:\all\your\base\") == r"c:\all\your\base"`)); 1191 mixin(assertexpr!(`cleanPath(r"c:\all\your\base///\\") == r"c:\all\your\base"`)); 1192 mixin(assertexpr!(`cleanPath(r"c:\\\all\your\base") == r"c:\all\your\base"`)); 1193 mixin(assertexpr!(`cleanPath(r"c:\all\your\base\this.file") == r"c:\all\your\base\this.file"`)); 1194 mixin(assertexpr!(`cleanPath(r"c:\all your base\this.file") == r"c:\all your base\this.file"`)); 1195 1196 mixin(assertexpr!(`cleanPath(r".\foo\bar") == r"foo\bar"`)); 1197 //struct _83jh38h { import std.stdio; } 1198 //_83jh38h.writefln("unittest: %s", cleanPath(r"c:\foo\bar\.\baz\..\this.file")); 1199 mixin(assertexpr!(`cleanPath(r"c:\foo\bar\.\baz\..\this.file") == r"c:\foo\bar\this.file"`)); 1200 mixin(assertexpr!(`cleanPath(r"c:\foo\bar\.\baz\..\..\this.file") == r"c:\foo\this.file"`)); 1201 //mixin(assertexpr!(`cleanPath(r"c:\..\this.file") != r"this.file"`)); 1202 //mixin(assertexpr!(`cleanPath(r"c:\..\this.file") != r"\this.file"`)); 1203 } 1204 1205 1206 string[] parseArgs(string args) 1207 { 1208 string[] result; 1209 uint i; 1210 bool inQuote = false; 1211 bool findStart = true; 1212 uint startIndex = 0; 1213 1214 for(i = 0;; i++) 1215 { 1216 if(i == args.length) 1217 { 1218 if(findStart) 1219 startIndex = i; 1220 break; 1221 } 1222 1223 if(findStart) 1224 { 1225 if(args[i] == ' ' || args[i] == '\t') 1226 continue; 1227 findStart = false; 1228 startIndex = i; 1229 } 1230 1231 if(args[i] == '"') 1232 { 1233 inQuote = !inQuote; 1234 if(!inQuote) //matched quotes 1235 { 1236 result.length = result.length + 1; 1237 result[result.length - 1] = args[startIndex .. i]; 1238 findStart = true; 1239 } 1240 else //starting quote 1241 { 1242 if(startIndex != i) //must be a quote stuck to another word, separate them 1243 { 1244 result.length = result.length + 1; 1245 result[result.length - 1] = args[startIndex .. i]; 1246 startIndex = i + 1; 1247 } 1248 else 1249 { 1250 startIndex++; //exclude the quote 1251 } 1252 } 1253 } 1254 else if(!inQuote) 1255 { 1256 if(args[i] == ' ' || args[i] == '\t') 1257 { 1258 result.length = result.length + 1; 1259 result[result.length - 1] = args[startIndex .. i]; 1260 findStart = true; 1261 } 1262 } 1263 } 1264 1265 if(startIndex != i) 1266 { 1267 result.length = result.length + 1; 1268 result[result.length - 1] = args[startIndex .. i]; 1269 } 1270 1271 return result; 1272 } 1273 1274 unittest 1275 { 1276 string[] args; 1277 1278 args = parseArgs(`"foo" bar`); 1279 assert(args.length == 2); 1280 assert(args[0] == "foo"); 1281 assert(args[1] == "bar"); 1282 1283 args = parseArgs(`"environment"`); 1284 assert(args.length == 1); 1285 assert(args[0] == "environment"); 1286 1287 /+ 1288 writefln("commandLine = '%s'", Environment.commandLine); 1289 foreach(string arg; Environment.getCommandLineArgs()) 1290 { 1291 writefln("\t'%s'", arg); 1292 } 1293 +/ 1294 } 1295 1296 1297 /+ 1298 abstract class MSlice(TElem) 1299 { 1300 TElem opIndex(size_t); 1301 MSlice opSlice(size_t, size_t); 1302 size_t length(); // getter 1303 } 1304 1305 1306 class MSliceArray(TElem): MSlice(TElem) 1307 { 1308 this(TElem[] array) 1309 { 1310 this.array = array; 1311 } 1312 1313 1314 override TElem opIndex(size_t idx) 1315 { 1316 return array[idx]; 1317 } 1318 1319 1320 override TElem opSlice(size_t idx1, size_t idx2) 1321 { 1322 return array[idx1 .. idx2]; 1323 } 1324 1325 1326 override size_t length() // getter 1327 { 1328 return array.length; 1329 } 1330 1331 1332 protected: 1333 TElem[] array; 1334 } 1335 +/ 1336 trunk/win32/entice/winapi.d
r101 r102 1 public import dfl. winapi;1 public import dfl.internal.winapi; 2 2 3 3 … … 166 166 enum: UINT 167 167 { 168 DRIVE_FIXED = 3, 169 } 170 171 172 alias DWORD function(LPCWSTR lpszLongPath,LPWSTR lpszShortPath,DWORD cchBuffer) GetShortPathNameWProc; 168 DRIVE_FIXED = 3, 169 } 173 170 174 171 … … 192 189 193 190 BOOL ReplyMessage(LRESULT lResult); 191 192 193 struct STARTUPINFO { 194 DWORD cb; 195 LPTSTR lpReserved; 196 LPTSTR lpDesktop; 197 LPTSTR lpTitle; 198 DWORD dwX; 199 DWORD dwY; 200 DWORD dwXSize; 201 DWORD dwYSize; 202 DWORD dwXCountChars; 203 DWORD dwYCountChars; 204 DWORD dwFillAttribute; 205 DWORD dwFlags; 206 WORD wShowWindow; 207 WORD cbReserved2; 208 LPBYTE lpReserved2; 209 HANDLE hStdInput; 210 HANDLE hStdOutput; 211 HANDLE hStdError; 212 } 213 214 alias STARTUPINFO* LPSTARTUPINFO; 215 216 217 struct PROCESS_INFORMATION { 218 HANDLE hProcess; 219 HANDLE hThread; 220 DWORD dwProcessId; 221 DWORD dwThreadId; 222 } 223 224 alias PROCESS_INFORMATION* LPPROCESS_INFORMATION; 225 226 227 BOOL CreateProcessW( 228 LPCWSTR lpApplicationName, 229 LPWSTR lpCommandLine, 230 LPSECURITY_ATTRIBUTES lpProcessAttributes, 231 LPSECURITY_ATTRIBUTES lpThreadAttributes, 232 BOOL bInheritHandles, 233 DWORD dwCreationFlags, 234 LPVOID lpEnvironment, 235 LPWSTR lpCurrentDirectory, 236 LPSTARTUPINFO lpStartupInfo, 237 LPPROCESS_INFORMATION lpProcessInformation 238 ); 239 240 BOOL CreateProcessA( 241 LPCSTR lpApplicationName, 242 LPSTR lpCommandLine, 243 LPSECURITY_ATTRIBUTES lpProcessAttributes, 244 LPSECURITY_ATTRIBUTES lpThreadAttributes, 245 BOOL bInheritHandles, 246 DWORD dwCreationFlags, 247 LPVOID lpEnvironment, 248 LPTSTR lpCurrentDirectory, 249 LPSTARTUPINFO lpStartupInfo, 250 LPPROCESS_INFORMATION lpProcessInformation 251 ); 252 253 194 254 } 195 255
