QuickMuffin8782-Alt

ccwininstall

Nov 11th, 2020
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local srcFiles = {
  2. "/startup",
  3. "/server",
  4. "/license.txt",
  5. "/win/win",
  6. "/win/startup.ini",
  7. "/win/apis/cmndlg",
  8. "/win/apis/html",
  9. "/win/apps/notepad",
  10. "/win/apps/notepad.ini",
  11. "/win/apps/fexplore",
  12. "/win/apps/fexplore.asc",
  13. "/win/apps/browse",
  14. "/win/apps/browse.ini",
  15. "/win/apps/chat",
  16. "/win/apps/shutdown",
  17. "/win/apps/manager",
  18. "/win/apps/email",
  19. "/win/apps/email.ini",
  20. "/win/apps/emread",
  21. "/win/apps/emwrite",
  22. "/win/apps/sadmin",
  23. "/win/apps/sadmin.ini",
  24. "/win/apps/cmd",
  25. "/win/term/desktop.ini",
  26. "/win/term/startup.ini",
  27. "/templates/minApp",
  28. "/templates/starter",
  29. "/templates/single",
  30. "/templates/menu",
  31. "/templates/popup"
  32. }
  33. local srcData = {
  34. "--SERVER_ROOT = \"/public\"\
  35. --SERVER_PORT = 80\
  36. --SERVER_NETWORK = \"wide_area_network\"\
  37. --SERVER_WIRELESS = true\
  38. --SERVER_TIMEOUT = 5\
  39. --SERVER_PASSWORD = \"admin\"\
  40. --ACCOUNTS_ROOT = \"/accounts\"\
  41. --shell.run(\"/server\")\
  42. os.loadAPI(\"/win/win\")\
  43. if not win.startWin(shell) then\
  44.   os.unloadAPI(\"/win/win\")\
  45. end\
  46. ",
  47. "local function iif(condition,trueValue,falseValue)\
  48. if condition then\
  49. return trueValue\
  50. end\
  51. return falseValue\
  52. end\
  53. local function syslog(entry)\
  54. local file=fs.open(\"/server.log\",iif(fs.exists(\"/server.log\"),\"a\",\"w\"))\
  55. if file then\
  56. file.write(entry..\"\\n\\n\")\
  57. file.close()\
  58. end\
  59. end\
  60. local function printMsg(msg)\
  61. if win then\
  62. if win.syslog then\
  63. syslog(msg)\
  64. return\
  65. end\
  66. end\
  67. print(msg)\
  68. end\
  69. if SERVER_VERSION then\
  70. printMsg(\"Server already running\")\
  71. return\
  72. end\
  73. SERVER_VERSION=1.0\
  74. if not SERVER_ROOT then\
  75. SERVER_ROOT=\"/public\"\
  76. end\
  77. if not SERVER_PORT then\
  78. SERVER_PORT=80\
  79. end\
  80. if not SERVER_NETWORK then\
  81. SERVER_NETWORK=\"wide_area_network\"\
  82. end\
  83. if SERVER_WIRELESS==nil then\
  84. SERVER_WIRELESS=true\
  85. end\
  86. if not SERVER_TIMEOUT then\
  87. SERVER_TIMEOUT=5\
  88. end\
  89. if not SERVER_PASSWORD then\
  90. SERVER_PASSWORD=\"admin\"\
  91. end\
  92. if not ACCOUNTS_ROOT then\
  93. ACCOUNTS_ROOT=\"/accounts\"\
  94. end\
  95. local COMMTIME=0.3\
  96. local commTimer=nil\
  97. local commTime=os.clock()\
  98. local os_pullEventRaw=os.pullEventRaw\
  99. local function asnumber(v,defV)\
  100. return tonumber(v)or(tonumber(defV or 0)or 0)\
  101. end\
  102. local function asstring(v,defV)\
  103. return tostring(v or(tostring(defV or \"\")))..\"\"\
  104. end\
  105. local function findModem(wireless)\
  106. return peripheral.find(\
  107. \"modem\",\
  108. function(name,obj)\
  109. return iif(wireless,obj.isWireless(),\
  110. iif(wireless==false,\
  111. not obj.isWireless(),\
  112. true))\
  113. end)\
  114. end\
  115. local timeStamp=0\
  116. local function startTime()\
  117. timeStamp=os.clock()\
  118. end\
  119. local function checkTime()\
  120. if(os.clock()-timeStamp)>=5 then\
  121. sleep(0.05)\
  122. timeStamp=os.clock()\
  123. return true\
  124. end\
  125. return false\
  126. end\
  127. local function readBinaryFile(path)\
  128. local strFile=\"\"\
  129. local hFile=fs.open(path,\"rb\")\
  130. if not hFile then\
  131. return nil\
  132. end\
  133. startTime()\
  134. local nSrc=hFile.read()\
  135. while nSrc do\
  136. local tChars={}\
  137. while nSrc and #tChars<200 do\
  138. tChars[#tChars+1]=nSrc\
  139. nSrc=hFile.read()\
  140. end\
  141. strFile=strFile..string.char(unpack(tChars))\
  142. checkTime()\
  143. end\
  144. hFile.close()\
  145. return strFile\
  146. end\
  147. local __classBase={}\
  148. function __classBase:constructor(...)\
  149. return self\
  150. end\
  151. function __classBase:new(...)\
  152. local obj={}\
  153. setmetatable(obj,self)\
  154. self.__index=self\
  155. return obj:constructor(...)\
  156. end\
  157. function __classBase:base()\
  158. local obj={}\
  159. setmetatable(obj,self)\
  160. self.__index=self\
  161. return obj\
  162. end\
  163. local comm=__classBase:base()\
  164. function comm:constructor(name,wireless,port,timeout,relay)\
  165. self.comm__name=name\
  166. self.comm__wireless=wireless\
  167. self.comm__port=port or 10\
  168. self.comm__timeout=timeout or 10\
  169. self.comm__relay=relay==true\
  170. self.comm__interests={}\
  171. self.comm__processing={}\
  172. return self\
  173. end\
  174. function comm:getName()\
  175. return self.comm__name\
  176. end\
  177. function comm:setName(name)\
  178. self.comm__name=name\
  179. end\
  180. function comm:getPort()\
  181. return self.comm__port\
  182. end\
  183. function comm:setPort(port)\
  184. self.comm__port=port or 10\
  185. end\
  186. function comm:getTimeout()\
  187. return self.comm__timeout\
  188. end\
  189. function comm:setTimeout(timeout)\
  190. self.comm__timeout=timeout or 10\
  191. end\
  192. function comm:getRelay()\
  193. return self.comm__relay\
  194. end\
  195. function comm:setRelay(relay)\
  196. self.comm__relay=relay==true\
  197. end\
  198. function comm:getWireless()\
  199. return self.comm__wireless\
  200. end\
  201. function comm:setWireless(wireless)\
  202. self.comm__wireless=wireless\
  203. end\
  204. function comm:modem()\
  205. return findModem(self.comm__wireless)\
  206. end\
  207. function comm:connect()\
  208. local modem=self:modem()\
  209. if modem then\
  210. modem.open(self:getPort())\
  211. return true\
  212. end\
  213. return false\
  214. end\
  215. function comm:disconnect()\
  216. local modem=self:modem()\
  217. if modem then\
  218. modem.close(self:getPort())\
  219. end\
  220. end\
  221. function comm:ready()\
  222. local modem=self:modem()\
  223. if modem then\
  224. if modem.isOpen(self:getPort())then\
  225. return modem\
  226. end\
  227. end\
  228. return nil\
  229. end\
  230. function comm:transmit(message)\
  231. local modem=self:ready()\
  232. if modem then\
  233. modem.transmit(self:getPort(),self:getPort(),message)\
  234. return true\
  235. end\
  236. return false\
  237. end\
  238. function comm:register(group,application,receive,sent)\
  239. self.comm__interests[#self.comm__interests+1]=\
  240. {\
  241. application=application,\
  242. receive=receive,\
  243. sent=sent,\
  244. group=group\
  245. }\
  246. end\
  247. function comm:unregister(group,application,receive,sent)\
  248. for i=#self.comm__interests,1,-1 do\
  249. local interest=self.comm__interests[i]\
  250. if interest.group==group and\
  251. (interest.application==application or not application)and\
  252. (interest.receive==receive or not receive)and\
  253. (interest.sent==sent or not sent)then\
  254. table.remove(self.comm__interests,i)\
  255. end\
  256. end\
  257. end\
  258. function comm:copyMsg(msg)\
  259. return textutils.unserialize(textutils.serialize(msg))\
  260. end\
  261. function comm:callSentHandlers(msg,result)\
  262. for i=1,#self.comm__interests,1 do\
  263. if self.comm__interests[i].application==msg.application then\
  264. local success,err=pcall(self.comm__interests[i].sent,msg,result)\
  265. if not success then\
  266. syslog(\"comm \"..self:getName()..\" call to sent handler failed: \"..tostring(err))\
  267. end\
  268. end\
  269. end\
  270. end\
  271. function comm:isDuplicate(msg)\
  272. for i=1,#self.comm__processing,1 do\
  273. local process=self.comm__processing[i]\
  274. if process.msg.messageId==msg.messageId then\
  275. if process.status==\"received\" or\
  276. (process.status==\"relay\" and\
  277. process.msg.sequence==msg.sequence)then\
  278. return true\
  279. end\
  280. end\
  281. end\
  282. return false\
  283. end\
  284. function comm:isConfirmation(msg)\
  285. if msg.context==\"confirm\" then\
  286. for i=#self.comm__processing,1,-1 do\
  287. local process=self.comm__processing[i]\
  288. if process.status==\"send\" then\
  289. if process.msg.messageId==msg.messageId then\
  290. self:callSentHandlers(process.msg,true)\
  291. table.remove(self.comm__processing,i)\
  292. end\
  293. end\
  294. end\
  295. return true\
  296. end\
  297. return false\
  298. end\
  299. function comm:isFromMe(msg)\
  300. return(asnumber(msg.senderId)==os.getComputerID()or\
  301. asstring(msg.senderName)==os.getComputerLabel())\
  302. end\
  303. function comm:isForMe(msg,exclusive)\
  304. if msg.recipientId then\
  305. return asnumber(msg.recipientId)==os.getComputerID()\
  306. elseif msg.recipientName then\
  307. return asstring(msg.recipientName)==os.getComputerLabel()\
  308. elseif exclusive then\
  309. return false\
  310. end\
  311. return(not self:isFromMe(msg))\
  312. end\
  313. function comm:callReceiveHandlers(msg,modemSide,senderChannel,replyChannel,distance)\
  314. local received=false\
  315. local copy=self:copyMsg(msg)\
  316. copy.modemSide=modemSide\
  317. copy.senderChannel=senderChannel\
  318. copy.replyChannel=replyChannel\
  319. copy.distance=distance\
  320. for i=1,#self.comm__interests,1 do\
  321. if self.comm__interests[i].application==msg.application then\
  322. local success,result=pcall(self.comm__interests[i].receive,copy)\
  323. if not success then\
  324. syslog(\"comm \"..self:getName()..\" call to receive handler failed: \"..tostring(result))\
  325. else\
  326. received=result\
  327. end\
  328. end\
  329. end\
  330. return received\
  331. end\
  332. function comm:sendConfirmation(msg)\
  333. if msg.recipientName or msg.recipientId then\
  334. local copy=self:copyMsg(msg)\
  335. copy.context=\"confirm\"\
  336. copy.recipientName=copy.senderName\
  337. copy.recipientId=copy.senderId\
  338. copy.senderName=os.getComputerLabel()\
  339. copy.senderId=os.getComputerID()\
  340. copy.sequence=-1\
  341. if not self:transmit(textutils.serialize(copy))then\
  342. syslog(\"comm \"..self:getName()..\" no modem for confirmation to \"..asstring(msg.senderName))\
  343. end\
  344. end\
  345. end\
  346. function comm:receive(modemSide,senderChannel,replyChannel,message,distance)\
  347. if senderChannel==self:getPort()then\
  348. local success,msg=pcall(textutils.unserialize,message)\
  349. if success and type(msg)==\"table\" then\
  350. if msg.messageId and msg.application and msg.context then\
  351. if self:isForMe(msg)then\
  352. if not self:isConfirmation(msg)then\
  353. if not self:isDuplicate(msg)then\
  354. if self:callReceiveHandlers(msg,modemSide,senderChannel,replyChannel,distance)then\
  355. self.comm__processing[#self.comm__processing+1]=\
  356. {\
  357. timeStamp=os.clock(),\
  358. status=\"received\",\
  359. msg=msg\
  360. }\
  361. self:sendConfirmation(msg)\
  362. end\
  363. end\
  364. end\
  365. end\
  366. if self:getRelay()then\
  367. if not self:isFromMe(msg)and not self:isForMe(msg,true)then\
  368. if not self:isDuplicate(msg)then\
  369. if not self:transmit(message)then\
  370. syslog(\"comm \"..self:getName()..\" no modem to relay message\")\
  371. end\
  372. self.comm__processing[#self.comm__processing+1]=\
  373. {\
  374. timeStamp=os.clock(),\
  375. status=\"relay\",\
  376. msg=msg\
  377. }\
  378. end\
  379. end\
  380. end\
  381. end\
  382. end\
  383. end\
  384. end\
  385. function comm:send(recipient,application,context,data)\
  386. local msg={}\
  387. local method=\"send\"\
  388. if recipient then\
  389. if type(recipient)==\"number\" then\
  390. msg.recipientId=recipient\
  391. if msg.recipientId==os.getComputerID()then\
  392. return\
  393. end\
  394. else\
  395. msg.recipientName=asstring(recipient)\
  396. if msg.recipientName==os.getComputerLabel()then\
  397. return\
  398. end\
  399. end\
  400. else\
  401. method=\"broadcast\"\
  402. end\
  403. msg.context=context\
  404. msg.application=application\
  405. msg.data=data\
  406. msg.senderId=os.getComputerID()\
  407. msg.senderName=os.getComputerLabel()\
  408. msg.messageId=math.random(1,65535)\
  409. msg.sequence=0\
  410. self.comm__processing[#self.comm__processing+1]=\
  411. {\
  412. timeStamp=os.clock(),\
  413. status=method,\
  414. msg=msg\
  415. }\
  416. return msg.messageId\
  417. end\
  418. function comm:process()\
  419. for i=#self.comm__processing,1,-1 do\
  420. local process=self.comm__processing[i]\
  421. if process.status==\"received\" or process.status==\"relay\" then\
  422. if(os.clock()-process.timeStamp)>(self:getTimeout()*2)then\
  423. table.remove(self.comm__processing,i)\
  424. end\
  425. elseif process.status==\"send\" or process.status==\"broadcast\" then\
  426. if(os.clock()-process.timeStamp)>self:getTimeout()then\
  427. if process.status==\"send\" then\
  428. self:callSentHandlers(process.msg,false)\
  429. end\
  430. table.remove(self.comm__processing,i)\
  431. else\
  432. process.msg.sequence=process.msg.sequence+1\
  433. if self:transmit(textutils.serialize(process.msg))then\
  434. if process.status==\"broadcast\" then\
  435. if process.msg.sequence==1 then\
  436. self:callSentHandlers(process.msg,true)\
  437. end\
  438. end\
  439. else\
  440. syslog(\"comm \"..self:getName()..\" no modem to send message\")\
  441. end\
  442. end\
  443. end\
  444. end\
  445. end\
  446. local connection=comm:new(\"server\",SERVER_WIRELESS,SERVER_PORT,SERVER_TIMEOUT,SERVER_WIRELESS)\
  447. if not connection:connect()then\
  448. printMsg(\"Server could not connect\")\
  449. return\
  450. end\
  451. local function fileNotFound(path)\
  452. return string.format(\"\\nFile \\\"%s\\\" not found!\\n\\nEnsure the path is entered correctly.\",path)\
  453. end\
  454. local function accountFolder(account)\
  455. return ACCOUNTS_ROOT..\"/\"..account\
  456. end\
  457. local function readAccount(account)\
  458. local data=nil\
  459. local file=fs.open(accountFolder(account)..\"/account.dat\",\"r\")\
  460. if file then\
  461. data=textutils.unserialize(file.readAll())\
  462. file.close()\
  463. end\
  464. return data\
  465. end\
  466. local function saveAccount(account,data)\
  467. local file=fs.open(accountFolder(account)..\"/account.dat\",\"w\")\
  468. if file then\
  469. file.write(textutils.serialize(data))\
  470. file.close()\
  471. return true\
  472. end\
  473. return false\
  474. end\
  475. local function validatePassword(account,password)\
  476. local data=readAccount(account)\
  477. if data then\
  478. return data.password==password\
  479. end\
  480. return false\
  481. end\
  482. function setAccountPassword(account,password)\
  483. local data=readAccount(account)\
  484. if data then\
  485. data.password=password\
  486. return saveAccount(account,data)\
  487. end\
  488. return false\
  489. end\
  490. function createAccount(account,password)\
  491. if not fs.isDir(accountFolder(account))then\
  492. if(pcall(fs.makeDir,accountFolder(account)))and\
  493. (pcall(fs.makeDir,accountFolder(account)..\"/emails\"))then\
  494. local data={\
  495. password=tostring(password or \"1234\")\
  496. }\
  497. return saveAccount(account,data)\
  498. end\
  499. end\
  500. return false\
  501. end\
  502. function deleteAccount(account)\
  503. if fs.exists(accountFolder(account))and\
  504. fs.isDir(accountFolder(account))then\
  505. pcall(fs.delete,accountFolder(account))\
  506. return not fs.exists(accountFolder(account))\
  507. end\
  508. return false\
  509. end\
  510. local function readEmail(account,name)\
  511. local data=nil\
  512. local file=fs.open(accountFolder(account)..\"/emails/\"..name,\"r\")\
  513. if file then\
  514. data=textutils.unserialize(file.readAll())\
  515. file.close()\
  516. end\
  517. return data\
  518. end\
  519. local function saveEmail(account,email)\
  520. local name=accountFolder(account)..\"/emails/email\"..\
  521. tostring(math.random(1,65535))\
  522. local file=fs.open(name,\"w\")\
  523. if file then\
  524. file.write(textutils.serialize(email))\
  525. file.close()\
  526. return true\
  527. end\
  528. return false\
  529. end\
  530. local function deleteEmail(account,name)\
  531. pcall(fs.delete,accountFolder(account)..\"/emails/\"..name)\
  532. end\
  533. local function listEmails(account)\
  534. local success,files=pcall(fs.list,accountFolder(account)..\"/emails\")\
  535. if success then\
  536. for i=#files,1,-1 do\
  537. if files[i]:sub(1,5)~=\"email\" then\
  538. table.remove(files,i)\
  539. end\
  540. end\
  541. return files\
  542. end\
  543. return nil\
  544. end\
  545. local function requestType(msg)\
  546. if(msg.recipientId or msg.recipientName)and\
  547. type(msg.data)==\"table\" then\
  548. if msg.context==\"http_request\" or\
  549. msg.context==\"ftp_request\" then\
  550. if msg.data.path and msg.data.application then\
  551. return \"file_request\"\
  552. end\
  553. elseif msg.context==\"email_request\" then\
  554. if msg.data.account and msg.data.password and\
  555. msg.data.application and\
  556. fs.isDir(accountFolder(msg.data.account))then\
  557. return msg.context\
  558. end\
  559. elseif msg.context==\"email_delete\" then\
  560. if msg.data.account and msg.data.password and\
  561. msg.data.id and\
  562. fs.isDir(accountFolder(msg.data.account))then\
  563. return msg.context\
  564. end\
  565. elseif msg.context==\"account_password\" then\
  566. if msg.data.account and msg.data.password and\
  567. msg.data.newPassword and\
  568. fs.isDir(accountFolder(msg.data.account))then\
  569. return msg.context\
  570. end\
  571. elseif msg.context==\"email_send\" then\
  572. if msg.data.account and type(msg.data.email)==\"table\" and\
  573. fs.isDir(accountFolder(msg.data.account))then\
  574. if msg.data.email.recipient and msg.data.email.sender and\
  575. msg.data.email.message then\
  576. return msg.context\
  577. end\
  578. end\
  579. elseif msg.context==\"create_account\" then\
  580. if msg.data.account and msg.data.password then\
  581. return msg.context\
  582. end\
  583. elseif msg.context==\"delete_account\" then\
  584. if msg.data.account and msg.data.password then\
  585. return msg.context\
  586. end\
  587. elseif msg.context==\"reset_password\" then\
  588. if msg.data.account and msg.data.password then\
  589. return msg.context\
  590. end\
  591. elseif msg.context==\"file_upload\" then\
  592. if msg.data.path and msg.data.content and msg.data.password then\
  593. return msg.context\
  594. end\
  595. elseif msg.context==\"file_delete\" then\
  596. if msg.data.path and msg.data.password then\
  597. return msg.context\
  598. end\
  599. elseif msg.context==\"listing_request\" then\
  600. if msg.data.path and msg.data.application and\
  601. msg.data.password then\
  602. return msg.context\
  603. end\
  604. elseif msg.context==\"directory_create\" then\
  605. if msg.data.path and msg.data.password then\
  606. return msg.context\
  607. end\
  608. end\
  609. end\
  610. return \"\"\
  611. end\
  612. local function onFileRequest(msg)\
  613. local path=tostring(msg.data.path or \"\")\
  614. local context=\"http_response\"\
  615. if msg.context==\"ftp_request\" then\
  616. context=\"ftp_response\"\
  617. end\
  618. if string.sub(path,1,1)~=\"/\" then\
  619. path=\"/\"..path\
  620. end\
  621. if string.sub(path,-1,-1)~=\"/\" then\
  622. if fs.isDir(SERVER_ROOT..path)then\
  623. path=path..\"/\"\
  624. end\
  625. end\
  626. if string.sub(path,-1,-1)==\"/\" then\
  627. if fs.exists(SERVER_ROOT..path..\"index.html\")then\
  628. path=path..\"index.html\"\
  629. elseif fs.exists(SERVER_ROOT..path..\"index.htm\")then\
  630. path=path..\"index.htm\"\
  631. elseif fs.exists(SERVER_ROOT..path..\"index.txt\")then\
  632. path=path..\"index.txt\"\
  633. end\
  634. end\
  635. local localPath=SERVER_ROOT..path\
  636. local domainPath=asstring(os.getComputerLabel())..path\
  637. local data={path=domainPath}\
  638. data.content=readBinaryFile(localPath)\
  639. if not data.content then\
  640. if context==\"ftp_response\" then\
  641. return false\
  642. end\
  643. data.content=fileNotFound(domainPath)\
  644. end\
  645. connection:send(msg.senderId or msg.senderName,\
  646. msg.data.application,context,data)\
  647. return true\
  648. end\
  649. local function onEmailSend(msg)\
  650. return saveEmail(msg.data.account,msg.data.email)\
  651. end\
  652. local function onAccountPassword(msg)\
  653. if validatePassword(msg.data.account,msg.data.password)then\
  654. return setAccountPassword(msg.data.account,msg.data.newPassword)\
  655. end\
  656. return false\
  657. end\
  658. local function onEmailRequest(msg)\
  659. if validatePassword(msg.data.account,msg.data.password)then\
  660. local files=listEmails(msg.data.account)\
  661. if files then\
  662. for i=1,#files,1 do\
  663. local data={\
  664. account=msg.data.account,\
  665. id=files[i],\
  666. email=readEmail(msg.data.account,files[i])\
  667. }\
  668. connection:send(msg.senderId or msg.senderName,\
  669. msg.data.application,\"email_response\",data)\
  670. end\
  671. return true\
  672. end\
  673. end\
  674. return false\
  675. end\
  676. local function onEmailDelete(msg)\
  677. if validatePassword(msg.data.account,msg.data.password)then\
  678. deleteEmail(msg.data.account,msg.data.id)\
  679. return true\
  680. end\
  681. return false\
  682. end\
  683. local function onCreateAccount(msg)\
  684. if msg.data.password==SERVER_PASSWORD then\
  685. return createAccount(msg.data.account,msg.data.clientPassword)\
  686. end\
  687. return false\
  688. end\
  689. local function onDeleteAccount(msg)\
  690. if msg.data.password==SERVER_PASSWORD then\
  691. return deleteAccount(msg.data.account)\
  692. end\
  693. return false\
  694. end\
  695. local function onResetPassword(msg)\
  696. if msg.data.password==SERVER_PASSWORD then\
  697. return setAccountPassword(msg.data.account,\
  698. tostring(msg.data.clientPassword or \"1234\"))\
  699. end\
  700. return false\
  701. end\
  702. local function onFileUpload(msg)\
  703. if msg.data.password==SERVER_PASSWORD then\
  704. local path=tostring(msg.data.path or \"\")\
  705. if path:sub(1,1)~=\"/\" then\
  706. path=\"/\"..path\
  707. end\
  708. local file=fs.open(SERVER_ROOT..path,\"w\")\
  709. if file then\
  710. file.write(tostring(msg.data.content))\
  711. file.close()\
  712. return true\
  713. end\
  714. end\
  715. return false\
  716. end\
  717. local function onFileDelete(msg)\
  718. if msg.data.password==SERVER_PASSWORD then\
  719. local path=tostring(msg.data.path or \"\")\
  720. if path:sub(1,1)~=\"/\" then\
  721. path=\"/\"..path\
  722. end\
  723. if fs.exists(SERVER_ROOT..path)then\
  724. fs.delete(SERVER_ROOT..path)\
  725. return not fs.exists(SERVER_ROOT..path)\
  726. end\
  727. end\
  728. return false\
  729. end\
  730. local function onListingRequest(msg)\
  731. if msg.data.password==SERVER_PASSWORD then\
  732. local path=tostring(msg.data.path or \"\")\
  733. if path:sub(-1,-1)==\"/\" then\
  734. path=path:sub(1,-2)\
  735. end\
  736. if path:sub(1,1)~=\"/\" then\
  737. path=\"/\"..path\
  738. end\
  739. if fs.exists(SERVER_ROOT..path)and fs.isDir(SERVER_ROOT..path)then\
  740. local success,listing=pcall(fs.list,SERVER_ROOT..path)\
  741. if success then\
  742. if path:sub(-1,-1)~=\"/\" then\
  743. path=path..\"/\"\
  744. end\
  745. local data=\
  746. {\
  747. path=path,\
  748. files={},\
  749. folders={}\
  750. }\
  751. for i=1,#listing,1 do\
  752. if fs.isDir(SERVER_ROOT..path..listing[i])then\
  753. data.folders[#data.folders+1]=listing[i]\
  754. else\
  755. data.files[#data.files+1]=listing[i]\
  756. end\
  757. end\
  758. connection:send(msg.senderId or msg.senderName,\
  759. msg.data.application,\"listing_response\",data)\
  760. return true\
  761. end\
  762. end\
  763. end\
  764. return false\
  765. end\
  766. local function onDirectoryCreate(msg)\
  767. if msg.data.password==SERVER_PASSWORD then\
  768. local path=tostring(msg.data.path or \"\")\
  769. if path:sub(1,1)~=\"/\" then\
  770. path=\"/\"..path\
  771. end\
  772. if not fs.exists(SERVER_ROOT..path)then\
  773. pcall(fs.makeDir,SERVER_ROOT..path)\
  774. return fs.exists(SERVER_ROOT..path)\
  775. end\
  776. end\
  777. return false\
  778. end\
  779. local function receive(msg)\
  780. local request=requestType(msg)\
  781. if request==\"file_request\" then\
  782. return onFileRequest(msg)\
  783. elseif request==\"account_password\" then\
  784. return onAccountPassword(msg)\
  785. elseif request==\"email_request\" then\
  786. return onEmailRequest(msg)\
  787. elseif request==\"email_delete\" then\
  788. return onEmailDelete(msg)\
  789. elseif request==\"email_send\" then\
  790. return onEmailSend(msg)\
  791. elseif request==\"file_upload\" then\
  792. return onFileUpload(msg)\
  793. elseif request==\"file_delete\" then\
  794. return onFileDelete(msg)\
  795. elseif request==\"listing_request\" then\
  796. return onListingRequest(msg)\
  797. elseif request==\"directory_create\" then\
  798. return onDirectoryCreate(msg)\
  799. elseif request==\"create_account\" then\
  800. return onCreateAccount(msg)\
  801. elseif request==\"delete_account\" then\
  802. return onDeleteAccount(msg)\
  803. elseif request==\"reset_password\" then\
  804. return onResetPassword(msg)\
  805. end\
  806. return false\
  807. end\
  808. local function sent(msg,success)\
  809. end\
  810. connection:register(nil,SERVER_NETWORK,receive,sent)\
  811. function os.pullEventRaw(target)\
  812. if not commTimer or(os.clock()-commTime)>=COMMTIME then\
  813. connection:process()\
  814. commTimer=os.startTimer(COMMTIME)\
  815. commTime=os.clock()\
  816. end\
  817. while true do\
  818. local event={os_pullEventRaw()}\
  819. if event[1]==\"timer\" and event[2]==commTimer then\
  820. connection:process()\
  821. commTimer=os.startTimer(COMMTIME)\
  822. commTime=os.clock()\
  823. else\
  824. if event[1]==\"modem_message\" then\
  825. connection:receive(event[2],event[3],event[4],event[5],event[6])\
  826. end\
  827. if not target or event[1]==target or event[1]==\"terminate\" then\
  828. return unpack(event)\
  829. end\
  830. end\
  831. end\
  832. end\
  833. printMsg(\"Server started\")\
  834. ",
  835. "This software is covered by the MIT license.\
  836. \
  837. MIT License\
  838. \
  839. Copyright (c) 2015 loosewheel\
  840. \
  841. Permission is hereby granted, free of charge, to any person obtaining a copy\
  842. of this software and associated documentation files (the \"Software\"), to deal\
  843. in the Software without restriction, including without limitation the rights\
  844. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\
  845. copies of the Software, and to permit persons to whom the Software is\
  846. furnished to do so, subject to the following conditions:\
  847. \
  848. The above copyright notice and this permission notice shall be included in all\
  849. copies or substantial portions of the Software.\
  850. \
  851. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\
  852. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\
  853. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\
  854. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\
  855. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\
  856. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\
  857. SOFTWARE.\
  858. ",
  859. "function version()\
  860. return 0.23\
  861. end\
  862. local _ccversion=nil\
  863. function ccVersion()\
  864. if not _ccversion then\
  865. _ccversion=0\
  866. if _G._HOST then\
  867. for w in string.gmatch(_G._HOST,\"(%d+%p%d+)\")do\
  868. if asnumber(w)>0 then\
  869. _ccversion=asnumber(w)\
  870. break\
  871. end\
  872. end\
  873. elseif _G._CC_VERSION then\
  874. _ccversion=asnumber(_G._CC_VERSION)\
  875. else\
  876. local v=os.version()\
  877. for w in string.gmatch(v,\"(%d+%p%d+)\")do\
  878. if asnumber(w)>0 then\
  879. _ccversion=asnumber(w)\
  880. break\
  881. end\
  882. end\
  883. end\
  884. end\
  885. return _ccversion\
  886. end\
  887. function _G.asnumber(v,defV)\
  888. return tonumber(v)or(tonumber(defV or 0)or 0)\
  889. end\
  890. function _G.asstring(v,defV)\
  891. return tostring(v or(tostring(defV or \"\")))..\"\"\
  892. end\
  893. function _G.iif(condition,trueValue,falseValue)\
  894. if condition then\
  895. return trueValue\
  896. end\
  897. return falseValue\
  898. end\
  899. function string:trimLeft(char)\
  900. str=tostring(self or \"\")\
  901. char=tostring(char or \" \")\
  902. if char:len()>0 then\
  903. while str:sub(1,char:len())==char do\
  904. str=str:sub(char:len()+1)\
  905. end\
  906. end\
  907. return str\
  908. end\
  909. function string:trimRight(char)\
  910. str=tostring(self or \"\")\
  911. char=tostring(char or \" \")\
  912. if char:len()>0 then\
  913. while str:sub(-1,-(char:len()))==char do\
  914. str=str:sub(1,-(char:len()+1))\
  915. end\
  916. end\
  917. return str\
  918. end\
  919. function string:trim(char)\
  920. return string.trimRight(string.trimLeft(self,char),char)\
  921. end\
  922. function string:splice(len)\
  923. str=tostring(self or \"\")\
  924. len=tonumber(len or 0)or 0\
  925. if len>0 then\
  926. local eol=(str:find(\"[\\r\\n]\"))or(str:len()+1)\
  927. local nextLine=eol+1\
  928. if(eol-1)<=len and eol<=str:len()then\
  929. if str:byte(eol)==13 and eol<str:len()then\
  930. if str:byte(eol+1)==10 then\
  931. nextLine=nextLine+1\
  932. end\
  933. end\
  934. return str:sub(1,eol-1),(str:sub(nextLine)or \"\"),true\
  935. end\
  936. if str:len()<=len then\
  937. return str,nil,false\
  938. end\
  939. for pos=len+1,1,-1 do\
  940. if str:byte(pos)==32 then\
  941. return str:sub(1,pos-1),(str:sub(pos+1)or \"\"),true\
  942. end\
  943. end\
  944. return str:sub(1,len),(str:sub(len+1)or \"\"),true\
  945. end\
  946. return str,nil,false\
  947. end\
  948. function string:wrap(maxWidth)\
  949. local wrapped={}\
  950. str=tostring(self or \"\")\
  951. maxWidth=tonumber(maxWidth or 0)or 0\
  952. repeat\
  953. wrapped[#wrapped+1],str=string.splice(str,maxWidth)\
  954. until not str\
  955. return wrapped\
  956. end\
  957. function string.wrapSize(wrapStr)\
  958. local width,height=0,0\
  959. if type(wrapStr)==\"table\" then\
  960. height=#wrapStr\
  961. for i=1,height,1 do\
  962. if type(wrapStr[i])~=\"string\" then\
  963. return 0,0\
  964. end\
  965. if wrapStr[i]:len()>width then\
  966. width=wrapStr[i]:len()\
  967. end\
  968. end\
  969. end\
  970. return width,height\
  971. end\
  972. function textutils.formatTime(timeValue,twentyFourHour,minLength)\
  973. local str;\
  974. local hour,minute=math.modf(asnumber(timeValue))\
  975. minute=minute*60\
  976. if twentyFourHour then\
  977. str=string.format(\"%d:%02d\",hour,minute)\
  978. else\
  979. local ampm=iif(hour<12,\"AM\",\"PM\")\
  980. if hour==0 then\
  981. hour=12\
  982. elseif hour>12 then\
  983. hour=hour-12\
  984. end\
  985. str=string.format(\"%d:%02d %s\",hour,minute,ampm)\
  986. end\
  987. if minLength then\
  988. if minLength>str:len()then\
  989. str=string.rep(\" \",minLength-str:len())..str\
  990. end\
  991. end\
  992. return str\
  993. end\
  994. function fs.getExtension(path)\
  995. local ext=\"\"\
  996. local fileName=fs.getName(path)\
  997. for i=fileName:len(),1,-1 do\
  998. if fileName:sub(i,i)==\".\" then\
  999. ext=fileName:sub(i+1)\
  1000. break\
  1001. end\
  1002. end\
  1003. return ext\
  1004. end\
  1005. function fs.loadIniFile(path)\
  1006. local iniFile;\
  1007. path=asstring(path)\
  1008. if fs.exists(path)and not fs.isDir(path)then\
  1009. local hInit=fs.open(path,\"r\")\
  1010. if hInit then\
  1011. local content=hInit.readAll()\
  1012. if content then\
  1013. iniFile={}\
  1014. for line in content:gmatch(\"([^\\r\\n]*)[\\r\\n]*\")do\
  1015. local comment,name,value=line:match(\"(;*)([^=]*)=(.*)\")\
  1016. if comment and comment:len()==0 then\
  1017. name=string.trim(name)\
  1018. if name:len()>0 then\
  1019. iniFile[#iniFile+1]=\
  1020. {\
  1021. name=name,\
  1022. value=value\
  1023. }\
  1024. end\
  1025. end\
  1026. end\
  1027. function iniFile:find(key)\
  1028. for i=1,#self,1 do\
  1029. if self[i].name==key then\
  1030. return self[i].value\
  1031. end\
  1032. end\
  1033. return nil\
  1034. end\
  1035. function iniFile:next(key)\
  1036. local init=1\
  1037. return function()\
  1038. for i=init,#self,1 do\
  1039. if self[i].name==key then\
  1040. init=i+1\
  1041. return self[i].value\
  1042. end\
  1043. end\
  1044. init=#self+1\
  1045. return nil\
  1046. end\
  1047. end\
  1048. end\
  1049. hInit.close()\
  1050. end\
  1051. end\
  1052. return iniFile\
  1053. end\
  1054. function fs.tmpfile(prefix)\
  1055. local path;\
  1056. local counter=0\
  1057. repeat\
  1058. path=\"/win/tmp/\"..tostring(prefix or \"tmp\")..tostring(counter)\
  1059. counter=counter+1\
  1060. until not fs.exists(path)\
  1061. return path\
  1062. end\
  1063. local function getPassword()\
  1064. local iniFile=fs.loadIniFile(\"/win/startup.ini\")\
  1065. local password=\"\"\
  1066. if iniFile then\
  1067. password=asstring(iniFile:find(\"password\"),\"\")\
  1068. end\
  1069. return password\
  1070. end\
  1071. local function safeRead(mask)\
  1072. local entered=\"\"\
  1073. mask=asstring(mask):sub(1,1)\
  1074. term.setCursorBlink(true)\
  1075. while true do\
  1076. local event,param=os.pullEventRaw()\
  1077. if event==\"key\" then\
  1078. if param==keys.enter then\
  1079. term.setCursorBlink(false)\
  1080. return entered\
  1081. elseif param==keys.backspace then\
  1082. if entered:len()>0 then\
  1083. local x,y=term.getCursorPos()\
  1084. entered=entered:sub(1,-2)\
  1085. term.setCursorPos(x-1,y)\
  1086. term.write(\" \")\
  1087. term.setCursorPos(x-1,y)\
  1088. end\
  1089. end\
  1090. elseif event==\"char\" then\
  1091. entered=entered..param\
  1092. if mask:len()==1 then\
  1093. term.write(mask)\
  1094. else\
  1095. term.write(param)\
  1096. end\
  1097. end\
  1098. end\
  1099. end\
  1100. function syslog(entry)\
  1101. local file=fs.open(\"/win/win.log\",iif(fs.exists(\"/win/win.log\"),\"a\",\"w\"))\
  1102. if file then\
  1103. file.write(entry..\"\\n\\n\")\
  1104. file.close()\
  1105. end\
  1106. end\
  1107. function parseCmdLine(...)\
  1108. local line=table.concat({...},\" \")\
  1109. local args={}\
  1110. local quoted=false\
  1111. for match in(line..\"\\\"\"):gmatch(\"(.-)\\\"\")do\
  1112. if quoted then\
  1113. args[#args+1]=match\
  1114. else\
  1115. for arg in match:gmatch(\"[^ \\t]+\")do\
  1116. args[#args+1]=arg\
  1117. end\
  1118. end\
  1119. quoted=not quoted\
  1120. end\
  1121. return args\
  1122. end\
  1123. function loadAPI(path,perm)\
  1124. local name=fs.getName(path)\
  1125. local refCount=perm and-1 or 1\
  1126. if not perm and _G[name]and _G[name].api_refCount then\
  1127. refCount=_G[name].api_refCount\
  1128. if refCount>=0 then\
  1129. refCount=refCount+1\
  1130. end\
  1131. end\
  1132. os.loadAPI(path)\
  1133. if _G[name]then\
  1134. _G[name].api_refCount=refCount\
  1135. return true\
  1136. end\
  1137. return false\
  1138. end\
  1139. function unloadAPI(path)\
  1140. local name=fs.getName(path)\
  1141. if _G[name]and _G[name].api_refCount then\
  1142. if _G[name].api_refCount<0 then\
  1143. return\
  1144. elseif _G[name].api_refCount>1 then\
  1145. _G[name].api_refCount=_G[name].api_refCount-1\
  1146. return\
  1147. end\
  1148. end\
  1149. os.unloadAPI(path)\
  1150. end\
  1151. __classBase={}\
  1152. function __classBase:constructor(...)\
  1153. return self\
  1154. end\
  1155. function __classBase:new(...)\
  1156. local obj={}\
  1157. setmetatable(obj,self)\
  1158. self.__index=self\
  1159. return obj:constructor(...)\
  1160. end\
  1161. function __classBase:base()\
  1162. local obj={}\
  1163. setmetatable(obj,self)\
  1164. self.__index=self\
  1165. return obj\
  1166. end\
  1167. local GDI_TERM=1\
  1168. local GDI_MONITOR=2\
  1169. local GDI_PRINTER=4\
  1170. WND_TOP=0\
  1171. WND_BOTTOM=100000\
  1172. HT_NOWHERE=0\
  1173. HT_CLIENT=1\
  1174. HT_LINEUP=2\
  1175. HT_LINEDOWN=3\
  1176. HT_PAGEUP=4\
  1177. HT_PAGEDOWN=5\
  1178. HT_LINELEFT=6\
  1179. HT_LINERIGHT=7\
  1180. HT_PAGELEFT=8\
  1181. HT_PAGERIGHT=9\
  1182. local ID_DESKTOP=65536\
  1183. local ID_FRAME=65537\
  1184. local ID_TASKBAR=65538\
  1185. local ID_MENULIST=65539\
  1186. local ID_APPLIST=65540\
  1187. local ID_MENUFRAME=65539\
  1188. local ID_APPFRAME=65540\
  1189. local ID_KEYBOARD=65541\
  1190. local ID_DIALOG=65542\
  1191. local ID_MSGBOX_MSG=65543\
  1192. local ID_LOCKSCRN=65544\
  1193. local ID_LOCKPW=65545\
  1194. local ID_LOCKOK=65546\
  1195. local ID_HOMELOCK=65547\
  1196. local FRAME_CLASS_WINDOW=70000\
  1197. local FRAME_CLASS_SYSTEM=70001\
  1198. local FRAME_CLASS_APPLICATION=70002\
  1199. local FRAME_CLASS_DIALOG=70003\
  1200. ID_TITLEBAR=80000\
  1201. ID_CLOSE=80001\
  1202. CB_EMPTY=0\
  1203. CB_TEXT=1\
  1204. KEYINPUT_NONE=0\
  1205. KEYINPUT_LINE=1\
  1206. KEYINPUT_EDIT=2\
  1207. local __ccwin;\
  1208. local __shell=nil\
  1209. desktopTheme=__classBase:base()\
  1210. function desktopTheme:constructor()\
  1211. self.doubleClick=0.5\
  1212. self.textScale=1.0\
  1213. self.keyboardHeight=5\
  1214. self.closeBtnChar=\"x\"\
  1215. self.color={\
  1216. desktopBack=colors.black,\
  1217. wndText=colors.black,\
  1218. wndBack=colors.white,\
  1219. wndFocus=colors.lightBlue,\
  1220. frameText=colors.black,\
  1221. frameBack=colors.lightGray,\
  1222. popupText=colors.black,\
  1223. popupBack=colors.yellow,\
  1224. buttonText=colors.black,\
  1225. buttonBack=colors.blue,\
  1226. buttonFocus=colors.cyan,\
  1227. inputText=colors.black,\
  1228. inputBack=colors.white,\
  1229. inputFocus=colors.lightBlue,\
  1230. inputError=colors.pink,\
  1231. inputBanner=colors.lightGray,\
  1232. selectedText=colors.white,\
  1233. selectedBack=colors.blue,\
  1234. scrollText=colors.lightGray,\
  1235. scrollBack=colors.gray,\
  1236. scrollTrack=colors.lightGray,\
  1237. checkText=colors.green,\
  1238. checkBack=colors.white,\
  1239. checkFocus=colors.lightBlue,\
  1240. taskText=colors.lightGray,\
  1241. taskBack=colors.gray,\
  1242. homeText=colors.lightGray,\
  1243. homeBack=colors.black,\
  1244. homeItemText=colors.blue,\
  1245. homeItemBack=colors.black,\
  1246. homeItemSelectedText=colors.lightBlue,\
  1247. homeItemSelectedBack=colors.black,\
  1248. titleText=colors.white,\
  1249. titleBack=colors.gray,\
  1250. closeText=colors.white,\
  1251. closeBack=colors.red,\
  1252. closeFocus=colors.purple,\
  1253. kbText=colors.lightGray,\
  1254. kbBack=colors.black,\
  1255. kbKey=colors.black,\
  1256. kbCmd=colors.blue,\
  1257. kbCancel=colors.green,\
  1258. kbToggle=colors.lightBlue,\
  1259. menuText=colors.black,\
  1260. menuBack=colors.lightBlue,\
  1261. menuSelectedText=colors.white,\
  1262. menuSelectedBack=colors.blue\
  1263. }\
  1264. return self\
  1265. end\
  1266. local __defaultTheme=desktopTheme:new()\
  1267. function wndToScreen(wnd,x,y)\
  1268. local _wnd,rx,ry=wnd,x,y\
  1269. while _wnd do\
  1270. rx=rx+_wnd.x\
  1271. ry=ry+_wnd.y\
  1272. _wnd=_wnd.wnd__parent\
  1273. end\
  1274. return rx,ry\
  1275. end\
  1276. function screenToWnd(wnd,x,y)\
  1277. local _wnd,rx,ry=wnd,x,y\
  1278. while _wnd do\
  1279. rx=rx-_wnd.x\
  1280. ry=ry-_wnd.y\
  1281. _wnd=_wnd.wnd__parent\
  1282. end\
  1283. return rx,ry\
  1284. end\
  1285. rect=__classBase:base()\
  1286. function rect:constructor(x,y,width,height)\
  1287. self.x=asnumber(x)\
  1288. self.y=asnumber(y)\
  1289. self.width=asnumber(width)\
  1290. self.height=asnumber(height)\
  1291. return self\
  1292. end\
  1293. function rect:isEmpty()\
  1294. if self.x and self.y and self.width and self.height then\
  1295. return(self.width==0 or self.height==0)\
  1296. end\
  1297. return true\
  1298. end\
  1299. function rect:empty()\
  1300. self.x=0\
  1301. self.y=0\
  1302. self.width=0\
  1303. self.height=0\
  1304. end\
  1305. function rect:copy(rtCopy)\
  1306. self.x=asnumber(rtCopy.x)\
  1307. self.y=asnumber(rtCopy.y)\
  1308. self.width=asnumber(rtCopy.width)\
  1309. self.height=asnumber(rtCopy.height)\
  1310. end\
  1311. function rect:unpack()\
  1312. return self.x,self.y,self.width,self.height\
  1313. end\
  1314. function rect:clip(rtClip)\
  1315. if rtClip:isEmpty()or self:isEmpty()then\
  1316. self:empty()\
  1317. else\
  1318. self.width=self.width+self.x\
  1319. self.height=self.height+self.y\
  1320. if rtClip.x>self.x then\
  1321. self.x=rtClip.x\
  1322. end\
  1323. if rtClip.y>self.y then\
  1324. self.y=rtClip.y\
  1325. end\
  1326. if self.width>(rtClip.x+rtClip.width)then\
  1327. self.width=rtClip.x+rtClip.width\
  1328. end\
  1329. if self.height>(rtClip.y+rtClip.height)then\
  1330. self.height=rtClip.y+rtClip.height\
  1331. end\
  1332. self.width=self.width-self.x\
  1333. self.height=self.height-self.y\
  1334. if self.width<=0 or self.height<=0 then\
  1335. self:empty()\
  1336. end\
  1337. end\
  1338. end\
  1339. function rect:bound(rtCombine)\
  1340. if self:isEmpty()then\
  1341. self:copy(rtCombine)\
  1342. elseif not rtCombine:isEmpty()then\
  1343. self.width=self.width+self.x\
  1344. self.height=self.height+self.y\
  1345. if rtCombine.x<self.x then\
  1346. self.x=rtCombine.x\
  1347. end\
  1348. if rtCombine.y<self.y then\
  1349. self.y=rtCombine.y\
  1350. end\
  1351. if self.width<(rtCombine.x+rtCombine.width)then\
  1352. self.width=rtCombine.x+rtCombine.width\
  1353. end\
  1354. if self.height<(rtCombine.y+rtCombine.height)then\
  1355. self.height=rtCombine.y+rtCombine.height\
  1356. end\
  1357. self.width=self.width-self.x\
  1358. self.height=self.height-self.y\
  1359. end\
  1360. end\
  1361. function rect:offset(x,y)\
  1362. if not self:isEmpty()then\
  1363. self.x=self.x+x\
  1364. self.y=self.y+y\
  1365. end\
  1366. end\
  1367. function rect:contains(x,y)\
  1368. if not self:isEmpty()then\
  1369. return((x>=self.x)and(x<(self.x+self.width))and\
  1370. (y>=self.y)and(y<(self.y+self.height)))\
  1371. end\
  1372. return false\
  1373. end\
  1374. function rect:overlap(rtTest)\
  1375. if self:isEmpty()or rtTest:isEmpty()then\
  1376. return false\
  1377. end\
  1378. if self.x>=(rtTest.x+rtTest.width)then\
  1379. return false\
  1380. end\
  1381. if rtTest.x>=(self.x+self.width)then\
  1382. return false\
  1383. end\
  1384. if self.y>=(rtTest.y+rtTest.height)then\
  1385. return false\
  1386. end\
  1387. if rtTest.y>=(self.y+self.height)then\
  1388. return false\
  1389. end\
  1390. return true\
  1391. end\
  1392. local function displayBuffer(interface)\
  1393. local db={}\
  1394. db.x=-1\
  1395. db.y=-1\
  1396. db.draw=true\
  1397. db.color=colors.white\
  1398. db.bgColor=colors.black\
  1399. db.blink=true\
  1400. db.scale=1.0\
  1401. db.interface=interface\
  1402. db.lines={}\
  1403. function db.blit()\
  1404. local width,height=db.getSize()\
  1405. db.interface.setCursorBlink(false)\
  1406. for line=1,height,1 do\
  1407. if db.lines[line]then\
  1408. for i=1,#db.lines[line],1 do\
  1409. local b=db.lines[line][i]\
  1410. db.interface.setCursorPos(b.first,line)\
  1411. if db.interface.isColor()then\
  1412. db.interface.setTextColor(b.color)\
  1413. db.interface.setBackgroundColor(b.bgColor)\
  1414. end\
  1415. db.interface.write(b.text)\
  1416. end\
  1417. end\
  1418. end\
  1419. db.interface.setCursorPos(db.x,db.y)\
  1420. if db.interface.isColor()then\
  1421. db.interface.setTextColor(db.color)\
  1422. db.interface.setBackgroundColor(db.bgColor)\
  1423. end\
  1424. db.interface.setCursorBlink(db.blink)\
  1425. db.lines={}\
  1426. end\
  1427. function db.setDraw(draw)\
  1428. if draw~=db.draw then\
  1429. db.draw=draw\
  1430. if draw then\
  1431. db.blit()\
  1432. end\
  1433. end\
  1434. end\
  1435. function db.write(text)\
  1436. if text:len()>0 then\
  1437. local first,last=db.x,db.x+text:len()-1\
  1438. if not db.lines[db.y]then\
  1439. db.lines[db.y]={}\
  1440. else\
  1441. for i=#db.lines[db.y],1,-1 do\
  1442. local part=db.lines[db.y][i]\
  1443. if first<=part.first then\
  1444. if last>=part.last then\
  1445. table.remove(db.lines[db.y],i)\
  1446. elseif last>=part.first then\
  1447. part.text=part.text:sub(last-part.first+2)\
  1448. part.first=last+1\
  1449. end\
  1450. elseif last>=part.last then\
  1451. if first<=part.last then\
  1452. part.text=part.text:sub(1,-(part.last-first+2))\
  1453. part.last=first-1\
  1454. end\
  1455. elseif first>part.first and last<part.last then\
  1456. db.lines[db.y][#db.lines[db.y]+1]=\
  1457. {\
  1458. first=last+1,\
  1459. last=part.last,\
  1460. color=part.color,\
  1461. bgColor=part.bgColor,\
  1462. text=part.text:sub(last-part.first+2)\
  1463. }\
  1464. part.text=part.text:sub(1,first-part.first)\
  1465. part.last=first-1\
  1466. end\
  1467. end\
  1468. end\
  1469. db.lines[db.y][#db.lines[db.y]+1]=\
  1470. {\
  1471. first=first,\
  1472. last=last,\
  1473. color=db.color,\
  1474. bgColor=db.bgColor,\
  1475. text=text\
  1476. }\
  1477. if db.draw then\
  1478. db.interface.setCursorPos(db.x,db.y)\
  1479. if db.interface.isColor()then\
  1480. db.interface.setTextColor(db.color)\
  1481. db.interface.setBackgroundColor(db.bgColor)\
  1482. end\
  1483. db.interface.write(text)\
  1484. end\
  1485. db.x=last+1\
  1486. end\
  1487. end\
  1488. function db.getCursorPos()\
  1489. return db.interface.getCursorPos()\
  1490. end\
  1491. function db.setCursorPos(x,y)\
  1492. db.x=x\
  1493. db.y=y\
  1494. db.interface.setCursorPos(x,y)\
  1495. end\
  1496. function db.setCursorBlink(blink)\
  1497. db.blink=blink\
  1498. db.interface.setCursorBlink(blink)\
  1499. end\
  1500. function db.isColor()\
  1501. return db.interface.isColor()\
  1502. end\
  1503. function db.getSize()\
  1504. return db.interface.getSize()\
  1505. end\
  1506. function db.setTextColor(color)\
  1507. db.color=color\
  1508. db.interface.setTextColor(color)\
  1509. end\
  1510. function db.setBackgroundColor(color)\
  1511. db.bgColor=color\
  1512. db.interface.setBackgroundColor(color)\
  1513. end\
  1514. function db.getTextColor()\
  1515. return db.color\
  1516. end\
  1517. function db.getBackgroundColor()\
  1518. return db.bgColor\
  1519. end\
  1520. function db.setTextScale(scale)\
  1521. db.scale=scale\
  1522. db.interface.setTextScale(scale)\
  1523. end\
  1524. return db\
  1525. end\
  1526. GDI=__classBase:base()\
  1527. function GDI:constructor(side,wnd)\
  1528. self.gdi__side=\"\"\
  1529. self.gdi__device=nil\
  1530. self.gdi__type=0\
  1531. self.gdi__wnd=wnd\
  1532. self.gdi__xOrg=0\
  1533. self.gdi__yOrg=0\
  1534. self.gdi__shellBuffered=false\
  1535. self.gdi__storedCursorX=nil\
  1536. self.gdi__storedCursorY=nil\
  1537. self.gdi__bounds=rect:new()\
  1538. if not self:setSide(side)then\
  1539. return nil\
  1540. end\
  1541. return self\
  1542. end\
  1543. function GDI:setSide(side)\
  1544. side=asstring(side)\
  1545. self.gdi__shellBuffered=false\
  1546. if side==\"term\" then\
  1547. self.gdi__side=\"term\"\
  1548. self.gdi__type=GDI_TERM\
  1549. if self.gdi__wnd and self.gdi__wnd:getParent()then\
  1550. self.gdi__device=self.gdi__wnd:getParent().gdi.gdi__device\
  1551. elseif self.gdi__wnd and self.gdi__wnd.dt__bufferDisplay then\
  1552. if term.current()and term.current().setVisible then\
  1553. self.gdi__device=term\
  1554. self.gdi__shellBuffered=true\
  1555. else\
  1556. self.gdi__device=displayBuffer(term)\
  1557. end\
  1558. else\
  1559. self.gdi__device=term\
  1560. end\
  1561. else\
  1562. local devType=peripheral.getType(side)\
  1563. if devType==\"monitor\" then\
  1564. self.gdi__side=side\
  1565. self.gdi__type=GDI_MONITOR\
  1566. if self.gdi__wnd and self.gdi__wnd:getParent()then\
  1567. self.gdi__device=self.gdi__wnd:getParent().gdi.gdi__device\
  1568. elseif self.gdi__wnd and self.gdi__wnd.dt__bufferDisplay then\
  1569. self.gdi__device=displayBuffer(peripheral.wrap(side))\
  1570. else\
  1571. self.gdi__device=peripheral.wrap(side)\
  1572. end\
  1573. elseif devType==\"printer\" then\
  1574. self.gdi__side=side\
  1575. self.gdi__type=GDI_PRINTER\
  1576. self.gdi__device=peripheral.wrap(side)\
  1577. else\
  1578. return false\
  1579. end\
  1580. end\
  1581. return true\
  1582. end\
  1583. function GDI:getSide()\
  1584. return self.gdi__side\
  1585. end\
  1586. function GDI:setDraw(draw)\
  1587. if self.gdi__shellBuffered then\
  1588. term.current().setVisible(draw)\
  1589. elseif self.gdi__device.setDraw then\
  1590. self.gdi__device.setDraw(draw)\
  1591. end\
  1592. end\
  1593. function GDI:getOrg()\
  1594. return self.gdi__xOrg,self.gdi__yOrg\
  1595. end\
  1596. function GDI:setOrg(x,y)\
  1597. self.gdi__xOrg=x\
  1598. self.gdi__yOrg=y\
  1599. end\
  1600. function GDI:getBounds(clearBounds)\
  1601. local rt=rect:new(self.gdi__bounds:unpack())\
  1602. if clearBounds then\
  1603. self.gdi__bounds:empty()\
  1604. end\
  1605. return rt\
  1606. end\
  1607. function GDI:addBounds(rt)\
  1608. self.gdi__bounds:bound(rt)\
  1609. end\
  1610. function GDI:isPrinter()\
  1611. return(self.gdi__type==GDI_PRINTER)\
  1612. end\
  1613. function GDI:isMonitor()\
  1614. return(self.gdi__type==GDI_MONITOR)\
  1615. end\
  1616. function GDI:isTerm()\
  1617. return(self.gdi__type==GDI_TERM)\
  1618. end\
  1619. function GDI:isColor()\
  1620. if self.gdi__device.isColor then\
  1621. return self.gdi__device.isColor()\
  1622. end\
  1623. return false\
  1624. end\
  1625. function GDI:getSize()\
  1626. if self:isTerm()or self:isMonitor()then\
  1627. return self.gdi__device.getSize()\
  1628. elseif self:isPrinter()then\
  1629. return self.gdi__device.getPageSize()\
  1630. end\
  1631. return 0,0\
  1632. end\
  1633. function GDI:getCursorPos()\
  1634. local x,y=self.gdi__device.getCursorPos();\
  1635. return(x-1),(y-1)\
  1636. end\
  1637. function GDI:setCursorPos(x,y)\
  1638. self.gdi__device.setCursorPos(x+1,y+1)\
  1639. end\
  1640. function GDI:setCursorBlink(blink)\
  1641. if self:isTerm()or self:isMonitor()then\
  1642. self.gdi__device.setCursorBlink(blink)\
  1643. end\
  1644. end\
  1645. function GDI:hideCursor()\
  1646. self:setCursorPos(-1,-1)\
  1647. end\
  1648. function GDI:store()\
  1649. if not self.gdi__storedCursorX or not self.gdi__storedCursorY then\
  1650. self.gdi__storedCursorX,self.gdi__storedCursorY=self:getCursorPos()\
  1651. end\
  1652. end\
  1653. function GDI:restore()\
  1654. if self.gdi__storedCursorX and self.gdi__storedCursorY then\
  1655. self:setCursorPos(self.gdi__storedCursorX,self.gdi__storedCursorY)\
  1656. self.gdi__storedCursorX,self.gdi__storedCursorY=nil,nil\
  1657. if __ccwin:getDesktop(self:getSide())then\
  1658. self:setTextColor(__ccwin:getDesktop(self:getSide()).dt__cursorColor)\
  1659. end\
  1660. end\
  1661. end\
  1662. function GDI:setTextColor(color)\
  1663. if self:isColor()then\
  1664. self.gdi__device.setTextColor(color)\
  1665. end\
  1666. end\
  1667. function GDI:getTextColor()\
  1668. if self.gdi__device.getTextColor then\
  1669. return self.gdi__device.getTextColor()\
  1670. end\
  1671. return colors.white\
  1672. end\
  1673. function GDI:setBackgroundColor(color)\
  1674. if self:isColor()then\
  1675. self.gdi__device.setBackgroundColor(color)\
  1676. end\
  1677. end\
  1678. function GDI:getBackgroundColor()\
  1679. if self.gdi__device.getBackgroundColor then\
  1680. return self.gdi__device.getBackgroundColor()\
  1681. end\
  1682. return colors.black\
  1683. end\
  1684. function GDI:setTextScale(scale)\
  1685. if self:isMonitor()then\
  1686. self.gdi__device.setTextScale(scale)\
  1687. end\
  1688. end\
  1689. function GDI:clearWnd(x,y,width,height)\
  1690. local rt=rect:new(x,y,width,height)\
  1691. if self.gdi__wnd then\
  1692. rt:clip(rect:new(0,0,self.gdi__wnd.width,\
  1693. self.gdi__wnd.height))\
  1694. rt:offset(self.gdi__wnd:wndToScreen(0,0))\
  1695. if self.gdi__wnd:getParent()then\
  1696. rt:clip(self.gdi__wnd:getParent():getScreenRect())\
  1697. end\
  1698. end\
  1699. rt:offset(self:getOrg())\
  1700. rt:clip(rect:new(0,0,self:getSize()))\
  1701. if not rt:isEmpty()then\
  1702. local blank=string.rep(\" \",rt.width)\
  1703. for i=0,rt.height-1,1 do\
  1704. self:setCursorPos(rt.x,rt.y+i)\
  1705. self.gdi__device.write(blank)\
  1706. end\
  1707. self:addBounds(rt)\
  1708. end\
  1709. end\
  1710. function GDI:writeWnd(text,x,y)\
  1711. local rt,txt=nil,asstring(text)\
  1712. if txt:len()then\
  1713. if self.gdi__wnd then\
  1714. rt=rect:new(x,y,txt:len(),1)\
  1715. if rt.x<0 then\
  1716. txt=txt:sub((rt.x*-1)+1)\
  1717. end\
  1718. rt:clip(rect:new(0,0,self.gdi__wnd.width,\
  1719. self.gdi__wnd.height))\
  1720. rt:offset(self.gdi__wnd:wndToScreen(0,0))\
  1721. local screenX=rt.x\
  1722. if self.gdi__wnd:getParent()then\
  1723. rt:clip(self.gdi__wnd:getParent():getScreenRect())\
  1724. end\
  1725. if screenX<rt.x then\
  1726. txt=txt:sub((rt.x-screenX)+1)\
  1727. end\
  1728. else\
  1729. if x<0 then\
  1730. txt=txt:sub((x*-1)+1)\
  1731. x=0\
  1732. end\
  1733. rt=rect:new(x,y,txt:len(),1)\
  1734. end\
  1735. rt:offset(self:getOrg())\
  1736. rt:clip(rect:new(0,0,self:getSize()))\
  1737. if not rt:isEmpty()then\
  1738. if txt:len()>rt.width then\
  1739. txt=txt:sub(1,rt.width)\
  1740. end\
  1741. self:setCursorPos(rt.x,rt.y)\
  1742. self.gdi__device.write(txt)\
  1743. self:addBounds(rt)\
  1744. end\
  1745. end\
  1746. end\
  1747. function GDI:clear(x,y,width,height)\
  1748. local rt;\
  1749. if self.gdi__wnd then\
  1750. rt=rect:new(x-self.gdi__wnd.wnd__scrollX,\
  1751. y-self.gdi__wnd.wnd__scrollY,width,height)\
  1752. rt:clip(rect:new(0,0,self.gdi__wnd:getClientSize()))\
  1753. rt:offset(self.gdi__wnd:wndToScreen(0,0))\
  1754. if self.gdi__wnd:getParent()then\
  1755. rt:clip(self.gdi__wnd:getParent():getScreenRect())\
  1756. end\
  1757. else\
  1758. rt=rect:new(x,y,width,height)\
  1759. end\
  1760. rt:offset(self:getOrg())\
  1761. rt:clip(rect:new(0,0,self:getSize()))\
  1762. if not rt:isEmpty()then\
  1763. local blank=string.rep(\" \",rt.width)\
  1764. for i=0,rt.height-1,1 do\
  1765. self:setCursorPos(rt.x,rt.y+i)\
  1766. self.gdi__device.write(blank)\
  1767. end\
  1768. self:addBounds(rt)\
  1769. end\
  1770. end\
  1771. function GDI:write(text,x,y)\
  1772. local rt,txt=nil,asstring(text)\
  1773. if txt:len()then\
  1774. if self.gdi__wnd then\
  1775. rt=rect:new(x-self.gdi__wnd.wnd__scrollX,\
  1776. y-self.gdi__wnd.wnd__scrollY,\
  1777. txt:len(),1)\
  1778. if rt.x<0 then\
  1779. txt=txt:sub((rt.x*-1)+1)\
  1780. end\
  1781. rt:clip(rect:new(0,0,self.gdi__wnd:getClientSize()))\
  1782. rt:offset(self.gdi__wnd:wndToScreen(0,0))\
  1783. local screenX=rt.x\
  1784. if self.gdi__wnd:getParent()then\
  1785. rt:clip(self.gdi__wnd:getParent():getScreenRect())\
  1786. end\
  1787. if screenX<rt.x then\
  1788. txt=txt:sub((rt.x-screenX)+1)\
  1789. end\
  1790. else\
  1791. rt=rect:new(x,y,txt:len(),1)\
  1792. if rt.x<0 then\
  1793. txt=txt:sub((rt.x*-1)+1)\
  1794. end\
  1795. end\
  1796. rt:offset(self:getOrg())\
  1797. rt:clip(rect:new(0,0,self:getSize()))\
  1798. if not rt:isEmpty()then\
  1799. if txt:len()>rt.width then\
  1800. txt=txt:sub(1,rt.width)\
  1801. end\
  1802. self:setCursorPos(rt.x,rt.y)\
  1803. self.gdi__device.write(txt)\
  1804. self:addBounds(rt)\
  1805. end\
  1806. end\
  1807. end\
  1808. function GDI:setPixelWnd(x,y,color)\
  1809. self:setBackgroundColor(color)\
  1810. self:writeWnd(\" \",x,y)\
  1811. end\
  1812. function GDI:setPixel(x,y,color)\
  1813. self:setBackgroundColor(color)\
  1814. self:write(\" \",x,y)\
  1815. end\
  1816. function GDI:getPaperLevel()\
  1817. if self:isPrinter()then\
  1818. return self.gdi__device.getPaperLevel()\
  1819. end\
  1820. return nil\
  1821. end\
  1822. function GDI:newPage()\
  1823. if self:isPrinter()then\
  1824. return self.gdi__device.newPage()\
  1825. end\
  1826. return false\
  1827. end\
  1828. function GDI:endPage()\
  1829. if self:isPrinter()then\
  1830. return self.gdi__device.endPage()\
  1831. end\
  1832. return false\
  1833. end\
  1834. function GDI:setPageTitle(title)\
  1835. if self:isPrinter()then\
  1836. self.gdi__device.setPageTitle(title)\
  1837. end\
  1838. end\
  1839. function GDI:getInkLevel()\
  1840. if self:isPrinter()then\
  1841. return self.gdi__device.getInkLevel()\
  1842. end\
  1843. return nil\
  1844. end\
  1845. function GDI:getPageSize()\
  1846. if self:isPrinter()then\
  1847. return self.gdi__device.getPageSize()\
  1848. end\
  1849. return nil,nil\
  1850. end\
  1851. function findModem(wireless)\
  1852. return peripheral.find(\
  1853. \"modem\",\
  1854. function(name,obj)\
  1855. return iif(wireless,obj.isWireless(),\
  1856. iif(wireless==false,\
  1857. not obj.isWireless(),\
  1858. true))\
  1859. end)\
  1860. end\
  1861. comm=__classBase:base()\
  1862. function comm:constructor(name,wireless,port,timeout,relay)\
  1863. self.comm__name=name\
  1864. self.comm__wireless=wireless\
  1865. self.comm__port=port or 80\
  1866. self.comm__timeout=timeout or 5\
  1867. self.comm__relay=relay==true\
  1868. self.comm__interests={}\
  1869. self.comm__processing={}\
  1870. return self\
  1871. end\
  1872. function comm:getName()\
  1873. return self.comm__name\
  1874. end\
  1875. function comm:setName(name)\
  1876. self.comm__name=name\
  1877. end\
  1878. function comm:getPort()\
  1879. return self.comm__port\
  1880. end\
  1881. function comm:setPort(port)\
  1882. self.comm__port=port or 80\
  1883. end\
  1884. function comm:getTimeout()\
  1885. return self.comm__timeout\
  1886. end\
  1887. function comm:setTimeout(timeout)\
  1888. self.comm__timeout=timeout or 5\
  1889. end\
  1890. function comm:getRelay()\
  1891. return self.comm__relay\
  1892. end\
  1893. function comm:setRelay(relay)\
  1894. self.comm__relay=relay==true\
  1895. end\
  1896. function comm:getWireless()\
  1897. return self.comm__wireless\
  1898. end\
  1899. function comm:setWireless(wireless)\
  1900. self.comm__wireless=wireless\
  1901. end\
  1902. function comm:modem()\
  1903. return findModem(self.comm__wireless)\
  1904. end\
  1905. function comm:connect()\
  1906. local modem=self:modem()\
  1907. if modem then\
  1908. modem.open(self:getPort())\
  1909. return true\
  1910. end\
  1911. return false\
  1912. end\
  1913. function comm:disconnect()\
  1914. local modem=self:modem()\
  1915. if modem then\
  1916. modem.close(self:getPort())\
  1917. end\
  1918. end\
  1919. function comm:ready()\
  1920. local modem=self:modem()\
  1921. if modem then\
  1922. if modem.isOpen(self:getPort())then\
  1923. return modem\
  1924. end\
  1925. end\
  1926. return nil\
  1927. end\
  1928. function comm:transmit(message)\
  1929. local modem=self:ready()\
  1930. if modem then\
  1931. modem.transmit(self:getPort(),self:getPort(),message)\
  1932. return true\
  1933. end\
  1934. return false\
  1935. end\
  1936. function comm:register(wnd,application)\
  1937. self.comm__interests[#self.comm__interests+1]=\
  1938. {\
  1939. wnd=wnd,\
  1940. application=application\
  1941. }\
  1942. end\
  1943. function comm:unregister(wnd,application)\
  1944. for i=#self.comm__interests,1,-1 do\
  1945. local interest=self.comm__interests[i]\
  1946. if interest.wnd==wnd and\
  1947. (interest.application==application or not application)then\
  1948. table.remove(self.comm__interests,i)\
  1949. end\
  1950. end\
  1951. end\
  1952. function comm:copyMsg(msg)\
  1953. return textutils.unserialize(textutils.serialize(msg))\
  1954. end\
  1955. function comm:callSentHandlers(msg,result)\
  1956. for i=1,#self.comm__interests,1 do\
  1957. if self.comm__interests[i].application==msg.application then\
  1958. __ccwin:pumpEvent(self.comm__interests[i].wnd,\"comm_sent\",self:copyMsg(msg),result)\
  1959. end\
  1960. end\
  1961. end\
  1962. function comm:isDuplicate(msg)\
  1963. for i=1,#self.comm__processing,1 do\
  1964. local process=self.comm__processing[i]\
  1965. if process.msg.messageId==msg.messageId then\
  1966. if process.status==\"received\" or\
  1967. (process.status==\"relay\" and\
  1968. process.msg.sequence==msg.sequence)then\
  1969. return true\
  1970. end\
  1971. end\
  1972. end\
  1973. return false\
  1974. end\
  1975. function comm:isConfirmation(msg)\
  1976. if msg.context==\"confirm\" then\
  1977. for i=#self.comm__processing,1,-1 do\
  1978. local process=self.comm__processing[i]\
  1979. if process.status==\"send\" then\
  1980. if process.msg.messageId==msg.messageId then\
  1981. self:callSentHandlers(process.msg,true)\
  1982. table.remove(self.comm__processing,i)\
  1983. end\
  1984. end\
  1985. end\
  1986. return true\
  1987. end\
  1988. return false\
  1989. end\
  1990. function comm:isFromMe(msg)\
  1991. return(asnumber(msg.senderId)==os.getComputerID()or\
  1992. asstring(msg.senderName)==os.getComputerLabel())\
  1993. end\
  1994. function comm:isForMe(msg,exclusive)\
  1995. if msg.recipientId then\
  1996. return asnumber(msg.recipientId)==os.getComputerID()\
  1997. elseif msg.recipientName then\
  1998. return asstring(msg.recipientName)==os.getComputerLabel()\
  1999. elseif exclusive then\
  2000. return false\
  2001. end\
  2002. return(not self:isFromMe(msg))\
  2003. end\
  2004. function comm:callReceiveHandlers(msg,modemSide,senderChannel,replyChannel,distance)\
  2005. local received=false\
  2006. local copy=self:copyMsg(msg)\
  2007. copy.modemSide=modemSide\
  2008. copy.senderChannel=senderChannel\
  2009. copy.replyChannel=replyChannel\
  2010. copy.distance=distance\
  2011. for i=1,#self.comm__interests,1 do\
  2012. if self.comm__interests[i].application==msg.application then\
  2013. if __ccwin:pumpEvent(self.comm__interests[i].wnd,\"comm_receive\",copy)then\
  2014. received=true\
  2015. end\
  2016. end\
  2017. end\
  2018. return received\
  2019. end\
  2020. function comm:sendConfirmation(msg)\
  2021. if msg.recipientName or msg.recipientId then\
  2022. local copy=self:copyMsg(msg)\
  2023. copy.context=\"confirm\"\
  2024. copy.recipientName=copy.senderName\
  2025. copy.recipientId=copy.senderId\
  2026. copy.senderName=os.getComputerLabel()\
  2027. copy.senderId=os.getComputerID()\
  2028. copy.sequence=-1\
  2029. if not self:transmit(textutils.serialize(copy))then\
  2030. syslog(\"comm \"..self:getName()..\" no modem for confirmation to \"..asstring(msg.senderName))\
  2031. end\
  2032. end\
  2033. end\
  2034. function comm:receive(modemSide,senderChannel,replyChannel,message,distance)\
  2035. if senderChannel==self:getPort()then\
  2036. local success,msg=pcall(textutils.unserialize,message)\
  2037. if success and type(msg)==\"table\" then\
  2038. if msg.messageId and msg.application and msg.context then\
  2039. if self:isForMe(msg)then\
  2040. if not self:isConfirmation(msg)then\
  2041. if not self:isDuplicate(msg)then\
  2042. if self:callReceiveHandlers(msg,modemSide,senderChannel,replyChannel,distance)then\
  2043. self.comm__processing[#self.comm__processing+1]=\
  2044. {\
  2045. timeStamp=os.clock(),\
  2046. status=\"received\",\
  2047. msg=msg\
  2048. }\
  2049. self:sendConfirmation(msg)\
  2050. end\
  2051. end\
  2052. end\
  2053. end\
  2054. if self:getRelay()then\
  2055. if not self:isFromMe(msg)and not self:isForMe(msg,true)then\
  2056. if not self:isDuplicate(msg)then\
  2057. if not self:transmit(message)then\
  2058. syslog(\"comm \"..self:getName()..\" no modem to relay message\")\
  2059. end\
  2060. self.comm__processing[#self.comm__processing+1]=\
  2061. {\
  2062. timeStamp=os.clock(),\
  2063. status=\"relay\",\
  2064. msg=msg\
  2065. }\
  2066. end\
  2067. end\
  2068. end\
  2069. end\
  2070. end\
  2071. end\
  2072. end\
  2073. function comm:send(recipient,application,context,data)\
  2074. local msg={}\
  2075. local method=\"send\"\
  2076. if recipient then\
  2077. if type(recipient)==\"number\" then\
  2078. msg.recipientId=recipient\
  2079. if msg.recipientId==os.getComputerID()then\
  2080. return\
  2081. end\
  2082. else\
  2083. msg.recipientName=asstring(recipient)\
  2084. if msg.recipientName==os.getComputerLabel()then\
  2085. return\
  2086. end\
  2087. end\
  2088. else\
  2089. method=\"broadcast\"\
  2090. end\
  2091. msg.context=context\
  2092. msg.application=application\
  2093. msg.data=data\
  2094. msg.senderId=os.getComputerID()\
  2095. msg.senderName=os.getComputerLabel()or \"\"\
  2096. msg.messageId=math.random(1,65535)\
  2097. msg.sequence=0\
  2098. self.comm__processing[#self.comm__processing+1]=\
  2099. {\
  2100. timeStamp=os.clock(),\
  2101. status=method,\
  2102. msg=msg\
  2103. }\
  2104. return msg.messageId\
  2105. end\
  2106. function comm:process()\
  2107. for i=#self.comm__processing,1,-1 do\
  2108. local process=self.comm__processing[i]\
  2109. if process.status==\"received\" or process.status==\"relay\" then\
  2110. if(os.clock()-process.timeStamp)>(self:getTimeout()*2)then\
  2111. table.remove(self.comm__processing,i)\
  2112. end\
  2113. elseif process.status==\"send\" or process.status==\"broadcast\" then\
  2114. if(os.clock()-process.timeStamp)>self:getTimeout()then\
  2115. if process.status==\"send\" then\
  2116. self:callSentHandlers(process.msg,false)\
  2117. end\
  2118. table.remove(self.comm__processing,i)\
  2119. else\
  2120. process.msg.sequence=process.msg.sequence+1\
  2121. if self:transmit(textutils.serialize(process.msg))then\
  2122. if process.status==\"broadcast\" then\
  2123. if process.msg.sequence==1 then\
  2124. self:callSentHandlers(process.msg,true)\
  2125. end\
  2126. end\
  2127. else\
  2128. syslog(\"comm \"..self:getName()..\" no modem to send message\")\
  2129. end\
  2130. end\
  2131. end\
  2132. end\
  2133. end\
  2134. window=__classBase:base()\
  2135. function window:constructor(parent,id,x,y,width,height)\
  2136. self.x=math.floor(asnumber(x))\
  2137. self.y=math.floor(asnumber(y))\
  2138. self.width=math.floor(asnumber(width))\
  2139. self.height=math.floor(asnumber(height))\
  2140. self.wnd__parent=nil\
  2141. self.wnd__owner=nil\
  2142. self.wnd__popup=nil\
  2143. self.wnd__frameClass=FRAME_CLASS_WINDOW\
  2144. self.wnd__id=asnumber(id)\
  2145. self.wnd__color=colors.black\
  2146. self.wnd__bgColor=0\
  2147. self.wnd__cursorX=0\
  2148. self.wnd__cursorY=0\
  2149. self.wnd__scrollX=0\
  2150. self.wnd__scrollY=0\
  2151. self.wnd__scrollWidth=0\
  2152. self.wnd__scrollHeight=0\
  2153. self.wnd__enabled=true\
  2154. self.wnd__hidden=false\
  2155. self.wnd__text=\"\"\
  2156. self.wnd__wantFocus=true\
  2157. self.wnd__alive=true\
  2158. self.wnd__wantKeyInput=KEYINPUT_NONE\
  2159. self.gdi=nil\
  2160. self.wnd__nodes={}\
  2161. self.wnd__invalid=rect:new()\
  2162. self:setParent(parent)\
  2163. return self\
  2164. end\
  2165. function window:invalidate(x,y,width,height)\
  2166. if not x then\
  2167. x=0\
  2168. end\
  2169. if not y then\
  2170. y=0\
  2171. end\
  2172. if not width then\
  2173. width=self.width\
  2174. end\
  2175. if not height then\
  2176. height=self.height\
  2177. end\
  2178. self.wnd__invalid:bound(rect:new(math.floor(x),math.floor(y),\
  2179. math.floor(width),math.floor(height)))\
  2180. if self:getParent()then\
  2181. local px,py=wndToScreen(self,self.wnd__invalid.x,\
  2182. self.wnd__invalid.y)\
  2183. px,py=screenToWnd(self:getParent(),px,py)\
  2184. self:getParent():invalidate(px,py,\
  2185. self.wnd__invalid.width,\
  2186. self.wnd__invalid.height)\
  2187. end\
  2188. end\
  2189. function window:validate()\
  2190. self.wnd__invalid=rect:new(0,0,0,0)\
  2191. end\
  2192. function window:move(x,y,width,height,z)\
  2193. self:invalidate()\
  2194. self:validate()\
  2195. if x then\
  2196. self.x=math.floor(x)\
  2197. end\
  2198. if y then\
  2199. self.y=math.floor(y)\
  2200. end\
  2201. if width then\
  2202. self.width=math.floor(width)\
  2203. end\
  2204. if height then\
  2205. self.height=math.floor(height)\
  2206. end\
  2207. if z and self:getParent()then\
  2208. local pos=self:getParent():childIndex(self)\
  2209. local i=pos\
  2210. if i>0 then\
  2211. if z==WND_TOP then\
  2212. pos=1\
  2213. elseif z==WND_BOTTOM then\
  2214. pos=self:getParent():children()\
  2215. else\
  2216. pos=pos+z\
  2217. end\
  2218. if pos<1 then\
  2219. pos=1\
  2220. elseif pos>self:getParent():children()then\
  2221. pos=self:getParent():children()\
  2222. end\
  2223. table.insert(self:getParent().wnd__nodes,pos,\
  2224. table.remove(self:getParent().wnd__nodes,i))\
  2225. end\
  2226. end\
  2227. self:setScrollOrg(self:getScrollOrg())\
  2228. self:invalidate()\
  2229. local success,msg=pcall(self.onMove,self)\
  2230. if not success then\
  2231. syslog(\"onMove \"..msg)\
  2232. end\
  2233. end\
  2234. function window:getGDI()\
  2235. self.gdi:store()\
  2236. return self.gdi\
  2237. end\
  2238. function window:releaseGDI()\
  2239. self.gdi:restore()\
  2240. end\
  2241. function window:setId(id)\
  2242. self.wnd__id=asnumber(id)\
  2243. end\
  2244. function window:getId()\
  2245. return self.wnd__id\
  2246. end\
  2247. function window:getColor()\
  2248. return self.wnd__color\
  2249. end\
  2250. function window:setColor(color)\
  2251. self.wnd__color=asnumber(color,colors.black)\
  2252. self:invalidate()\
  2253. end\
  2254. function window:getBgColor()\
  2255. return self.wnd__bgColor\
  2256. end\
  2257. function window:setBgColor(color)\
  2258. self.wnd__bgColor=asnumber(color,colors.white)\
  2259. self:invalidate()\
  2260. end\
  2261. function window:getText()\
  2262. return self.wnd__text\
  2263. end\
  2264. function window:setText(text)\
  2265. self.wnd__text=asstring(text)\
  2266. self:invalidate()\
  2267. end\
  2268. function window:getWantFocus()\
  2269. return self.wnd__wantFocus\
  2270. end\
  2271. function window:setWantFocus(want)\
  2272. self.wnd__wantFocus=want\
  2273. end\
  2274. function window:getWantKeyInput()\
  2275. return self.wnd__wantKeyInput\
  2276. end\
  2277. function window:setWantKeyInput(keyInput)\
  2278. self.wnd__wantKeyInput=keyInput\
  2279. end\
  2280. function window:show(show)\
  2281. show=show~=false\
  2282. if(not show)~=self.wnd__hidden then\
  2283. if not show then\
  2284. if self:capturedMouse()==self then\
  2285. self:releaseMouse()\
  2286. end\
  2287. if self:getFocus()==self then\
  2288. local frame=self:getParentFrame()\
  2289. if frame then\
  2290. frame:setFocusWnd(nil)\
  2291. end\
  2292. end\
  2293. end\
  2294. self.wnd__hidden=not show\
  2295. self:invalidate()\
  2296. end\
  2297. end\
  2298. function window:isShown()\
  2299. if self.wnd__hidden then\
  2300. return false\
  2301. end\
  2302. if self:getParent()then\
  2303. return self:getParent():isShown()\
  2304. end\
  2305. return true\
  2306. end\
  2307. function window:enable(enable)\
  2308. enable=enable~=false\
  2309. if enable~=self.wnd__enabled then\
  2310. if not enable then\
  2311. if self:capturedMouse()==self then\
  2312. self:releaseMouse()\
  2313. end\
  2314. if self:getFocus()==self then\
  2315. local frame=self:getParentFrame()\
  2316. if frame then\
  2317. frame:setFocusWnd(nil)\
  2318. end\
  2319. end\
  2320. end\
  2321. self.wnd__enabled=enable\
  2322. self:invalidate()\
  2323. end\
  2324. end\
  2325. function window:isEnabled()\
  2326. if not self.wnd__enabled then\
  2327. return false\
  2328. end\
  2329. if self:getParent()then\
  2330. return self:getParent():isEnabled()\
  2331. end\
  2332. return true\
  2333. end\
  2334. function window:children()\
  2335. return #self.wnd__nodes\
  2336. end\
  2337. function window:addChild(child)\
  2338. self.wnd__nodes[self:children()+1]=child\
  2339. end\
  2340. function window:getChild(i)\
  2341. if i>0 and i<=self:children()then\
  2342. return self.wnd__nodes[i]\
  2343. end\
  2344. return nil\
  2345. end\
  2346. function window:childIndex(child)\
  2347. for i=1,self:children(),1 do\
  2348. if self.wnd__nodes[i]==child then\
  2349. return i\
  2350. end\
  2351. end\
  2352. return 0\
  2353. end\
  2354. function window:removeChild(child)\
  2355. local i=self:childIndex(child)\
  2356. if i>0 then\
  2357. table.remove(self.wnd__nodes,i)\
  2358. return true\
  2359. end\
  2360. return false\
  2361. end\
  2362. function window:getParent()\
  2363. return self.wnd__parent\
  2364. end\
  2365. function window:setParent(parent)\
  2366. if parent then\
  2367. if parent:childIndex(self)==0 then\
  2368. if self.wnd__parent then\
  2369. self:invalidate()\
  2370. self.wnd__parent:removeChild(self)\
  2371. end\
  2372. self.wnd__parent=parent\
  2373. if not self.gdi then\
  2374. self.gdi=GDI:new(parent:getSide(),self)\
  2375. else\
  2376. self.gdi:setSide(parent:getSide())\
  2377. end\
  2378. parent:addChild(self)\
  2379. self:invalidate()\
  2380. end\
  2381. else\
  2382. if self.wnd__parent then\
  2383. self:invalidate()\
  2384. self.wnd__parent:removeChild(self)\
  2385. self.wnd__parent=nil\
  2386. end\
  2387. end\
  2388. end\
  2389. function window:destroyWnd()\
  2390. if self.wnd__alive then\
  2391. self.wnd__alive=false\
  2392. local success,msg=pcall(self.onDestroyWnd,self)\
  2393. if not success then\
  2394. syslog(\"onDestroyWnd \"..msg)\
  2395. end\
  2396. self:show(false)\
  2397. self:unwantMessages()\
  2398. if self.wnd__popup then\
  2399. self.wnd__popup:destroyWnd()\
  2400. end\
  2401. if self.wnd__owner then\
  2402. self.wnd__owner.wnd__popup=nil\
  2403. self.wnd__owner:enable(true)\
  2404. end\
  2405. if self:capturedMouse()==self then\
  2406. self:releaseMouse()\
  2407. end\
  2408. if self:getDesktop()then\
  2409. if self:getDesktop().dt__dragWnd==self then\
  2410. self:getDesktop().dt__dragWnd=nil\
  2411. end\
  2412. end\
  2413. if self:getFocus()==self then\
  2414. local frame=self:getParentFrame()\
  2415. if frame then\
  2416. frame:setFocusWnd(nil)\
  2417. end\
  2418. end\
  2419. self:getWorkSpace():unwantEvent(self,nil)\
  2420. self:getWorkSpace():killTimers(self)\
  2421. for i=self:children(),1,-1 do\
  2422. local child=self:getChild(i)\
  2423. if child then\
  2424. child:destroyWnd()\
  2425. end\
  2426. end\
  2427. self:setParent(nil)\
  2428. end\
  2429. end\
  2430. function window:getWorkSpace()\
  2431. return __ccwin\
  2432. end\
  2433. function window:getDesktop()\
  2434. return self:getWorkSpace():getDesktop(self:getSide())\
  2435. end\
  2436. function window:getParentFrame()\
  2437. local parent=self:getParent()\
  2438. while parent do\
  2439. if parent.wnd__frameClass~=FRAME_CLASS_WINDOW then\
  2440. return parent\
  2441. end\
  2442. parent=parent:getParent()\
  2443. end\
  2444. return nil\
  2445. end\
  2446. function window:getAppFrame()\
  2447. local parent=self:getParent()\
  2448. local desktop=self:getDesktop()\
  2449. if(self.wnd__frameClass==FRAME_CLASS_APPLICATION or\
  2450. self.wnd__frameClass==FRAME_CLASS_SYSTEM)\
  2451. and parent==desktop then\
  2452. return self\
  2453. end\
  2454. if self.wnd__owner then\
  2455. parent=self.wnd__owner\
  2456. end\
  2457. while parent do\
  2458. if(parent.wnd__frameClass==FRAME_CLASS_APPLICATION or\
  2459. parent.wnd__frameClass==FRAME_CLASS_SYSTEM)\
  2460. and parent:getParent()==desktop then\
  2461. return parent\
  2462. end\
  2463. if parent.wnd__owner then\
  2464. parent=parent.wnd__owner\
  2465. else\
  2466. parent=parent:getParent()\
  2467. end\
  2468. end\
  2469. return nil\
  2470. end\
  2471. function window:getTheme()\
  2472. if self:getDesktop()then\
  2473. return self:getDesktop():getTheme()\
  2474. end\
  2475. return __defaultTheme\
  2476. end\
  2477. function window:getColors()\
  2478. return self:getTheme().color\
  2479. end\
  2480. function window:getSide()\
  2481. if self.gdi then\
  2482. return self.gdi:getSide()\
  2483. end\
  2484. return \"\"\
  2485. end\
  2486. function window:hasScrollBars()\
  2487. local vert,horz,width,height=\
  2488. false,false,self.width,self.height\
  2489. if self.wnd__scrollHeight>self.height then\
  2490. vert=true\
  2491. width=self.width-1\
  2492. end\
  2493. if self.wnd__scrollWidth>width then\
  2494. horz=true\
  2495. height=self.height-1\
  2496. end\
  2497. vert=(self.wnd__scrollHeight>height)\
  2498. return vert,horz\
  2499. end\
  2500. function window:getClientSize()\
  2501. local vert,horz=self:hasScrollBars()\
  2502. local width,height=self.width,self.height\
  2503. if vert then\
  2504. width=self.width-1\
  2505. end\
  2506. if horz then\
  2507. height=self.height-1\
  2508. end\
  2509. return width,height\
  2510. end\
  2511. function window:getScrollOrg()\
  2512. return self.wnd__scrollX,self.wnd__scrollY\
  2513. end\
  2514. function window:setScrollOrg(x,y)\
  2515. local width,height=self:getClientSize()\
  2516. local tx,ty=x,y\
  2517. if(tx+width)>self.wnd__scrollWidth then\
  2518. tx=self.wnd__scrollWidth-width\
  2519. end\
  2520. if tx<0 or self.wnd__scrollWidth<=width then\
  2521. tx=0\
  2522. end\
  2523. if(ty+height)>self.wnd__scrollHeight then\
  2524. ty=self.wnd__scrollHeight-height\
  2525. end\
  2526. if ty<0 or self.wnd__scrollHeight<=height then\
  2527. ty=0\
  2528. end\
  2529. if tx~=self.wnd__scrollX or ty~=self.wnd__scrollY then\
  2530. self.wnd__scrollX=tx\
  2531. self.wnd__scrollY=ty\
  2532. self:invalidate()\
  2533. local success,msg=pcall(self.onScroll,self)\
  2534. if not success then\
  2535. syslog(\"onScroll \"..msg)\
  2536. end\
  2537. end\
  2538. end\
  2539. function window:setScrollSize(width,height)\
  2540. if self.wnd__scrollWidth~=width or\
  2541. self.wnd__scrollHeight~=height then\
  2542. self.wnd__scrollWidth=width\
  2543. self.wnd__scrollHeight=height\
  2544. if self.wnd__scrollWidth<0 then\
  2545. self.wnd__scrollWidth=0\
  2546. end\
  2547. if self.wnd__scrollHeight<0 then\
  2548. self.wnd__scrollHeight=0\
  2549. end\
  2550. self:setScrollOrg(self.wnd__scrollX,self.wnd__scrollY)\
  2551. self:invalidate()\
  2552. end\
  2553. end\
  2554. function window:getScrollSize()\
  2555. return self.wnd__scrollWidth,self.wnd__scrollHeight\
  2556. end\
  2557. function window:scrollLines(lines)\
  2558. self:setScrollOrg(self.wnd__scrollX,\
  2559. self.wnd__scrollY+lines)\
  2560. end\
  2561. function window:scrollCols(cols)\
  2562. self:setScrollOrg(self.wnd__scrollX+cols,\
  2563. self.wnd__scrollY)\
  2564. end\
  2565. function window:getWndRect()\
  2566. return rect:new(self.x,self.y,self.width,self.height)\
  2567. end\
  2568. function window:getScreenRect()\
  2569. local x,y=self:wndToScreen(0,0)\
  2570. return rect:new(x,y,self.width,self.height)\
  2571. end\
  2572. function window:wndAtPoint(x,y,recurse,disabled,hidden)\
  2573. if(self:isShown()or hidden)and(self:isEnabled()or disabled)then\
  2574. local sx,sy=self:screenToWnd(math.floor(x),math.floor(y))\
  2575. local rt=rect:new(0,0,self.width,self.height)\
  2576. if rt:contains(sx,sy)then\
  2577. for i=1,self:children(),1 do\
  2578. local wnd=self:getChild(i):wndAtPoint(x,y,recurse,disabled,hidden)\
  2579. if wnd then\
  2580. return wnd\
  2581. end\
  2582. end\
  2583. return self\
  2584. end\
  2585. end\
  2586. return nil\
  2587. end\
  2588. function window:wndFromPoint(x,y)\
  2589. local wnd=self:wndAtPoint(x,y,true,true,false)\
  2590. if wnd then\
  2591. if wnd:isEnabled()then\
  2592. return wnd\
  2593. end\
  2594. end\
  2595. return nil\
  2596. end\
  2597. function window:getWndById(id,recursive)\
  2598. for i=1,self:children(),1 do\
  2599. if self:getChild(i):getId()==id then\
  2600. return self:getChild(i)\
  2601. end\
  2602. end\
  2603. if recursive~=false then\
  2604. for i=1,self:children(),1 do\
  2605. local wnd=self:getChild(i):getWndById(id)\
  2606. if wnd then\
  2607. return wnd\
  2608. end\
  2609. end\
  2610. end\
  2611. return nil\
  2612. end\
  2613. function window:draw(gdi,bounds)\
  2614. end\
  2615. function window:update(force)\
  2616. if self:isShown()then\
  2617. if force then\
  2618. self:invalidate()\
  2619. end\
  2620. if not self.wnd__invalid:isEmpty()then\
  2621. self.gdi:store()\
  2622. local vert,horz=self:hasScrollBars()\
  2623. local zx,zy=self:getClientSize()\
  2624. if self:getBgColor()>0 then\
  2625. local rtErase=rect:new(0,0,zx,zy)\
  2626. rtErase:clip(self.wnd__invalid)\
  2627. self.gdi:setBackgroundColor(self:getBgColor())\
  2628. self.gdi:clearWnd(rtErase:unpack())\
  2629. else\
  2630. local rtBound=rect:new(self.wnd__invalid:unpack())\
  2631. rtBound.x,rtBound.y=self:wndToScreen(rtBound.x,rtBound.y)\
  2632. self.gdi:addBounds(rtBound)\
  2633. end\
  2634. self:draw(self.gdi,rect:new(self.wnd__invalid:unpack()))\
  2635. for i=self:children(),1,-1 do\
  2636. local child=self:getChild(i)\
  2637. if child:getScreenRect():overlap(self.gdi:getBounds())then\
  2638. self.gdi:addBounds(child:update(true))\
  2639. end\
  2640. end\
  2641. if vert or horz then\
  2642. local vertLeft=self.width-1\
  2643. local vertBottom=self.height-iif(horz,2,1)\
  2644. local horzTop=self.height-1\
  2645. local horzRight=self.width-iif(vert,2,1)\
  2646. if vert then\
  2647. self.gdi:setTextColor(self:getColors().scrollText)\
  2648. self.gdi:setBackgroundColor(self:getColors().scrollBack)\
  2649. if ccVersion()>=1.76 then\
  2650. self.gdi:writeWnd(string.char(30),vertLeft,0)\
  2651. self.gdi:writeWnd(string.char(31),vertLeft,vertBottom)\
  2652. else\
  2653. self.gdi:writeWnd(\"^\",vertLeft,0)\
  2654. self.gdi:writeWnd(\"v\",vertLeft,vertBottom)\
  2655. end\
  2656. self.gdi:setBackgroundColor(self:getColors().scrollTrack)\
  2657. for i=1,vertBottom-1,1 do\
  2658. self.gdi:writeWnd(\" \",vertLeft,i)\
  2659. end\
  2660. if vertBottom>3 then\
  2661. self.gdi:setBackgroundColor(self:getColors().scrollBack)\
  2662. self.gdi:writeWnd(\" \",vertLeft,\
  2663. math.floor((self.wnd__scrollY/(self.wnd__scrollHeight-zy))*(vertBottom-2))+1)\
  2664. end\
  2665. end\
  2666. if horz then\
  2667. self.gdi:setTextColor(self:getColors().scrollText)\
  2668. self.gdi:setBackgroundColor(self:getColors().scrollBack)\
  2669. if ccVersion()>=1.76 then\
  2670. self.gdi:writeWnd(string.char(17),0,horzTop)\
  2671. self.gdi:writeWnd(string.char(16),horzRight,horzTop)\
  2672. else\
  2673. self.gdi:writeWnd(\"<\",0,horzTop)\
  2674. self.gdi:writeWnd(\">\",horzRight,horzTop)\
  2675. end\
  2676. if horzRight>1 then\
  2677. self.gdi:setBackgroundColor(self:getColors().scrollTrack)\
  2678. self.gdi:writeWnd(string.rep(\" \",horzRight-1),1,horzTop)\
  2679. end\
  2680. if horzRight>3 then\
  2681. self.gdi:setBackgroundColor(self:getColors().scrollBack)\
  2682. self.gdi:writeWnd(\" \",\
  2683. math.floor((self.wnd__scrollX/(self.wnd__scrollWidth-zx))*(horzRight-2))+1,\
  2684. horzTop)\
  2685. end\
  2686. end\
  2687. if vert and horz then\
  2688. local corner=self:getColors().scrollTrack\
  2689. if self:getParent()then\
  2690. if self:getParent():getBgColor()~=0 then\
  2691. corner=self:getParent():getBgColor()\
  2692. end\
  2693. end\
  2694. self.gdi:setBackgroundColor(corner)\
  2695. self.gdi:writeWnd(\" \",vertLeft,horzTop)\
  2696. end\
  2697. end\
  2698. self:validate()\
  2699. self.gdi:restore()\
  2700. end\
  2701. return self.gdi:getBounds(true)\
  2702. end\
  2703. return rect:new()\
  2704. end\
  2705. function window:print(gdi,children,hidden)\
  2706. if self:isShown()or hidden then\
  2707. if self:getBgColor()>0 then\
  2708. gdi:setBackgroundColor(self:getBgColor())\
  2709. gdi:clear(self:getWndRect())\
  2710. end\
  2711. self:draw(gdi,self:getWndRect())\
  2712. if children then\
  2713. for i=self:children(),1,-1 do\
  2714. gdi:addBounds(self:getChild(i):print(gdi,children,hidden))\
  2715. end\
  2716. end\
  2717. end\
  2718. end\
  2719. function window:wndToScreen(x,y)\
  2720. return wndToScreen(self,x,y)\
  2721. end\
  2722. function window:screenToWnd(x,y)\
  2723. return screenToWnd(self,x,y)\
  2724. end\
  2725. function window:wndToScroll(x,y)\
  2726. return(x+self.wnd__scrollX),(y+self.wnd__scrollY)\
  2727. end\
  2728. function window:scrollToWnd(x,y)\
  2729. return(x-self.wnd__scrollX),(y-self.wnd__scrollY)\
  2730. end\
  2731. function window:getCursorPos()\
  2732. return self.wnd__cursorX,self.wnd__cursorY\
  2733. end\
  2734. function window:setCursorPos(x,y)\
  2735. local width,height=self:getClientSize()\
  2736. self.wnd__cursorX=x\
  2737. self.wnd__cursorY=y\
  2738. if self:getDesktop()then\
  2739. self:getDesktop().dt__cursorColor=self:getColor()\
  2740. end\
  2741. if(x-self.wnd__scrollX)>=0 and\
  2742. (x-self.wnd__scrollX)<width and\
  2743. (y-self.wnd__scrollY)>=0 and\
  2744. (y-self.wnd__scrollY)<height then\
  2745. self.gdi:setCursorPos(self:wndToScreen(x-self.wnd__scrollX,\
  2746. y-self.wnd__scrollY))\
  2747. self.gdi:setCursorBlink(true)\
  2748. else\
  2749. self.gdi:hideCursor()\
  2750. end\
  2751. end\
  2752. function window:captureMouse()\
  2753. if self:getDesktop()then\
  2754. self:getDesktop():captureMouse(self)\
  2755. end\
  2756. end\
  2757. function window:releaseMouse()\
  2758. if self:getDesktop()then\
  2759. self:getDesktop():captureMouse(nil)\
  2760. end\
  2761. end\
  2762. function window:capturedMouse()\
  2763. if self:getDesktop()then\
  2764. return self:getDesktop():capturedMouse()\
  2765. end\
  2766. return nil\
  2767. end\
  2768. function window:getClipboard()\
  2769. if self:getDesktop()then\
  2770. return self:getDesktop():getClipboard()\
  2771. end\
  2772. return CB_EMPTY,nil\
  2773. end\
  2774. function window:setClipboard(data,cbType)\
  2775. if self:getDesktop()then\
  2776. self:getDesktop():setClipboard(data,cbType)\
  2777. end\
  2778. end\
  2779. function window:setCursorBlink(blink)\
  2780. self.gdi:setCursorBlink(blink)\
  2781. end\
  2782. function window:hideCursor()\
  2783. self.gdi:hideCursor()\
  2784. end\
  2785. function window:showCursor()\
  2786. self:setCursorPos(self.wnd__cursorX,self.wnd__cursorY)\
  2787. end\
  2788. function window:startTimer(timeout)\
  2789. return self:getWorkSpace():startTimer(self,timeout)\
  2790. end\
  2791. function window:setAlarm(alarmTime)\
  2792. return self:getWorkSpace():setAlarm(self,alarmTime)\
  2793. end\
  2794. function window:getFocus()\
  2795. if self:getDesktop()then\
  2796. return self:getDesktop():getFocusWnd()\
  2797. end\
  2798. return nil\
  2799. end\
  2800. function window:setFocus()\
  2801. if self==self:getFocus()then\
  2802. return true\
  2803. end\
  2804. local frame=self:getParentFrame()\
  2805. if frame then\
  2806. return frame:setFocusWnd(self)\
  2807. end\
  2808. return false\
  2809. end\
  2810. function window:comboKeys(ctrl,alt,shift)\
  2811. return self:getWorkSpace():comboKeys(ctrl,alt,shift)\
  2812. end\
  2813. function window:hitTest(x,y)\
  2814. x=math.floor(x)\
  2815. y=math.floor(y)\
  2816. if x>=0 and y>=0 and x<self.width and y<self.height then\
  2817. local vert,horz=self:hasScrollBars()\
  2818. if vert then\
  2819. local height=self.height-1\
  2820. if horz then\
  2821. height=height-1\
  2822. end\
  2823. if x==self.width-1 then\
  2824. if y==0 then\
  2825. return HT_LINEUP\
  2826. end\
  2827. if y==height then\
  2828. return HT_LINEDOWN\
  2829. end\
  2830. if y<=math.floor(height/2)and y<height then\
  2831. return HT_PAGEUP\
  2832. end\
  2833. if y>math.floor(height/2)and y>0 then\
  2834. return HT_PAGEDOWN\
  2835. end\
  2836. end\
  2837. end\
  2838. if horz then\
  2839. local width=self.width-1\
  2840. if vert then\
  2841. width=width-1\
  2842. end\
  2843. if y==self.height-1 then\
  2844. if x==0 then\
  2845. return HT_LINELEFT\
  2846. end\
  2847. if x==width then\
  2848. return HT_LINERIGHT\
  2849. end\
  2850. if x<=math.floor(width/2)and x<width then\
  2851. return HT_PAGELEFT\
  2852. end\
  2853. if x>math.floor(width/2)and x>0 then\
  2854. return HT_PAGERIGHT\
  2855. end\
  2856. end\
  2857. end\
  2858. return HT_CLIENT\
  2859. end\
  2860. return HT_NOWHERE\
  2861. end\
  2862. function window:commEnabled()\
  2863. return self:getWorkSpace():commEnabled()\
  2864. end\
  2865. function window:sendMessage(recipient,application,context,data,name,wireless)\
  2866. return self:getWorkSpace():commSend(recipient,application,context,data,name,wireless)\
  2867. end\
  2868. function window:wantMessages(application,name,wireless)\
  2869. return self:getWorkSpace():commRegister(self,application,name,wireless)\
  2870. end\
  2871. function window:unwantMessages(application,name,wireless)\
  2872. return self:getWorkSpace():commUnregister(self,application,name,wireless)\
  2873. end\
  2874. function window:commFind(name,wireless)\
  2875. return self:getWorkSpace():commFind(name,wireless)\
  2876. end\
  2877. function window:commOpen(name,wireless,port,timeout,relay)\
  2878. return self:getWorkSpace():commOpen(name,wireless,port,timeout,relay)\
  2879. end\
  2880. function window:commClose(name)\
  2881. return self:getWorkSpace():commClose(name)\
  2882. end\
  2883. function window:routeChildEvent(wnd,event,p1,p2,p3,p4,p5,...)\
  2884. if event==\"timer\" then\
  2885. return false\
  2886. end\
  2887. if event==\"idle\" then\
  2888. return false\
  2889. end\
  2890. if event==\"focus\" then\
  2891. return self:onChildFocus(wnd,p1)\
  2892. end\
  2893. if event==\"blur\" then\
  2894. return self:onChildBlur(wnd,p1)\
  2895. end\
  2896. if event==\"mouse_click\" then\
  2897. if p1==2 then\
  2898. return self:onChildRightClick(wnd,p2,p3)\
  2899. elseif p1==3 then\
  2900. return self:onChildMiddleClick(wnd,p2,p3)\
  2901. end\
  2902. return self:onChildLeftClick(wnd,p2,p3)\
  2903. end\
  2904. if event==\"mouse_up\" then\
  2905. if p1==2 then\
  2906. return self:onChildRightUp(wnd,p2,p3)\
  2907. elseif p1==3 then\
  2908. return self:onChildMiddleUp(wnd,p2,p3)\
  2909. end\
  2910. return self:onChildLeftUp(wnd,p2,p3)\
  2911. end\
  2912. if event==\"char\" then\
  2913. return self:onChildChar(wnd,p1)\
  2914. end\
  2915. if event==\"key\" then\
  2916. return self:onChildKey(wnd,p1,p2,p3,p4)\
  2917. end\
  2918. if event==\"key_up\" then\
  2919. return self:onChildKeyUp(wnd,p1)\
  2920. end\
  2921. if event==\"mouse_scroll\" then\
  2922. return false\
  2923. end\
  2924. if event==\"mouse_drag\" then\
  2925. if p1==2 then\
  2926. return self:onChildRightDrag(wnd,p2,p3)\
  2927. elseif p1==3 then\
  2928. return self:onChildMiddleDrag(wnd,p2,p3)\
  2929. end\
  2930. return self:onChildLeftDrag(wnd,p2,p3)\
  2931. end\
  2932. if event==\"monitor_touch\" then\
  2933. return self:onChildTouch(wnd,p2,p3)\
  2934. end\
  2935. if event==\"monitor_resize\" then\
  2936. return false\
  2937. end\
  2938. if event==\"alarm\" then\
  2939. return false\
  2940. end\
  2941. if event==\"paste\" then\
  2942. return self:onChildPaste(wnd,p1)\
  2943. end\
  2944. if event==\"frame_close\" then\
  2945. return false\
  2946. end\
  2947. return self:onChildEvent(wnd,event,p1,p2,p3,p4,p5,...)\
  2948. end\
  2949. function window:routeWndEvent(event,p1,p2,p3,p4,p5,...)\
  2950. if event==\"timer\" then\
  2951. return self:onTimer(p1)\
  2952. end\
  2953. if event==\"idle\" then\
  2954. return self:onIdle(p1)\
  2955. end\
  2956. if event==\"vbar_scroll\" then\
  2957. return self:onVScroll(p1,p2)\
  2958. end\
  2959. if event==\"hbar_scroll\" then\
  2960. return self:onHScroll(p1,p2)\
  2961. end\
  2962. if event==\"mouse_scroll\" then\
  2963. return self:onScrollWheel(p1,self:screenToWnd(p2,p3))\
  2964. end\
  2965. if event==\"mouse_drag\" then\
  2966. if p1==2 then\
  2967. return self:onRightDrag(self:screenToWnd(p2,p3))\
  2968. elseif p1==3 then\
  2969. return self:onMiddleDrag(self:screenToWnd(p2,p3))\
  2970. end\
  2971. return self:onLeftDrag(self:screenToWnd(p2,p3))\
  2972. end\
  2973. if event==\"comm_receive\" then\
  2974. return self:onReceive(p1)\
  2975. end\
  2976. if event==\"comm_sent\" then\
  2977. return self:onSent(p1,p2)\
  2978. end\
  2979. if event==\"focus\" then\
  2980. return self:onFocus(p1)\
  2981. end\
  2982. if event==\"blur\" then\
  2983. return self:onBlur(p1)\
  2984. end\
  2985. if event==\"mouse_click\" then\
  2986. if p1==2 then\
  2987. return self:onRightClick(self:screenToWnd(p2,p3))\
  2988. elseif p1==3 then\
  2989. return self:onMiddleClick(self:screenToWnd(p2,p3))\
  2990. end\
  2991. return self:onLeftClick(self:screenToWnd(p2,p3))\
  2992. end\
  2993. if event==\"mouse_up\" then\
  2994. if p1==2 then\
  2995. return self:onRightUp(self:screenToWnd(p2,p3))\
  2996. elseif p1==3 then\
  2997. return self:onMiddleUp(self:screenToWnd(p2,p3))\
  2998. end\
  2999. return self:onLeftUp(self:screenToWnd(p2,p3))\
  3000. end\
  3001. if event==\"char\" then\
  3002. return self:onChar(p1)\
  3003. end\
  3004. if event==\"key\" then\
  3005. return self:onKey(p1,p2,p3,p4)\
  3006. end\
  3007. if event==\"key_up\" then\
  3008. return self:onKeyUp(p1)\
  3009. end\
  3010. if event==\"monitor_touch\" then\
  3011. return self:onTouch(self:screenToWnd(p2,p3))\
  3012. end\
  3013. if event==\"monitor_resize\" then\
  3014. return self:onResize()\
  3015. end\
  3016. if event==\"alarm\" then\
  3017. return self:onAlarm(p1)\
  3018. end\
  3019. if event==\"paste\" then\
  3020. return self:onPaste(p1)\
  3021. end\
  3022. if event==\"frame_close\" then\
  3023. return self:onFrameClose()\
  3024. end\
  3025. return self:onEvent(event,p1,p2,p3,p4,p5,...)\
  3026. end\
  3027. function window:routeEvent(wnd,event,...)\
  3028. local success,result;\
  3029. if self==wnd then\
  3030. success,result=pcall(self.routeWndEvent,self,event,...)\
  3031. else\
  3032. success,result=pcall(self.routeChildEvent,self,wnd,event,...)\
  3033. end\
  3034. self:getWorkSpace():startIdleTimer()\
  3035. if success then\
  3036. return result\
  3037. end\
  3038. if self:getAppFrame()then\
  3039. local title=self:getAppFrame():getText()\
  3040. if title:len()>0 then\
  3041. result=title..\"\\n\"..asstring(result)\
  3042. end\
  3043. end\
  3044. syslog(result)\
  3045. self:getDesktop():msgBox(\"Error\",result,colors.red)\
  3046. return false\
  3047. end\
  3048. function window:sendEvent(event,...)\
  3049. return self:routeEvent(self,event,...)\
  3050. end\
  3051. function window:wantEvent(event)\
  3052. return self:getWorkSpace():wantEvent(self,event)\
  3053. end\
  3054. function window:unwantEvent(event)\
  3055. return self:getWorkSpace():unwantEvent(self,event)\
  3056. end\
  3057. function window:onFocus(blurred)\
  3058. self:hideCursor()\
  3059. return false\
  3060. end\
  3061. function window:onBlur(focused)\
  3062. self:hideCursor()\
  3063. return false\
  3064. end\
  3065. function window:onIdle(idleCount)\
  3066. return false\
  3067. end\
  3068. function window:onLeftClick(x,y)\
  3069. if self:getWantFocus()then\
  3070. self:setFocus()\
  3071. end\
  3072. local htPos=self:hitTest(x,y)\
  3073. if htPos>HT_CLIENT then\
  3074. if htPos==HT_LINEUP then\
  3075. return self:sendEvent(\"vbar_scroll\",-1,false)\
  3076. end\
  3077. if htPos==HT_LINEDOWN then\
  3078. return self:sendEvent(\"vbar_scroll\",1,false)\
  3079. end\
  3080. if htPos==HT_PAGEUP then\
  3081. return self:sendEvent(\"vbar_scroll\",-1,true)\
  3082. end\
  3083. if htPos==HT_PAGEDOWN then\
  3084. return self:sendEvent(\"vbar_scroll\",1,true)\
  3085. end\
  3086. if htPos==HT_LINELEFT then\
  3087. return self:sendEvent(\"hbar_scroll\",-1,false)\
  3088. end\
  3089. if htPos==HT_LINERIGHT then\
  3090. return self:sendEvent(\"hbar_scroll\",1,false)\
  3091. end\
  3092. if htPos==HT_PAGELEFT then\
  3093. return self:sendEvent(\"hbar_scroll\",-1,true)\
  3094. end\
  3095. if htPos==HT_PAGERIGHT then\
  3096. return self:sendEvent(\"hbar_scroll\",1,true)\
  3097. end\
  3098. end\
  3099. return false\
  3100. end\
  3101. function window:onRightClick(x,y)\
  3102. if self:getWantFocus()then\
  3103. self:setFocus()\
  3104. end\
  3105. return false\
  3106. end\
  3107. function window:onMiddleClick(x,y)\
  3108. if self:getWantFocus()then\
  3109. self:setFocus()\
  3110. end\
  3111. return false\
  3112. end\
  3113. function window:onLeftUp(x,y)\
  3114. return false\
  3115. end\
  3116. function window:onRightUp(x,y)\
  3117. return false\
  3118. end\
  3119. function window:onMiddleUp(x,y)\
  3120. return false\
  3121. end\
  3122. function window:onChar(char)\
  3123. return false\
  3124. end\
  3125. function window:onPaste(text)\
  3126. return false\
  3127. end\
  3128. function window:onKey(key,ctrl,alt,shift)\
  3129. return false\
  3130. end\
  3131. function window:onKeyUp(key)\
  3132. return false\
  3133. end\
  3134. function window:onScrollWheel(direction,x,y)\
  3135. local width,height=self:getClientSize()\
  3136. if height<self.height and y==height then\
  3137. local cols=3\
  3138. if width<6 then\
  3139. cols=1\
  3140. end\
  3141. self:scrollCols(cols*direction)\
  3142. else\
  3143. local lines=3\
  3144. if height<6 then\
  3145. lines=1\
  3146. end\
  3147. self:scrollLines(lines*direction)\
  3148. end\
  3149. return true\
  3150. end\
  3151. function window:onVScroll(direction,page)\
  3152. local lines=1\
  3153. local width,height=self:getClientSize()\
  3154. if page then\
  3155. lines=height-1\
  3156. if lines<1 then\
  3157. lines=1\
  3158. end\
  3159. end\
  3160. self:scrollLines(lines*direction)\
  3161. return true\
  3162. end\
  3163. function window:onHScroll(direction,page)\
  3164. local lines=1\
  3165. local width,height=self:getClientSize()\
  3166. if page then\
  3167. lines=width-1\
  3168. if lines<1 then\
  3169. lines=1\
  3170. end\
  3171. end\
  3172. self:scrollCols(lines*direction)\
  3173. return true\
  3174. end\
  3175. function window:onLeftDrag(x,y)\
  3176. return false\
  3177. end\
  3178. function window:onRightDrag(x,y)\
  3179. return false\
  3180. end\
  3181. function window:onMiddleDrag(x,y)\
  3182. return false\
  3183. end\
  3184. function window:onTouch(x,y)\
  3185. if self:getWantFocus()then\
  3186. self:setFocus()\
  3187. end\
  3188. local htPos=self:hitTest(x,y)\
  3189. if htPos>HT_CLIENT then\
  3190. if htPos==HT_LINEUP then\
  3191. return self:sendEvent(\"vbar_scroll\",-1,false)\
  3192. end\
  3193. if htPos==HT_LINEDOWN then\
  3194. return self:sendEvent(\"vbar_scroll\",1,false)\
  3195. end\
  3196. if htPos==HT_PAGEUP then\
  3197. return self:sendEvent(\"vbar_scroll\",-1,true)\
  3198. end\
  3199. if htPos==HT_PAGEDOWN then\
  3200. return self:sendEvent(\"vbar_scroll\",1,true)\
  3201. end\
  3202. if htPos==HT_LINELEFT then\
  3203. return self:sendEvent(\"hbar_scroll\",-1,false)\
  3204. end\
  3205. if htPos==HT_LINERIGHT then\
  3206. return self:sendEvent(\"hbar_scroll\",1,false)\
  3207. end\
  3208. if htPos==HT_PAGELEFT then\
  3209. return self:sendEvent(\"hbar_scroll\",-1,true)\
  3210. end\
  3211. if htPos==HT_PAGERIGHT then\
  3212. return self:sendEvent(\"hbar_scroll\",1,true)\
  3213. end\
  3214. end\
  3215. if self:getWantKeyInput()~=KEYINPUT_NONE then\
  3216. if self.gdi:isMonitor()then\
  3217. if self:getDesktop()then\
  3218. self:getDesktop():doKeyboard(self)\
  3219. end\
  3220. end\
  3221. end\
  3222. return false\
  3223. end\
  3224. function window:onResize()\
  3225. return false\
  3226. end\
  3227. function window:onAlarm(id)\
  3228. return false\
  3229. end\
  3230. function window:onTimer(id)\
  3231. return false\
  3232. end\
  3233. function window:onMove()\
  3234. return false\
  3235. end\
  3236. function window:onFrameClose()\
  3237. return false\
  3238. end\
  3239. function window:onReceive(msg)\
  3240. return false\
  3241. end\
  3242. function window:onSent(msg,success)\
  3243. return false\
  3244. end\
  3245. function window:onEvent(event,p1,p2,p3,p4,p5,...)\
  3246. return false\
  3247. end\
  3248. function window:onDestroyWnd()\
  3249. end\
  3250. function window:onScroll()\
  3251. end\
  3252. function window:onChildFocus(wnd,blurred)\
  3253. return false\
  3254. end\
  3255. function window:onChildBlur(wnd,focused)\
  3256. return false\
  3257. end\
  3258. function window:onChildLeftClick(wnd,x,y)\
  3259. return false\
  3260. end\
  3261. function window:onChildRightClick(wnd,x,y)\
  3262. return false\
  3263. end\
  3264. function window:onChildMiddleClick(wnd,x,y)\
  3265. return false\
  3266. end\
  3267. function window:onChildLeftUp(wnd,x,y)\
  3268. return false\
  3269. end\
  3270. function window:onChildRightUp(wnd,x,y)\
  3271. return false\
  3272. end\
  3273. function window:onChildMiddleUp(wnd,x,y)\
  3274. return false\
  3275. end\
  3276. function window:onChildChar(wnd,char)\
  3277. return false\
  3278. end\
  3279. function window:onChildPaste(wnd,text)\
  3280. return false\
  3281. end\
  3282. function window:onChildKey(wnd,key,ctrl,alt,shift)\
  3283. return false\
  3284. end\
  3285. function window:onChildKeyUp(wnd,key)\
  3286. return false\
  3287. end\
  3288. function window:onChildLeftDrag(wnd,x,y)\
  3289. return false\
  3290. end\
  3291. function window:onChildRightDrag(wnd,x,y)\
  3292. return false\
  3293. end\
  3294. function window:onChildMiddleDrag(wnd,x,y)\
  3295. return false\
  3296. end\
  3297. function window:onChildTouch(wnd,x,y)\
  3298. return false\
  3299. end\
  3300. function window:onChildEvent(wnd,event,p1,p2,p3,p4,p5,...)\
  3301. return false\
  3302. end\
  3303. buttonWindow=window:base()\
  3304. function buttonWindow:constructor(parent,id,x,y,label)\
  3305. if not window.constructor(self,parent,id,x,y,\
  3306. asstring(label):len(),1)then\
  3307. return nil\
  3308. end\
  3309. self.btn__colors={\
  3310. text=self:getColors().buttonText,\
  3311. back=self:getColors().buttonBack,\
  3312. focus=self:getColors().buttonFocus\
  3313. }\
  3314. self:setText(label)\
  3315. self:setColor(self.btn__colors.text)\
  3316. self:setBgColor(self.btn__colors.back)\
  3317. return self\
  3318. end\
  3319. function buttonWindow:setColors(text,background,focus)\
  3320. self.btn__colors.text=text\
  3321. self.btn__colors.back=background\
  3322. self.btn__colors.focus=focus\
  3323. self:setColor(text)\
  3324. self:setBgColor(iif(self:getFocus()==self,focus,background))\
  3325. end\
  3326. function buttonWindow:draw(gdi,bounds)\
  3327. gdi:setBackgroundColor(self:getBgColor())\
  3328. gdi:setTextColor(self:getColor())\
  3329. gdi:write(self:getText(),0,0)\
  3330. end\
  3331. function buttonWindow:onFocus(blurred)\
  3332. self:hideCursor()\
  3333. self:setBgColor(self.btn__colors.focus)\
  3334. return false\
  3335. end\
  3336. function buttonWindow:onBlur(focused)\
  3337. self:setBgColor(self.btn__colors.back)\
  3338. return false\
  3339. end\
  3340. function buttonWindow:onKey(key,ctrl,alt,shift)\
  3341. if not ctrl and not alt and not shift then\
  3342. if key==keys.enter then\
  3343. self:onLeftClick(0,0)\
  3344. end\
  3345. end\
  3346. return true\
  3347. end\
  3348. function buttonWindow:onLeftClick(x,y)\
  3349. if window.onLeftClick(self,x,y)then\
  3350. return true\
  3351. end\
  3352. if self:getParent()then\
  3353. self:getParent():sendEvent(\"btn_click\",self)\
  3354. end\
  3355. return false\
  3356. end\
  3357. function buttonWindow:onTouch(x,y)\
  3358. if window.onTouch(self,x,y)then\
  3359. return true\
  3360. end\
  3361. if self:getParent()then\
  3362. self:getParent():sendEvent(\"btn_click\",self)\
  3363. end\
  3364. return false\
  3365. end\
  3366. inputWindow=window:base()\
  3367. function inputWindow:constructor(parent,id,x,y,width,text,banner)\
  3368. if not window.constructor(self,parent,id,x,y,width,1)then\
  3369. return nil\
  3370. end\
  3371. self.input__banner=\"\"\
  3372. self.input__oldText=\"\"\
  3373. self.input__maskChar=\"\"\
  3374. self.input__error=false\
  3375. self.input__hOrg=0\
  3376. self.input__end=0\
  3377. self.input__start=0\
  3378. self.input__maxLen=0\
  3379. self.input__colors={\
  3380. text=self:getColors().inputText,\
  3381. back=self:getColors().inputBack,\
  3382. focus=self:getColors().inputFocus,\
  3383. error=self:getColors().inputError,\
  3384. banner=self:getColors().inputBanner\
  3385. }\
  3386. self:setColor(self.input__colors.text)\
  3387. self:setBgColor(self.input__colors.back)\
  3388. self:setWantKeyInput(KEYINPUT_LINE)\
  3389. self:setBanner(banner)\
  3390. self:setText(text)\
  3391. return self\
  3392. end\
  3393. function inputWindow:setColors(text,background,focus,banner,errorColor)\
  3394. self.input__colors.text=text\
  3395. self.input__colors.back=background\
  3396. self.input__colors.focus=focus\
  3397. self.input__colors.error=errorColor\
  3398. self.input__colors.banner=banner\
  3399. self:setColor(text)\
  3400. self:setBgColor(iif(self:getFocus()==self,focus,background))\
  3401. end\
  3402. function inputWindow:setBanner(banner)\
  3403. self.input__banner=asstring(banner)\
  3404. self:invalidate()\
  3405. end\
  3406. function inputWindow:setMaskChar(char)\
  3407. self.input__maskChar=asstring(char)\
  3408. self:invalidate()\
  3409. end\
  3410. function inputWindow:getMaskChar()\
  3411. return self.input__maskChar\
  3412. end\
  3413. function inputWindow:getBanner()\
  3414. return self.input__banner\
  3415. end\
  3416. function inputWindow:getError()\
  3417. return self.input__error\
  3418. end\
  3419. function inputWindow:setError(bError)\
  3420. bError=(bError~=false)\
  3421. if bError~=self.input__error then\
  3422. self.input__error=bError\
  3423. self:setBgColor(iif(self.input__error,\
  3424. self.input__colors.error,\
  3425. iif(self:getFocus()==self,\
  3426. self.input__colors.focus,\
  3427. self.input__colors.back)))\
  3428. end\
  3429. end\
  3430. function inputWindow:setMaxLength(maxLen)\
  3431. self.input__maxLen=asnumber(maxLen)\
  3432. if self.input__maxLen<1 then\
  3433. self.input__maxLen=0\
  3434. end\
  3435. end\
  3436. function inputWindow:getMaxLength()\
  3437. return self.input__maxLen\
  3438. end\
  3439. function inputWindow:setSel(selStart,selEnd,autoScroll)\
  3440. local strLen=self:getText():len()\
  3441. selStart=asnumber(selStart)\
  3442. if selStart<0 then\
  3443. selStart=0\
  3444. elseif selStart>strLen then\
  3445. selStart=strLen\
  3446. end\
  3447. if selEnd==nil then\
  3448. selEnd=selStart\
  3449. elseif selEnd==-1 then\
  3450. selEnd=strLen\
  3451. elseif selEnd<0 then\
  3452. selEnd=0\
  3453. elseif selEnd>strLen then\
  3454. selEnd=strLen\
  3455. end\
  3456. self.input__end=selEnd\
  3457. self.input__start=selStart\
  3458. if autoScroll~=false then\
  3459. if(self.input__end-self.input__hOrg)<=0 then\
  3460. self.input__hOrg=self.input__end-math.floor(self.width/2)\
  3461. if self.input__hOrg<0 then\
  3462. self.input__hOrg=0\
  3463. end\
  3464. end\
  3465. if(self.input__end-self.input__hOrg)>=self.width then\
  3466. self.input__hOrg=self.input__end-self.width+1\
  3467. end\
  3468. end\
  3469. self:invalidate()\
  3470. if self:getFocus()==self then\
  3471. self:setCursorPos(self.input__end-self.input__hOrg,0)\
  3472. end\
  3473. end\
  3474. function inputWindow:getSel(normalise)\
  3475. if normalise then\
  3476. if self.input__end<self.input__start then\
  3477. return self.input__end,self.input__start\
  3478. end\
  3479. end\
  3480. return self.input__start,self.input__end\
  3481. end\
  3482. function inputWindow:replaceSel(replaceText,autoScroll)\
  3483. local ss,se=self:getSel(true)\
  3484. local str=self:getText():sub(1,ss)..asstring(replaceText)..\
  3485. self:getText():sub(se+1)\
  3486. if self.input__maxLen>0 then\
  3487. if str:len()>self.input__maxLen then\
  3488. str=str:sub(1,self.input__maxLen)\
  3489. end\
  3490. end\
  3491. self:setText(str)\
  3492. se=ss+asstring(replaceText):len()\
  3493. self:setSel(se,se,autoScroll)\
  3494. end\
  3495. function inputWindow:getSelection()\
  3496. local ss,se=self:getSel(true)\
  3497. return self:getText():sub((ss+1),se)\
  3498. end\
  3499. function inputWindow:cut()\
  3500. local strSel=self:getSelection()\
  3501. if strSel:len()>0 then\
  3502. self:setClipboard(strSel,CB_TEXT)\
  3503. self:replaceSel(\"\")\
  3504. end\
  3505. end\
  3506. function inputWindow:copy()\
  3507. local strSel=self:getSelection()\
  3508. if strSel:len()>0 then\
  3509. self:setClipboard(strSel,CB_TEXT)\
  3510. end\
  3511. end\
  3512. function inputWindow:paste()\
  3513. local cbType,cbData=self:getClipboard()\
  3514. if cbType==CB_TEXT then\
  3515. self:replaceSel(cbData)\
  3516. end\
  3517. end\
  3518. function inputWindow:draw(gdi,bounds)\
  3519. gdi:setBackgroundColor(self:getBgColor())\
  3520. if self:getText():len()==0 then\
  3521. if self:getBanner():len()>0 then\
  3522. gdi:setTextColor(self.input__colors.banner)\
  3523. gdi:write(self:getBanner(),0,0)\
  3524. end\
  3525. else\
  3526. local displayText;\
  3527. local ss,se=self:getSel(true)\
  3528. if self.input__maskChar:len()>0 then\
  3529. displayText=string.rep(self.input__maskChar,self:getText():len())\
  3530. else\
  3531. displayText=self:getText()\
  3532. end\
  3533. if ss==se then\
  3534. gdi:setTextColor(self:getColor())\
  3535. gdi:write(displayText,(self.input__hOrg*-1),0)\
  3536. else\
  3537. local left=(self.input__hOrg*-1)\
  3538. local strPre,strSel,strPost=\
  3539. displayText:sub(1,ss),\
  3540. displayText:sub(ss+1,se),\
  3541. displayText:sub(se+1)\
  3542. gdi:setTextColor(self:getColor())\
  3543. gdi:write(strPre,left,0)\
  3544. left=left+strPre:len()\
  3545. gdi:setBackgroundColor(self:getColors().selectedBack)\
  3546. gdi:setTextColor(self:getColors().selectedText)\
  3547. gdi:write(strSel,left,0)\
  3548. left=left+strSel:len()\
  3549. gdi:setBackgroundColor(self:getBgColor())\
  3550. gdi:setTextColor(self:getColor())\
  3551. gdi:write(strPost,left,0)\
  3552. end\
  3553. end\
  3554. end\
  3555. function inputWindow:setText(text)\
  3556. window.setText(self,text)\
  3557. local ss,se=self:getSel(false)\
  3558. local strLen=self:getText():len()\
  3559. if ss>strLen then\
  3560. ss=strLen\
  3561. end\
  3562. if se>strLen then\
  3563. se=strLen\
  3564. end\
  3565. self:setSel(ss,se)\
  3566. end\
  3567. function inputWindow:onFocus(blurred)\
  3568. self:setBgColor(iif(self.input__error,\
  3569. self.input__colors.error,\
  3570. self.input__colors.focus))\
  3571. self:setCursorPos(self.input__end-self.input__hOrg,0)\
  3572. self.input__oldText=self:getText()\
  3573. return false\
  3574. end\
  3575. function inputWindow:onBlur(focused)\
  3576. self:hideCursor()\
  3577. self:setBgColor(iif(self.input__error,\
  3578. self.input__colors.error,\
  3579. self.input__colors.back))\
  3580. if self.input__oldText~=self:getText()then\
  3581. if self:getParent()then\
  3582. self:getParent():sendEvent(\"input_change\",self)\
  3583. end\
  3584. end\
  3585. return false\
  3586. end\
  3587. function inputWindow:onKey(key,ctrl,alt,shift)\
  3588. if not ctrl and not alt and not shift then\
  3589. local ss,se=self:getSel(false)\
  3590. if key==keys.backspace then\
  3591. if ss==se then\
  3592. self:setSel(ss-1,ss,false)\
  3593. end\
  3594. self:replaceSel(\"\")\
  3595. return true\
  3596. elseif key==keys.delete then\
  3597. if ss==se then\
  3598. self:setSel(ss,ss+1,false)\
  3599. end\
  3600. self:replaceSel(\"\")\
  3601. return true\
  3602. elseif key==keys.left then\
  3603. if se>=1 then\
  3604. self:setSel(se-1,se-1)\
  3605. end\
  3606. return true\
  3607. elseif key==keys.right then\
  3608. self:setSel(se+1,se+1)\
  3609. return true\
  3610. elseif key==keys.home then\
  3611. self:setSel(0,0)\
  3612. return true\
  3613. elseif key==207 then \
  3614. self:setSel(self:getText():len(),-1)\
  3615. return true\
  3616. end\
  3617. elseif not ctrl and not alt and shift then\
  3618. local ss,se=self:getSel(false)\
  3619. if key==keys.left then\
  3620. if se>=1 then\
  3621. self:setSel(ss,se-1)\
  3622. end\
  3623. return true\
  3624. elseif key==keys.right then\
  3625. self:setSel(ss,se+1)\
  3626. return true\
  3627. elseif key==keys.home then\
  3628. self:setSel(ss,0)\
  3629. return true\
  3630. elseif key==207 then \
  3631. self:setSel(ss,-1)\
  3632. return true\
  3633. end\
  3634. elseif ctrl and not alt and not shift then\
  3635. if key==keys.x then\
  3636. self:cut()\
  3637. return true\
  3638. elseif key==keys.c then\
  3639. self:copy()\
  3640. return true\
  3641. elseif key==keys.b then\
  3642. self:paste()\
  3643. return true\
  3644. elseif key==keys.a then\
  3645. self:setSel(0,-1)\
  3646. return true\
  3647. end\
  3648. end\
  3649. return false\
  3650. end\
  3651. function inputWindow:onChar(char)\
  3652. self:replaceSel(char)\
  3653. return true\
  3654. end\
  3655. function inputWindow:onLeftClick(x,y)\
  3656. if window.onLeftClick(self,x,y)then\
  3657. return true\
  3658. end\
  3659. self:setSel(x+self.input__hOrg,x+self.input__hOrg)\
  3660. return true\
  3661. end\
  3662. function inputWindow:onLeftDrag(x,y)\
  3663. local ss,se=self:getSel(false)\
  3664. self:setSel(ss,x+self.input__hOrg)\
  3665. return true\
  3666. end\
  3667. function inputWindow:onTouch(x,y)\
  3668. if window.onTouch(self,x,y)then\
  3669. return true\
  3670. end\
  3671. self:setSel(x+self.input__hOrg,x+self.input__hOrg)\
  3672. return true\
  3673. end\
  3674. function inputWindow:onMove()\
  3675. if self:getFocus()==self then\
  3676. self:showCursor()\
  3677. end\
  3678. return false\
  3679. end\
  3680. function inputWindow:onPaste(text)\
  3681. if asstring(text):len()>0 then\
  3682. self:replaceSel(asstring(text))\
  3683. end\
  3684. return true\
  3685. end\
  3686. labelWindow=window:base()\
  3687. function labelWindow:constructor(parent,id,x,y,label)\
  3688. if not window.constructor(self,parent,id,x,y,\
  3689. asstring(label):len(),1)then\
  3690. return nil\
  3691. end\
  3692. self:setText(label)\
  3693. self:setWantFocus(false)\
  3694. self:setColor(self:getColors().frameText)\
  3695. self:setBgColor(self:getColors().frameBack)\
  3696. return self\
  3697. end\
  3698. function labelWindow:draw(gdi,bounds)\
  3699. gdi:setBackgroundColor(self:getBgColor())\
  3700. gdi:setTextColor(self:getColor())\
  3701. gdi:write(self:getText(),0,0)\
  3702. end\
  3703. listWindow=window:base()\
  3704. function listWindow:constructor(parent,id,x,y,width,height)\
  3705. if not window.constructor(self,parent,id,x,y,width,height)then\
  3706. return nil\
  3707. end\
  3708. self.list__selIndex=0\
  3709. self.list__clickTime=-1\
  3710. self.list__clickX=-1\
  3711. self.list__clickY=-1\
  3712. self.list__colors={\
  3713. text=self:getColors().wndText,\
  3714. back=self:getColors().wndBack,\
  3715. focus=self:getColors().wndFocus,\
  3716. selectedText=self:getColors().selectedText,\
  3717. selectedBack=self:getColors().selectedBack\
  3718. }\
  3719. self.list__items={}\
  3720. self:setColor(self.list__colors.text)\
  3721. self:setBgColor(self.list__colors.back)\
  3722. return self\
  3723. end\
  3724. function listWindow:setColors(text,background,focus,selectedText,selectedBack)\
  3725. self.list__colors.text=text\
  3726. self.list__colors.back=background\
  3727. self.list__colors.focus=focus\
  3728. self.list__colors.selectedText=selectedText\
  3729. self.list__colors.selectedBack=selectedBack\
  3730. self:setColor(text)\
  3731. self:setBgColor(iif(self:getFocus()==self,focus,background))\
  3732. end\
  3733. function listWindow:count()\
  3734. return #self.list__items\
  3735. end\
  3736. function listWindow:addString(str,data,index)\
  3737. local i=index\
  3738. if i==nil then\
  3739. i=self:count()+1\
  3740. elseif i<1 or i>(self:count()+1)then\
  3741. i=self:count()+1\
  3742. end\
  3743. table.insert(self.list__items,i,{asstring(str),data})\
  3744. self:setScrollSize(self.wnd__scrollWidth,self:count())\
  3745. end\
  3746. function listWindow:removeString(index)\
  3747. if index==nil then\
  3748. return false\
  3749. elseif index<1 or index>self:count()then\
  3750. return false\
  3751. end\
  3752. table.remove(self.list__items,index)\
  3753. self:setScrollSize(self.wnd__scrollWidth,self:count())\
  3754. return true\
  3755. end\
  3756. function listWindow:resetContent()\
  3757. self.list__items={}\
  3758. self.list__selIndex=0\
  3759. self:setScrollSize(self.wnd__scrollWidth,0)\
  3760. end\
  3761. function listWindow:getCurSel()\
  3762. if self.list__selIndex>=0 and\
  3763. self.list__selIndex<=self:count()then\
  3764. return self.list__selIndex\
  3765. end\
  3766. return 0\
  3767. end\
  3768. function listWindow:setCurSel(index,makeVisible)\
  3769. local i=index\
  3770. if i==nil then\
  3771. i=0\
  3772. end\
  3773. if i>self:count()then\
  3774. i=self:count()\
  3775. end\
  3776. if i>=0 and i<=self:count()and\
  3777. i~=self.list__selIndex then\
  3778. self.list__selIndex=i\
  3779. if makeVisible~=false then\
  3780. self:ensureVisible()\
  3781. end\
  3782. self:invalidate()\
  3783. if self:getParent()then\
  3784. self:getParent():sendEvent(\"selection_change\",self)\
  3785. end\
  3786. return true\
  3787. end\
  3788. return false\
  3789. end\
  3790. function listWindow:getString(index)\
  3791. local i=index\
  3792. if i==nil then\
  3793. i=self:getCurSel()\
  3794. end\
  3795. if i>0 and i<=self:count()then\
  3796. return self.list__items[i][1]\
  3797. end\
  3798. return nil\
  3799. end\
  3800. function listWindow:getData(index)\
  3801. local i=index\
  3802. if i==nil then\
  3803. i=self:getCurSel()\
  3804. end\
  3805. if i>0 and i<=self:count()then\
  3806. return self.list__items[i][2]\
  3807. end\
  3808. return nil\
  3809. end\
  3810. local function list_sorterAscending(string1,string2)\
  3811. return(string1[1]<string2[1])\
  3812. end\
  3813. local function list_sorterDecending(string1,string2)\
  3814. return(string1[1]>string2[1])\
  3815. end\
  3816. function listWindow:sort(decending)\
  3817. if decending then\
  3818. table.sort(self.list__items,list_sorterDecending)\
  3819. else\
  3820. table.sort(self.list__items,list_sorterAscending)\
  3821. end\
  3822. self:invalidate()\
  3823. end\
  3824. function listWindow:ensureVisible(index)\
  3825. local top=index\
  3826. if top==nil then\
  3827. top=self:getCurSel()\
  3828. end\
  3829. if top>=1 and top<=self:count()then\
  3830. local width,height=self:getClientSize()\
  3831. local orgX,orgY=self:getScrollOrg()\
  3832. if top<=orgY then\
  3833. self:setScrollOrg(orgX,top-1)\
  3834. elseif top>(orgY+height)then\
  3835. self:setScrollOrg(orgX,top-height)\
  3836. end\
  3837. end\
  3838. end\
  3839. function listWindow:find(str,from,exact)\
  3840. str=asstring(str)\
  3841. from=asnumber(from)+1\
  3842. for i=from,self:count(),1 do\
  3843. local item=self:getString(i)\
  3844. if not exact then\
  3845. item=item:sub(1,str:len())\
  3846. end\
  3847. if str==item then\
  3848. return i\
  3849. end\
  3850. end\
  3851. return 0\
  3852. end\
  3853. function listWindow:setString(str,index)\
  3854. local i=index\
  3855. if i==nil then\
  3856. i=self:getCurSel()\
  3857. end\
  3858. if i>0 and i<=self:count()then\
  3859. self.list__items[i][1]=asstring(str)\
  3860. self:invalidate()\
  3861. return true\
  3862. end\
  3863. return false\
  3864. end\
  3865. function listWindow:setData(data,index)\
  3866. local i=index\
  3867. if i==nil then\
  3868. i=self:getCurSel()\
  3869. end\
  3870. if i>0 and i<=self:count()then\
  3871. self.list__items[i][2]=data\
  3872. return true\
  3873. end\
  3874. return false\
  3875. end\
  3876. function listWindow:draw(gdi,bounds)\
  3877. local first,last;\
  3878. first=self.wnd__scrollY+1\
  3879. last=self:count()\
  3880. if(last-first+1)>self.height then\
  3881. last=first+self.height\
  3882. end\
  3883. for i=first,last,1 do\
  3884. if i==self:getCurSel()then\
  3885. gdi:setBackgroundColor(self.list__colors.selectedBack)\
  3886. gdi:setTextColor(self.list__colors.selectedText)\
  3887. gdi:clear(0,i-1,self.width,1)\
  3888. else\
  3889. gdi:setBackgroundColor(self:getBgColor())\
  3890. gdi:setTextColor(self:getColor())\
  3891. end\
  3892. gdi:write(self:getString(i),0,i-1)\
  3893. end\
  3894. end\
  3895. function listWindow:onFocus(blurred)\
  3896. self:hideCursor()\
  3897. self:setBgColor(self.list__colors.focus)\
  3898. return false\
  3899. end\
  3900. function listWindow:onBlur(focused)\
  3901. self:setBgColor(self.list__colors.back)\
  3902. return false\
  3903. end\
  3904. function listWindow:onKey(key,ctrl,alt,shift)\
  3905. if not ctrl and not alt and not shift then\
  3906. if key==keys.enter then\
  3907. if self:getParent()then\
  3908. if(os.clock()-self.list__clickTime)<=self:getTheme().doubleClick and\
  3909. self.list__clickX==-2 and self.list__clickY==-2 then\
  3910. self.list__clickX=-1\
  3911. self.list__clickY=-1\
  3912. self.list__clickTime=-1\
  3913. self:getParent():sendEvent(\"list_double_click\",self)\
  3914. else\
  3915. self.list__clickX=-2\
  3916. self.list__clickY=-2\
  3917. self.list__clickTime=os.clock()\
  3918. self:getParent():sendEvent(\"list_click\",self)\
  3919. end\
  3920. end\
  3921. return true\
  3922. elseif key==keys.up then\
  3923. if self:getCurSel()>1 then\
  3924. self:setCurSel(self:getCurSel()-1)\
  3925. end\
  3926. return true\
  3927. elseif key==keys.down then\
  3928. self:setCurSel(self:getCurSel()+1)\
  3929. return true\
  3930. elseif key==keys.pageUp then\
  3931. local width,height=self:getClientSize()\
  3932. self:setCurSel(iif((self:getCurSel()-(height-1))<1,\
  3933. 1,(self:getCurSel()-(height-1))))\
  3934. return true\
  3935. elseif key==keys.pageDown then\
  3936. local width,height=self:getClientSize()\
  3937. self:setCurSel(self:getCurSel()+(height-1))\
  3938. return true\
  3939. elseif key==keys.home then\
  3940. self:setCurSel(1)\
  3941. return true\
  3942. elseif key==207 then \
  3943. self:setCurSel(self:count())\
  3944. return true\
  3945. end\
  3946. elseif ctrl and not alt and not shift then\
  3947. if key==keys.up then\
  3948. self:sendEvent(\"vbar_scroll\",-1,false)\
  3949. return true\
  3950. elseif key==keys.down then\
  3951. self:sendEvent(\"vbar_scroll\",1,false)\
  3952. return true\
  3953. elseif key==keys.left then\
  3954. self:sendEvent(\"hbar_scroll\",-1,false)\
  3955. return true\
  3956. elseif key==keys.right then\
  3957. self:sendEvent(\"hbar_scroll\",1,false)\
  3958. return true\
  3959. elseif key==keys.pageUp then\
  3960. self:sendEvent(\"vbar_scroll\",-1,true)\
  3961. return true\
  3962. elseif key==keys.pageDown then\
  3963. self:sendEvent(\"vbar_scroll\",1,true)\
  3964. return true\
  3965. elseif key==keys.home then\
  3966. self:setScrollOrg(0,0)\
  3967. return true\
  3968. elseif key==207 then \
  3969. self:setScrollOrg(0,self:count())\
  3970. return true\
  3971. end\
  3972. end\
  3973. return false\
  3974. end\
  3975. function listWindow:onLeftClick(x,y)\
  3976. if window.onLeftClick(self,x,y)then\
  3977. return true\
  3978. end\
  3979. local sx,sy=self:wndToScroll(x,y)\
  3980. local item=sy+1\
  3981. if item>=1 and item<=self:count()then\
  3982. self:setCurSel(item)\
  3983. if self:getParent()then\
  3984. if(os.clock()-self.list__clickTime)<=self:getTheme().doubleClick and\
  3985. self.list__clickX==sx and self.list__clickY==sy then\
  3986. self.list__clickX=-1\
  3987. self.list__clickY=-1\
  3988. self.list__clickTime=-1\
  3989. self:getParent():sendEvent(\"list_double_click\",self)\
  3990. else\
  3991. self.list__clickX=sx\
  3992. self.list__clickY=sy\
  3993. self.list__clickTime=os.clock()\
  3994. self:getParent():sendEvent(\"list_click\",self)\
  3995. end\
  3996. end\
  3997. end\
  3998. return true\
  3999. end\
  4000. function listWindow:onTouch(x,y)\
  4001. if window.onTouch(self,x,y)then\
  4002. return true\
  4003. end\
  4004. local sx,sy=self:wndToScroll(x,y)\
  4005. local item=sy+1\
  4006. if item>=1 and item<=self:count()then\
  4007. self:setCurSel(item)\
  4008. if self:getParent()then\
  4009. if(os.clock()-self.list__clickTime)<=self:getTheme().doubleClick and\
  4010. self.list__clickX==sx and self.list__clickY==sy then\
  4011. self.list__clickX=-1\
  4012. self.list__clickY=-1\
  4013. self.list__clickTime=-1\
  4014. self:getParent():sendEvent(\"list_double_click\",self)\
  4015. else\
  4016. self.list__clickX=sx\
  4017. self.list__clickY=sy\
  4018. self.list__clickTime=os.clock()\
  4019. self:getParent():sendEvent(\"list_click\",self)\
  4020. end\
  4021. end\
  4022. end\
  4023. return true\
  4024. end\
  4025. checkWindow=window:base()\
  4026. function checkWindow:constructor(parent,id,x,y,label,checked)\
  4027. if not window.constructor(self,parent,id,x,y,\
  4028. asstring(label):len()+2,1)then\
  4029. return nil\
  4030. end\
  4031. self.check__checked=(checked==true)\
  4032. self.check__colors={\
  4033. text=self:getColors().frameText,\
  4034. back=self:getColors().frameBack,\
  4035. focus=self:getColors().frameBack,\
  4036. checkText=self:getColors().checkText,\
  4037. checkBack=self:getColors().checkBack,\
  4038. checkFocus=self:getColors().checkFocus\
  4039. }\
  4040. self:setText(label)\
  4041. self:setColor(self.check__colors.text)\
  4042. self:setBgColor(self.check__colors.back)\
  4043. return self\
  4044. end\
  4045. function checkWindow:setColors(text,background,focus,checkText,checkBack,checkFocus)\
  4046. self.check__colors.text=text\
  4047. self.check__colors.back=background\
  4048. self.check__colors.focus=focus\
  4049. self.check__colors.checkText=checkText\
  4050. self.check__colors.checkBack=checkBack\
  4051. self.check__colors.checkFocus=checkFocus\
  4052. self:setColor(text)\
  4053. self:setBgColor(iif(self:getFocus()==self,focus,background))\
  4054. end\
  4055. function checkWindow:getChecked()\
  4056. return self.check__checked\
  4057. end\
  4058. function checkWindow:setChecked(check)\
  4059. check=(check~=false)\
  4060. if self.check__checked~=check then\
  4061. self.check__checked=check\
  4062. if self:getParent()then\
  4063. self:getParent():sendEvent(\"check_change\",self)\
  4064. end\
  4065. self:invalidate()\
  4066. end\
  4067. end\
  4068. function checkWindow:draw(gdi,bounds)\
  4069. if self==self:getFocus()then\
  4070. gdi:setBackgroundColor(self.check__colors.checkFocus)\
  4071. else\
  4072. gdi:setBackgroundColor(self.check__colors.checkBack)\
  4073. end\
  4074. gdi:setTextColor(self.check__colors.checkText)\
  4075. if self:getChecked()then\
  4076. gdi:write(\"x\",0,0)\
  4077. else\
  4078. gdi:write(\" \",0,0)\
  4079. end\
  4080. gdi:setBackgroundColor(self:getBgColor())\
  4081. gdi:setTextColor(self:getColor())\
  4082. gdi:write(\" \",1,0)\
  4083. gdi:write(self:getText(),2,0)\
  4084. end\
  4085. function checkWindow:onFocus(blurred)\
  4086. self:hideCursor()\
  4087. self:setBgColor(self.check__colors.focus)\
  4088. return false\
  4089. end\
  4090. function checkWindow:onBlur(focused)\
  4091. self:setBgColor(self.check__colors.back)\
  4092. return false\
  4093. end\
  4094. function checkWindow:onKey(key,ctrl,alt,shift)\
  4095. if not ctrl and not alt and not shift then\
  4096. if key==keys.enter then\
  4097. self:onLeftClick(0,0)\
  4098. end\
  4099. return true\
  4100. end\
  4101. return false\
  4102. end\
  4103. function checkWindow:onLeftClick(x,y)\
  4104. if window.onLeftClick(self,x,y)then\
  4105. return true\
  4106. end\
  4107. self:setChecked(not self:getChecked())\
  4108. return true\
  4109. end\
  4110. function checkWindow:onTouch(x,y)\
  4111. if window.onTouch(self,x,y)then\
  4112. return true\
  4113. end\
  4114. self:setChecked(not self:getChecked())\
  4115. return true\
  4116. end\
  4117. textWindow=window:base()\
  4118. function textWindow:constructor(parent,id,x,y,width,height,label)\
  4119. if not window.constructor(self,parent,id,x,y,width,height)then\
  4120. return nil\
  4121. end\
  4122. self.txtWnd__lines={}\
  4123. self:setWantFocus(false)\
  4124. self:setColor(self:getColors().frameText)\
  4125. self:setBgColor(self:getColors().frameBack)\
  4126. self:setText(label)\
  4127. return self\
  4128. end\
  4129. function textWindow:calcSize()\
  4130. self.txtWnd__lines=string.wrap(self:getText(),self.width)\
  4131. if #self.txtWnd__lines>self.height then\
  4132. self.txtWnd__lines=string.wrap(self:getText(),self.width-1)\
  4133. self:setScrollSize(0,#self.txtWnd__lines)\
  4134. else\
  4135. self:setScrollSize(0,0)\
  4136. end\
  4137. end\
  4138. function textWindow:draw(gdi,bounds)\
  4139. local first,last;\
  4140. first=self.wnd__scrollY+1\
  4141. last=#self.txtWnd__lines\
  4142. if(last-first+1)>self.height then\
  4143. last=first+self.height\
  4144. end\
  4145. gdi:setBackgroundColor(self:getBgColor())\
  4146. gdi:setTextColor(self:getColor())\
  4147. for i=first,last,1 do\
  4148. gdi:write(self.txtWnd__lines[i],0,i-1)\
  4149. end\
  4150. end\
  4151. function textWindow:onMove()\
  4152. self:calcSize()\
  4153. return false\
  4154. end\
  4155. function textWindow:setText(text)\
  4156. window.setText(self,text)\
  4157. self:calcSize()\
  4158. end\
  4159. local editUndo=__classBase:base()\
  4160. EU_REPLACE=0\
  4161. EU_TYPE=1\
  4162. EU_DELETE=2\
  4163. EU_BACKSPACE=3\
  4164. function editUndo:constructor()\
  4165. self.eu__cache={}\
  4166. self.eu__index=0\
  4167. return self\
  4168. end\
  4169. function editUndo:reset()\
  4170. self.eu__cache={}\
  4171. self.eu__index=0\
  4172. end\
  4173. function editUndo:endAction()\
  4174. if #self.eu__cache>0 then\
  4175. self.eu__cache[#self.eu__cache].action=EU_REPLACE\
  4176. end\
  4177. end\
  4178. function editUndo:record(pos,inserted,removed,action)\
  4179. if action~=EU_REPLACE and self.eu__index>0 and\
  4180. self.eu__index==#self.eu__cache and\
  4181. self.eu__cache[self.eu__index].action==action then\
  4182. if action==EU_TYPE then\
  4183. local cache=self.eu__cache[self.eu__index].inserted\
  4184. cache[#cache]=cache[#cache]..inserted[1]\
  4185. for i=2,#inserted,1 do\
  4186. cache[#cache+1]=inserted[i]\
  4187. end\
  4188. return\
  4189. elseif action==EU_DELETE then\
  4190. local cache=self.eu__cache[self.eu__index].removed\
  4191. cache[#cache]=cache[#cache]..removed[1]\
  4192. for i=2,#removed,1 do\
  4193. cache[#cache+1]=removed[i]\
  4194. end\
  4195. return\
  4196. elseif action==EU_BACKSPACE then\
  4197. local cache=self.eu__cache[self.eu__index].removed\
  4198. cache[1]=removed[#removed]..cache[1]\
  4199. for i=1,#removed-1,1 do\
  4200. table.insert(cache,1,removed[i])\
  4201. end\
  4202. self.eu__cache[self.eu__index].pos=pos\
  4203. return\
  4204. end\
  4205. end\
  4206. while #self.eu__cache>self.eu__index do\
  4207. table.remove(self.eu__cache,#self.eu__cache)\
  4208. end\
  4209. self:endAction()\
  4210. self.eu__index=#self.eu__cache+1\
  4211. self.eu__cache[self.eu__index]=\
  4212. {\
  4213. pos=pos,\
  4214. inserted=inserted,\
  4215. removed=removed,\
  4216. action=action\
  4217. }\
  4218. end\
  4219. function editUndo:canUndo()\
  4220. return self.eu__index>0\
  4221. end\
  4222. function editUndo:canRedo()\
  4223. return self.eu__index<#self.eu__cache\
  4224. end\
  4225. function editUndo:undo()\
  4226. local data;\
  4227. if self:canUndo()then\
  4228. self:endAction()\
  4229. data=self.eu__cache[self.eu__index]\
  4230. self.eu__index=self.eu__index-1\
  4231. end\
  4232. return data\
  4233. end\
  4234. function editUndo:redo()\
  4235. local data;\
  4236. if self:canRedo()then\
  4237. self:endAction()\
  4238. self.eu__index=self.eu__index+1\
  4239. data=self.eu__cache[self.eu__index]\
  4240. end\
  4241. return data\
  4242. end\
  4243. local function edit_textToTable(text)\
  4244. local tabText={}\
  4245. local last=1\
  4246. local pos=text:find(\"[\\r\\n]\",last)\
  4247. while pos do\
  4248. tabText[#tabText+1]=text:sub(last,pos-1)\
  4249. if text:byte(pos)==13 then\
  4250. if text:byte(pos+1)==10 then\
  4251. pos=pos+1\
  4252. end\
  4253. end\
  4254. last=pos+1\
  4255. pos=text:find(\"[\\r\\n]\",last)\
  4256. end\
  4257. tabText[#tabText+1]=text:sub(last)\
  4258. return tabText\
  4259. end\
  4260. local function edit_tableToText(tabText,eol)\
  4261. local str;\
  4262. if type(tabText[1])==\"table\" then\
  4263. str=tabText[1].str\
  4264. for line=2,#tabText,1 do\
  4265. str=str..eol..tabText[line].str\
  4266. end\
  4267. else\
  4268. str=tabText[1]\
  4269. for line=2,#tabText,1 do\
  4270. str=str..eol..tabText[line]\
  4271. end\
  4272. end\
  4273. return str\
  4274. end\
  4275. local function edit_countChars(tabText,longEOL)\
  4276. local eol=iif(longEOL,2,1)\
  4277. local len=0\
  4278. if type(tabText[1])==\"table\" then\
  4279. len=tabText[1].len\
  4280. for line=2,#tabText,1 do\
  4281. len=len+tabText[line].len+eol\
  4282. end\
  4283. else\
  4284. len=tabText[1]:len()\
  4285. for line=2,#tabText,1 do\
  4286. len=len+tabText[line]:len()+eol\
  4287. end\
  4288. end\
  4289. return len\
  4290. end\
  4291. editWindow=window:base()\
  4292. function editWindow:constructor(parent,id,x,y,width,height,text,banner)\
  4293. if not window.constructor(self,parent,id,x,y,width,height)then\
  4294. return nil\
  4295. end\
  4296. self.edit__data={{len=0,str=\"\"}}\
  4297. self.edit__banner=\"\"\
  4298. self.edit__modified=false\
  4299. self.edit__error=false\
  4300. self.edit__end=0\
  4301. self.edit__start=0\
  4302. self.edit__tab=0\
  4303. self.edit__cursorCol=0\
  4304. self.edit__readOnly=false\
  4305. self.edit__fireEvents=false\
  4306. self.edit__undo=editUndo:new()\
  4307. self.edit__colors={\
  4308. text=self:getColors().inputText,\
  4309. back=self:getColors().inputBack,\
  4310. focus=self:getColors().inputFocus,\
  4311. error=self:getColors().inputError,\
  4312. banner=self:getColors().inputBanner\
  4313. }\
  4314. self:setColor(self.edit__colors.text)\
  4315. self:setBgColor(self.edit__colors.back)\
  4316. self:setWantKeyInput(KEYINPUT_EDIT)\
  4317. self:setBanner(banner)\
  4318. self:setText(text)\
  4319. self.edit__fireEvents=true\
  4320. return self\
  4321. end\
  4322. function editWindow:setColors(text,background,focus,banner,errorColor)\
  4323. self.edit__colors.text=text\
  4324. self.edit__colors.back=background\
  4325. self.edit__colors.focus=focus\
  4326. self.edit__colors.error=errorColor\
  4327. self.edit__colors.banner=banner\
  4328. self:setColor(text)\
  4329. self:setBgColor(iif(self:getFocus()==self,focus,background))\
  4330. end\
  4331. function editWindow:setBanner(banner)\
  4332. self.edit__banner=asstring(banner)\
  4333. self:invalidate()\
  4334. end\
  4335. function editWindow:getBanner()\
  4336. return self.edit__banner\
  4337. end\
  4338. function editWindow:getError()\
  4339. return self.edit__error\
  4340. end\
  4341. function editWindow:setError(bError)\
  4342. bError=(bError~=false)\
  4343. if bError~=self.edit__error then\
  4344. self.edit__error=bError\
  4345. self:setBgColor(iif(self.edit__error,\
  4346. self.edit__colors.error,\
  4347. iif(self:getFocus()==self,\
  4348. self.edit__colors.focus,\
  4349. self.edit__colors.back)))\
  4350. end\
  4351. end\
  4352. function editWindow:setModified(modified,fireEvent)\
  4353. modified=(modified~=false)\
  4354. if(modified and not self.edit__modified)or\
  4355. (self.edit__modified and not modified)then\
  4356. self.edit__modified=modified\
  4357. if fireEvent~=false then\
  4358. if self:getParent()and self.edit__fireEvents then\
  4359. self:getParent():sendEvent(\"modified\",self)\
  4360. end\
  4361. end\
  4362. end\
  4363. end\
  4364. function editWindow:getModified()\
  4365. return self.edit__modified\
  4366. end\
  4367. function editWindow:getTabWidth()\
  4368. return self.edit__tab\
  4369. end\
  4370. function editWindow:setTabWidth(chars)\
  4371. self.edit__tab=math.floor(asnumber(chars))\
  4372. end\
  4373. function editWindow:getReadOnly()\
  4374. return self.edit__readOnly\
  4375. end\
  4376. function editWindow:setReadOnly(readOnly)\
  4377. self.edit__readOnly=readOnly~=false\
  4378. end\
  4379. function editWindow:lines()\
  4380. return #self.edit__data\
  4381. end\
  4382. function editWindow:getTextLength(longEOL)\
  4383. return edit_countChars(self.edit__data,longEOL)\
  4384. end\
  4385. function editWindow:lineIndex(line)\
  4386. local index=0\
  4387. line=iif(line<0,1,line+1)\
  4388. if line>(#self.edit__data+1)then\
  4389. line=#self.edit__data+1\
  4390. end\
  4391. for i=1,line-1,1 do\
  4392. index=index+self.edit__data[i].len+1\
  4393. end\
  4394. if line==(#self.edit__data+1)then\
  4395. index=index-1\
  4396. end\
  4397. return index\
  4398. end\
  4399. function editWindow:lineFromChar(char)\
  4400. local index,prior=0,0\
  4401. if char<0 then\
  4402. char=0\
  4403. end\
  4404. for line=1,#self.edit__data,1 do\
  4405. if char<index then\
  4406. return(line-2),(char-prior)\
  4407. end\
  4408. prior=index\
  4409. index=index+self.edit__data[line].len+1\
  4410. end\
  4411. char=char-prior\
  4412. if char>self.edit__data[#self.edit__data].len then\
  4413. char=self.edit__data[#self.edit__data].len\
  4414. end\
  4415. return(#self.edit__data-1),char\
  4416. end\
  4417. function editWindow:charFromPoint(x,y)\
  4418. local char,line=x,y+1\
  4419. if line>#self.edit__data then\
  4420. line=#self.edit__data\
  4421. elseif line<1 then\
  4422. line=1\
  4423. end\
  4424. if char>self.edit__data[line].len then\
  4425. char=self.edit__data[line].len\
  4426. elseif char<0 then\
  4427. char=0\
  4428. end\
  4429. if line>1 then\
  4430. char=char+self:lineIndex(line-1)\
  4431. end\
  4432. return char\
  4433. end\
  4434. function editWindow:setSel(selStart,selEnd,autoScroll)\
  4435. local strLen=self:getTextLength()\
  4436. selStart=asnumber(selStart)\
  4437. if selStart==-1 then\
  4438. selStart=strLen\
  4439. elseif selStart<0 then\
  4440. selStart=0\
  4441. elseif selStart>strLen then\
  4442. selStart=strLen\
  4443. end\
  4444. if selEnd==nil then\
  4445. selEnd=selStart\
  4446. elseif selEnd==-1 then\
  4447. selEnd=strLen\
  4448. elseif selEnd<0 then\
  4449. selEnd=0\
  4450. elseif selEnd>strLen then\
  4451. selEnd=strLen\
  4452. end\
  4453. self.edit__end=selEnd\
  4454. self.edit__start=selStart\
  4455. self:invalidate(0,0,self:getClientSize())\
  4456. if autoScroll~=false then\
  4457. local zx,zy=self:getClientSize()\
  4458. local sx,sy=self:getScrollOrg()\
  4459. local line,char=self:lineFromChar(selEnd)\
  4460. if(char-sx)<0 then\
  4461. sx=char-math.floor(zx/4)\
  4462. elseif char>=(sx+zx)then\
  4463. sx=char-zx+1\
  4464. end\
  4465. if(line-sy)<0 then\
  4466. sy=line\
  4467. elseif line>=(sy+zy)then\
  4468. sy=line-zy+1\
  4469. end\
  4470. self:setScrollOrg(sx,sy)\
  4471. end\
  4472. if self:getFocus()==self then\
  4473. local y,x=self:lineFromChar(self.edit__end)\
  4474. self:setCursorPos(x,y)\
  4475. end\
  4476. if self:getParent()and self.edit__fireEvents then\
  4477. self:getParent():sendEvent(\"selection_change\",self)\
  4478. end\
  4479. end\
  4480. function editWindow:getSel(normalise)\
  4481. if normalise then\
  4482. if self.edit__end<self.edit__start then\
  4483. return self.edit__end,self.edit__start\
  4484. end\
  4485. end\
  4486. return self.edit__start,self.edit__end\
  4487. end\
  4488. function editWindow:getSelection()\
  4489. local sel={}\
  4490. local ss,se=self:getSel(true)\
  4491. if ss~=se then\
  4492. local sline,schar=self:lineFromChar(ss)\
  4493. local eline,echar=self:lineFromChar(se)\
  4494. if sline==eline then\
  4495. sel[1]=self.edit__data[sline+1].str:sub(schar+1,echar)\
  4496. else\
  4497. sel[1]=self.edit__data[sline+1].str:sub(schar+1)\
  4498. for line=sline+2,eline,1 do\
  4499. sel[#sel+1]=self.edit__data[line].str\
  4500. end\
  4501. sel[#sel+1]=self.edit__data[eline+1].str:sub(1,echar)\
  4502. end\
  4503. else\
  4504. sel[1]=\"\"\
  4505. end\
  4506. return sel\
  4507. end\
  4508. function editWindow:getSelectedText(eol)\
  4509. return edit_tableToText(self:getSelection(),eol or \"\\n\")\
  4510. end\
  4511. function editWindow:updateScrollSize()\
  4512. local width=0\
  4513. for i=1,#self.edit__data,1 do\
  4514. if self.edit__data[i].len>=width then\
  4515. width=self.edit__data[i].len+1\
  4516. end\
  4517. end\
  4518. self:setScrollSize(width,#self.edit__data)\
  4519. end\
  4520. function editWindow:replaceSelTabled(insert,autoScroll,undoAction)\
  4521. local ss,se=self:getSel(true)\
  4522. local sline,schar=self:lineFromChar(ss)\
  4523. local removed={}\
  4524. local insertChars=edit_countChars(insert,false)\
  4525. if ss~=se then\
  4526. local eline,echar=self:lineFromChar(se)\
  4527. if sline==eline then\
  4528. removed[1]=self.edit__data[sline+1].str:sub(schar+1,echar)\
  4529. self.edit__data[sline+1].str=\
  4530. self.edit__data[sline+1].str:sub(1,schar)..\
  4531. self.edit__data[sline+1].str:sub(echar+1)\
  4532. self.edit__data[sline+1].len=self.edit__data[sline+1].str:len()\
  4533. else\
  4534. removed[1]=self.edit__data[sline+1].str:sub(schar+1)\
  4535. self.edit__data[sline+1].str=\
  4536. self.edit__data[sline+1].str:sub(1,schar)\
  4537. for line=sline+2,eline,1 do\
  4538. removed[#removed+1]=self.edit__data[sline+2].str\
  4539. table.remove(self.edit__data,sline+2)\
  4540. end\
  4541. removed[#removed+1]=self.edit__data[sline+2].str:sub(1,echar)\
  4542. self.edit__data[sline+1].str=\
  4543. self.edit__data[sline+1].str..\
  4544. self.edit__data[sline+2].str:sub(echar+1)\
  4545. table.remove(self.edit__data,sline+2)\
  4546. self.edit__data[sline+1].len=self.edit__data[sline+1].str:len()\
  4547. end\
  4548. else\
  4549. removed[1]=\"\"\
  4550. end\
  4551. if #insert==1 then\
  4552. if insert[1]:len()>0 then\
  4553. if insert[1]:len()==1 then\
  4554. self.edit__data[sline+1].str=\
  4555. self.edit__data[sline+1].str:sub(1,schar)..\
  4556. insert[1]..\
  4557. self.edit__data[sline+1].str:sub(schar+1)\
  4558. self.edit__data[sline+1].len=self.edit__data[sline+1].len+1\
  4559. else\
  4560. self.edit__data[sline+1].str=\
  4561. self.edit__data[sline+1].str:sub(1,schar)..\
  4562. insert[1]..\
  4563. self.edit__data[sline+1].str:sub(schar+1)\
  4564. self.edit__data[sline+1].len=self.edit__data[sline+1].len+insert[1]:len()\
  4565. end\
  4566. end\
  4567. else\
  4568. table.insert(self.edit__data,sline+2,\
  4569. {len=0,str=(insert[#insert]..self.edit__data[sline+1].str:sub(schar+1))})\
  4570. self.edit__data[sline+2].len=self.edit__data[sline+2].str:len()\
  4571. self.edit__data[sline+1].str=\
  4572. self.edit__data[sline+1].str:sub(1,schar)..\
  4573. insert[1]\
  4574. self.edit__data[sline+1].len=self.edit__data[sline+1].str:len()\
  4575. for line=2,#insert-1,1 do\
  4576. table.insert(self.edit__data,sline+line,{len=insert[line]:len(),str=insert[line]})\
  4577. end\
  4578. end\
  4579. if undoAction then\
  4580. self.edit__undo:record(ss,insert,removed,undoAction)\
  4581. end\
  4582. self:updateScrollSize()\
  4583. self:setSel(ss+insertChars,ss+insertChars,autoScroll)\
  4584. self:setModified()\
  4585. self.edit__cursorCol=self:getCursorPos()\
  4586. end\
  4587. function editWindow:replaceSel(replaceText,autoScroll)\
  4588. self:replaceSelTabled(edit_textToTable(asstring(replaceText)),autoScroll,EU_REPLACE)\
  4589. end\
  4590. function editWindow:cut()\
  4591. local strSel=self:getSelectedText()\
  4592. if strSel:len()>0 then\
  4593. self:setClipboard(strSel,CB_TEXT)\
  4594. self:replaceSelTabled({\"\"},nil,EU_REPLACE)\
  4595. self.edit__cursorCol=self:getCursorPos()\
  4596. end\
  4597. end\
  4598. function editWindow:copy()\
  4599. local strSel=self:getSelectedText()\
  4600. if strSel:len()>0 then\
  4601. self:setClipboard(strSel,CB_TEXT)\
  4602. end\
  4603. end\
  4604. function editWindow:paste()\
  4605. local cbType,cbData=self:getClipboard()\
  4606. if cbType==CB_TEXT then\
  4607. self:replaceSel(cbData)\
  4608. self.edit__cursorCol=self:getCursorPos()\
  4609. end\
  4610. end\
  4611. function editWindow:draw(gdi,bounds)\
  4612. if #self.edit__data==1 and self.edit__data[1].len==0 then\
  4613. if self:getBanner():len()>0 then\
  4614. gdi:setBackgroundColor(self:getBgColor())\
  4615. gdi:setTextColor(self.edit__colors.banner)\
  4616. gdi:write(self:getBanner(),0,0)\
  4617. end\
  4618. else\
  4619. local ss,se=self:getSel(true)\
  4620. local lastLine,firstLine=self:wndToScroll(bounds.x,bounds.y)\
  4621. lastLine=firstLine+bounds.height-1\
  4622. if firstLine<0 then\
  4623. firstLine=0\
  4624. elseif firstLine>=#self.edit__data then\
  4625. firstLine=#self.edit__data-1\
  4626. end\
  4627. if lastLine<0 then\
  4628. lastLine=0\
  4629. elseif lastLine>=#self.edit__data then\
  4630. lastLine=#self.edit__data-1\
  4631. end\
  4632. if lastLine>=firstLine then\
  4633. if ss==se then\
  4634. gdi:setBackgroundColor(self:getBgColor())\
  4635. gdi:setTextColor(self:getColor())\
  4636. for line=firstLine,lastLine,1 do\
  4637. gdi:write(self.edit__data[line+1].str,0,line)\
  4638. end\
  4639. else\
  4640. local sline,schar=self:lineFromChar(ss)\
  4641. local eline,echar=self:lineFromChar(se)\
  4642. if sline==eline then\
  4643. for line=firstLine,lastLine,1 do\
  4644. if line==sline then\
  4645. gdi:setBackgroundColor(self:getBgColor())\
  4646. gdi:setTextColor(self:getColor())\
  4647. gdi:write(self.edit__data[line+1].str:sub(1,schar),0,line)\
  4648. gdi:setBackgroundColor(self:getColors().selectedBack)\
  4649. gdi:setTextColor(self:getColors().selectedText)\
  4650. gdi:write(self.edit__data[line+1].str:sub(schar+1,echar),schar,line)\
  4651. gdi:setBackgroundColor(self:getBgColor())\
  4652. gdi:setTextColor(self:getColor())\
  4653. gdi:write(self.edit__data[line+1].str:sub(echar+1),echar,line)\
  4654. else\
  4655. gdi:setBackgroundColor(self:getBgColor())\
  4656. gdi:setTextColor(self:getColor())\
  4657. gdi:write(self.edit__data[line+1].str,0,line)\
  4658. end\
  4659. end\
  4660. else\
  4661. for line=firstLine,lastLine,1 do\
  4662. if line==sline then\
  4663. gdi:setBackgroundColor(self:getBgColor())\
  4664. gdi:setTextColor(self:getColor())\
  4665. gdi:write(self.edit__data[line+1].str:sub(1,schar),0,line)\
  4666. gdi:setBackgroundColor(self:getColors().selectedBack)\
  4667. gdi:setTextColor(self:getColors().selectedText)\
  4668. gdi:write((self.edit__data[line+1].str..\" \"):sub(schar+1),schar,line)\
  4669. elseif line==eline then\
  4670. gdi:setBackgroundColor(self:getColors().selectedBack)\
  4671. gdi:setTextColor(self:getColors().selectedText)\
  4672. gdi:write(self.edit__data[line+1].str:sub(1,echar),0,line)\
  4673. gdi:setBackgroundColor(self:getBgColor())\
  4674. gdi:setTextColor(self:getColor())\
  4675. gdi:write(self.edit__data[line+1].str:sub(echar+1),echar,line)\
  4676. else\
  4677. if line>sline and line<eline then\
  4678. gdi:setBackgroundColor(self:getColors().selectedBack)\
  4679. gdi:setTextColor(self:getColors().selectedText)\
  4680. gdi:write(self.edit__data[line+1].str..\" \",0,line)\
  4681. else\
  4682. gdi:setBackgroundColor(self:getBgColor())\
  4683. gdi:setTextColor(self:getColor())\
  4684. gdi:write(self.edit__data[line+1].str,0,line)\
  4685. end\
  4686. end\
  4687. end\
  4688. end\
  4689. end\
  4690. end\
  4691. end\
  4692. end\
  4693. function editWindow:setText(text)\
  4694. self:setSel(0,-1,false)\
  4695. self:replaceSel(asstring(text))\
  4696. self:setSel(-1,-1)\
  4697. self:setModified(false)\
  4698. self.edit__undo:reset()\
  4699. end\
  4700. function editWindow:canUndo()\
  4701. return self.edit__undo:canUndo()\
  4702. end\
  4703. function editWindow:canRedo()\
  4704. return self.edit__undo:canRedo()\
  4705. end\
  4706. function editWindow:undo()\
  4707. local data=self.edit__undo:undo()\
  4708. if data then\
  4709. self:setSel(data.pos,data.pos+edit_countChars(data.inserted,false),false)\
  4710. self:replaceSelTabled(data.removed)\
  4711. self.edit__cursorCol=self:getCursorPos()\
  4712. end\
  4713. end\
  4714. function editWindow:redo()\
  4715. local data=self.edit__undo:redo()\
  4716. if data then\
  4717. self:setSel(data.pos,data.pos+edit_countChars(data.removed,false),false)\
  4718. self:replaceSelTabled(data.inserted)\
  4719. self.edit__cursorCol=self:getCursorPos()\
  4720. end\
  4721. end\
  4722. function editWindow:getText(eol)\
  4723. return edit_tableToText(self.edit__data,eol or \"\\n\")\
  4724. end\
  4725. function editWindow:onFocus(blurred)\
  4726. self:setBgColor(iif(self.edit__error,\
  4727. self.edit__colors.error,\
  4728. self.edit__colors.focus))\
  4729. self:showCursor()\
  4730. return false\
  4731. end\
  4732. function editWindow:onBlur(focused)\
  4733. self:hideCursor()\
  4734. self:setBgColor(iif(self.edit__error,\
  4735. self.edit__colors.error,\
  4736. self.edit__colors.back))\
  4737. return false\
  4738. end\
  4739. function editWindow:onKey(key,ctrl,alt,shift)\
  4740. if not ctrl and not alt and not shift then\
  4741. local ss,se=self:getSel(false)\
  4742. if key==keys.backspace then\
  4743. if not self:getReadOnly()then\
  4744. if ss==se then\
  4745. if ss>0 then\
  4746. self:setSel(ss-1,ss,false)\
  4747. self:replaceSelTabled({\"\"},nil,EU_BACKSPACE)\
  4748. end\
  4749. else\
  4750. self:replaceSelTabled({\"\"},nil,EU_BACKSPACE)\
  4751. end\
  4752. end\
  4753. return true\
  4754. elseif key==keys.delete then\
  4755. if not self:getReadOnly()then\
  4756. if ss==se then\
  4757. self:setSel(ss,ss+1,false)\
  4758. end\
  4759. self:replaceSelTabled({\"\"},nil,EU_DELETE)\
  4760. end\
  4761. return true\
  4762. elseif key==keys.enter then\
  4763. if not self:getReadOnly()then\
  4764. self:replaceSelTabled({\"\",\"\"},nil,EU_TYPE)\
  4765. end\
  4766. return true\
  4767. elseif key==keys.tab then\
  4768. if not self:getReadOnly()and self:getTabWidth()>0 then\
  4769. local line,offset=self:lineFromChar((self:getSel(true)))\
  4770. offset=self:getTabWidth()-math.fmod(offset,self:getTabWidth())\
  4771. self:replaceSelTabled({string.rep(\" \",offset)},nil,EU_TYPE)\
  4772. end\
  4773. return true\
  4774. elseif key==keys.left then\
  4775. if se>0 then\
  4776. self:setSel(se-1,se-1)\
  4777. self.edit__undo:endAction()\
  4778. self.edit__cursorCol=self:getCursorPos()\
  4779. end\
  4780. return true\
  4781. elseif key==keys.right then\
  4782. self:setSel(se+1,se+1)\
  4783. self.edit__undo:endAction()\
  4784. self.edit__cursorCol=self:getCursorPos()\
  4785. return true\
  4786. elseif key==keys.up then\
  4787. local y,x=self:lineFromChar(se)\
  4788. if y>0 then\
  4789. y=self:charFromPoint(self.edit__cursorCol,y-1)\
  4790. self:setSel(y,y)\
  4791. self.edit__undo:endAction()\
  4792. end\
  4793. return true\
  4794. elseif key==keys.down then\
  4795. local y,x=self:lineFromChar(se)\
  4796. if y<self:lines()then\
  4797. y=self:charFromPoint(self.edit__cursorCol,y+1)\
  4798. self:setSel(y,y)\
  4799. self.edit__undo:endAction()\
  4800. end\
  4801. return true\
  4802. elseif key==keys.pageUp then\
  4803. local y,x=self:lineFromChar(se)\
  4804. if y>0 then\
  4805. local zx,zy=self:getClientSize()\
  4806. y=y-zy+1\
  4807. y=self:charFromPoint(self.edit__cursorCol,iif(y<0,0,y))\
  4808. self:setSel(y,y)\
  4809. self.edit__undo:endAction()\
  4810. end\
  4811. return true\
  4812. elseif key==keys.pageDown then\
  4813. local y,x=self:lineFromChar(se)\
  4814. if y<self:lines()then\
  4815. local zx,zy=self:getClientSize()\
  4816. y=y+zy-1\
  4817. y=self:charFromPoint(self.edit__cursorCol,iif(y>=self:lines(),self:lines()-1,y))\
  4818. self:setSel(y,y)\
  4819. self.edit__undo:endAction()\
  4820. end\
  4821. return true\
  4822. elseif key==keys.home then\
  4823. se=self:lineIndex((self:lineFromChar(se)))\
  4824. self:setSel(se,se)\
  4825. self.edit__undo:endAction()\
  4826. self.edit__cursorCol=self:getCursorPos()\
  4827. return true\
  4828. elseif key==207 then \
  4829. local line=self:lineFromChar(se)\
  4830. se=self:lineIndex(line+1)\
  4831. if line<(self:lines()-1)then\
  4832. se=se-1\
  4833. end\
  4834. self:setSel(se,se)\
  4835. self.edit__undo:endAction()\
  4836. self.edit__cursorCol=self:getCursorPos()\
  4837. return true\
  4838. end\
  4839. elseif not ctrl and not alt and shift then\
  4840. local ss,se=self:getSel(false)\
  4841. if key==keys.left then\
  4842. if se>0 then\
  4843. self:setSel(ss,se-1)\
  4844. self.edit__undo:endAction()\
  4845. self.edit__cursorCol=self:getCursorPos()\
  4846. end\
  4847. return true\
  4848. elseif key==keys.right then\
  4849. self:setSel(ss,se+1)\
  4850. self.edit__undo:endAction()\
  4851. self.edit__cursorCol=self:getCursorPos()\
  4852. return true\
  4853. elseif key==keys.up then\
  4854. local y,x=self:lineFromChar(se)\
  4855. if y>0 then\
  4856. self:setSel(ss,self:charFromPoint(self.edit__cursorCol,y-1))\
  4857. self.edit__undo:endAction()\
  4858. end\
  4859. return true\
  4860. elseif key==keys.down then\
  4861. local y,x=self:lineFromChar(se)\
  4862. if y<self:lines()then\
  4863. self:setSel(ss,self:charFromPoint(self.edit__cursorCol,y+1))\
  4864. self.edit__undo:endAction()\
  4865. end\
  4866. return true\
  4867. elseif key==keys.pageUp then\
  4868. local y,x=self:lineFromChar(se)\
  4869. if y>0 then\
  4870. local zx,zy=self:getClientSize()\
  4871. y=y-zy+1\
  4872. self:setSel(ss,self:charFromPoint(self.edit__cursorCol,iif(y<0,0,y)))\
  4873. self.edit__undo:endAction()\
  4874. end\
  4875. return true\
  4876. elseif key==keys.pageDown then\
  4877. local y,x=self:lineFromChar(se)\
  4878. if y<self:lines()then\
  4879. local zx,zy=self:getClientSize()\
  4880. y=y+zy-1\
  4881. self:setSel(ss,self:charFromPoint(self.edit__cursorCol,iif(y>=self:lines(),self:lines()-1,y)))\
  4882. self.edit__undo:endAction()\
  4883. end\
  4884. return true\
  4885. elseif key==keys.home then\
  4886. self:setSel(ss,self:lineIndex((self:lineFromChar(se))))\
  4887. self.edit__undo:endAction()\
  4888. self.edit__cursorCol=self:getCursorPos()\
  4889. return true\
  4890. elseif key==207 then \
  4891. local line=self:lineFromChar(se)\
  4892. se=self:lineIndex(line+1)\
  4893. if line<(self:lines()-1)then\
  4894. se=se-1\
  4895. end\
  4896. self:setSel(ss,se)\
  4897. self.edit__undo:endAction()\
  4898. self.edit__cursorCol=self:getCursorPos()\
  4899. return true\
  4900. end\
  4901. elseif ctrl and not alt and not shift then\
  4902. if key==keys.x then\
  4903. if not self:getReadOnly()then\
  4904. self:cut()\
  4905. end\
  4906. return true\
  4907. elseif key==keys.c then\
  4908. self:copy()\
  4909. return true\
  4910. elseif key==keys.b then\
  4911. if not self:getReadOnly()then\
  4912. self:paste()\
  4913. end\
  4914. return true\
  4915. elseif key==keys.z then\
  4916. if not self:getReadOnly()then\
  4917. self:undo()\
  4918. end\
  4919. return true\
  4920. elseif key==keys.y then\
  4921. if not self:getReadOnly()then\
  4922. self:redo()\
  4923. end\
  4924. return true\
  4925. elseif key==keys.a then\
  4926. self:setSel(0,-1,false)\
  4927. self.edit__undo:endAction()\
  4928. self.edit__cursorCol=self:getCursorPos()\
  4929. return true\
  4930. elseif key==keys.up then\
  4931. self:sendEvent(\"vbar_scroll\",-1,false)\
  4932. return true\
  4933. elseif key==keys.down then\
  4934. self:sendEvent(\"vbar_scroll\",1,false)\
  4935. return true\
  4936. elseif key==keys.left then\
  4937. self:sendEvent(\"hbar_scroll\",-1,false)\
  4938. return true\
  4939. elseif key==keys.right then\
  4940. self:sendEvent(\"hbar_scroll\",1,false)\
  4941. return true\
  4942. elseif key==keys.pageUp then\
  4943. self:sendEvent(\"vbar_scroll\",-1,true)\
  4944. return true\
  4945. elseif key==keys.pageDown then\
  4946. self:sendEvent(\"vbar_scroll\",1,true)\
  4947. return true\
  4948. elseif key==keys.home then\
  4949. self:setScrollOrg(0,0)\
  4950. return true\
  4951. elseif key==207 then \
  4952. self:setScrollOrg(0,self:lines())\
  4953. return true\
  4954. end\
  4955. end\
  4956. return false\
  4957. end\
  4958. function editWindow:onChar(char)\
  4959. if not self:getReadOnly()then\
  4960. self:replaceSelTabled({char},nil,EU_TYPE)\
  4961. end\
  4962. return true\
  4963. end\
  4964. function editWindow:onLeftClick(x,y)\
  4965. if window.onLeftClick(self,x,y)then\
  4966. return true\
  4967. end\
  4968. local char=self:charFromPoint(self:wndToScroll(x,y))\
  4969. self:setSel(char,char)\
  4970. self.edit__undo:endAction()\
  4971. self.edit__cursorCol=self:getCursorPos()\
  4972. return true\
  4973. end\
  4974. function editWindow:onLeftDrag(x,y)\
  4975. local ss,se=self:getSel(false)\
  4976. self:setSel(ss,self:charFromPoint(self:wndToScroll(x,y)))\
  4977. self.edit__undo:endAction()\
  4978. self.edit__cursorCol=self:getCursorPos()\
  4979. return true\
  4980. end\
  4981. function editWindow:onTouch(x,y)\
  4982. if window.onTouch(self,x,y)then\
  4983. return true\
  4984. end\
  4985. local char=self:charFromPoint(self:wndToScroll(x,y))\
  4986. self:setSel(char,char)\
  4987. self.edit__undo:endAction()\
  4988. self.edit__cursorCol=self:getCursorPos()\
  4989. return true\
  4990. end\
  4991. function editWindow:onMove()\
  4992. if self:getFocus()==self then\
  4993. self:showCursor()\
  4994. end\
  4995. return false\
  4996. end\
  4997. function editWindow:onPaste(text)\
  4998. if asstring(text):len()>0 then\
  4999. if not self:getReadOnly()then\
  5000. self:replaceSel(asstring(text))\
  5001. end\
  5002. end\
  5003. return true\
  5004. end\
  5005. function editWindow:onScroll()\
  5006. if self:getFocus()==self then\
  5007. self:showCursor()\
  5008. end\
  5009. end\
  5010. menuWindow=listWindow:base()\
  5011. function menuWindow:constructor(parent)\
  5012. if not listWindow.constructor(self,parent,0,0,0,0,0)then\
  5013. return nil\
  5014. end\
  5015. self:setColors(self:getColors().menuText,\
  5016. self:getColors().menuBack,\
  5017. self:getColors().menuBack,\
  5018. self:getColors().menuSelectedText,\
  5019. self:getColors().menuSelectedBack)\
  5020. self:show(false)\
  5021. return self\
  5022. end\
  5023. function menuWindow:track(x,y)\
  5024. local width,height=0,self:count()\
  5025. local rt=(self:getParent()and self:getParent():getWndRect())or nil\
  5026. for i=1,self:count(),1 do\
  5027. local len=self.list__items[i][1]:len()\
  5028. if len>width then\
  5029. width=len\
  5030. end\
  5031. end\
  5032. if rt then\
  5033. if height>rt.height then\
  5034. y=0\
  5035. height=rt.height\
  5036. width=width+1\
  5037. elseif(y+height)>rt.height then\
  5038. y=rt.height-height\
  5039. end\
  5040. if width>rt.width then\
  5041. x=0\
  5042. width=rt.width\
  5043. elseif(x+width)>rt.width then\
  5044. x=rt.width-width\
  5045. end\
  5046. end\
  5047. self.list__colors.focus=self.list__colors.back\
  5048. self:move(x,y,width,height,WND_TOP)\
  5049. self:setCurSel(self:nextValidItem(0))\
  5050. self:show(true)\
  5051. self:setFocus()\
  5052. self:captureMouse()\
  5053. end\
  5054. function menuWindow:addString(str,data,index)\
  5055. listWindow.addString(self,str,asnumber(data),index)\
  5056. end\
  5057. function menuWindow:setCurSel(index,makeVisible)\
  5058. local i=index\
  5059. if i==nil then\
  5060. i=0\
  5061. end\
  5062. if i>self:count()then\
  5063. i=self:count()\
  5064. end\
  5065. if i>=0 and i<=self:count()and i~=self.list__selIndex then\
  5066. self.list__selIndex=i\
  5067. if makeVisible~=false then\
  5068. self:ensureVisible()\
  5069. end\
  5070. self:invalidate()\
  5071. return true\
  5072. end\
  5073. return false\
  5074. end\
  5075. function menuWindow:nextValidItem(from)\
  5076. for i=asnumber(from)+1,self:count(),1 do\
  5077. if asnumber(self:getData(i))~=0 then\
  5078. return i\
  5079. end\
  5080. end\
  5081. return asnumber(from)\
  5082. end\
  5083. function menuWindow:priorValidItem(from)\
  5084. for i=asnumber(from)-1,1,-1 do\
  5085. if asnumber(self:getData(i))~=0 then\
  5086. return i\
  5087. end\
  5088. end\
  5089. return asnumber(from)\
  5090. end\
  5091. function menuWindow:onBlur(focused)\
  5092. self:destroyWnd()\
  5093. return true\
  5094. end\
  5095. function menuWindow:onKey(key,ctrl,alt,shift)\
  5096. if not ctrl and not alt and not shift then\
  5097. if key==keys.enter then\
  5098. local parent=self:getParent()\
  5099. self:destroyWnd()\
  5100. if parent then\
  5101. parent:sendEvent(\"menu_cmd\",self:getData())\
  5102. end\
  5103. return true\
  5104. end\
  5105. if key==keys.up then\
  5106. self:setCurSel(self:priorValidItem(self:getCurSel()))\
  5107. return true\
  5108. end\
  5109. if key==keys.down then\
  5110. self:setCurSel(self:nextValidItem(self:getCurSel()))\
  5111. return true\
  5112. end\
  5113. if key==keys.home then\
  5114. self:setCurSel(self:nextValidItem(0))\
  5115. return true\
  5116. end\
  5117. if key==207 then \
  5118. self:setCurSel(self:priorValidItem(self:count()+1))\
  5119. return true\
  5120. end\
  5121. elseif not alt and not shift then\
  5122. if key==keys.leftCtrl or key==keys.rightCtrl then\
  5123. self:destroyWnd()\
  5124. return true\
  5125. end\
  5126. end\
  5127. return false\
  5128. end\
  5129. function menuWindow:onLeftClick(x,y)\
  5130. if window.onLeftClick(self,x,y)then\
  5131. return true\
  5132. end\
  5133. local rtWnd=rect:new(0,0,self.width,self.height)\
  5134. if rtWnd:contains(x,y)then\
  5135. local sx,sy=self:wndToScroll(x,y)\
  5136. if self:getData(sy+1)~=0 then\
  5137. local parent=self:getParent()\
  5138. self:setCurSel(sy+1)\
  5139. self:destroyWnd()\
  5140. if parent then\
  5141. parent:sendEvent(\"menu_cmd\",self:getData())\
  5142. end\
  5143. end\
  5144. else\
  5145. self:destroyWnd()\
  5146. end\
  5147. return true\
  5148. end\
  5149. function menuWindow:onTouch(x,y)\
  5150. if window.onTouch(self,x,y)then\
  5151. return true\
  5152. end\
  5153. local rtWnd=rect:new(0,0,self.width,self.height)\
  5154. if rtWnd:contains(x,y)then\
  5155. local sx,sy=self:wndToScroll(x,y)\
  5156. if self:getData(sy+1)~=0 then\
  5157. local parent=self:getParent()\
  5158. self:setCurSel(sy+1)\
  5159. self:destroyWnd()\
  5160. if parent then\
  5161. parent:sendEvent(\"menu_cmd\",self:getData())\
  5162. end\
  5163. end\
  5164. else\
  5165. self:destroyWnd()\
  5166. end\
  5167. return true\
  5168. end\
  5169. closeButtonWindow=buttonWindow:base()\
  5170. function closeButtonWindow:constructor(parent,x,y)\
  5171. local label=__defaultTheme.closeBtnChar\
  5172. if parent then\
  5173. label=parent:getTheme().closeBtnChar\
  5174. end\
  5175. if not buttonWindow.constructor(self,parent,ID_CLOSE,x,y,label)then\
  5176. return nil\
  5177. end\
  5178. self:setColors(self:getColors().closeText,\
  5179. self:getColors().closeBack,\
  5180. self:getColors().closeFocus)\
  5181. return self\
  5182. end\
  5183. function closeButtonWindow:onLeftClick(x,y)\
  5184. if window.onLeftClick(self,x,y)then\
  5185. return true\
  5186. end\
  5187. if self:getParent()then\
  5188. self:getParent():sendEvent(\"frame_close\")\
  5189. end\
  5190. return false\
  5191. end\
  5192. function closeButtonWindow:onTouch(x,y)\
  5193. if window.onTouch(self,x,y)then\
  5194. return true\
  5195. end\
  5196. if self:getParent()then\
  5197. self:getParent():sendEvent(\"frame_close\")\
  5198. end\
  5199. return false\
  5200. end\
  5201. local parentFrame=window:base()\
  5202. popupFrame=parentFrame:base()\
  5203. function popupFrame:constructor(ownerFrame,width,height)\
  5204. assert(ownerFrame,\"popupFrame:new() must have an owner frame.\")\
  5205. assert(ownerFrame.onFrameActivate,\
  5206. \"popupFrame:new() must have an owner frame.\")\
  5207. assert(ownerFrame.wnd__popup==nil,\
  5208. \"popupFrame:new() owner frame already has popup.\")\
  5209. width=asnumber(width)\
  5210. height=asnumber(height)\
  5211. local desktop=ownerFrame:getDesktop()\
  5212. local rtWork=desktop:getWorkArea()\
  5213. local popupWidth,popupHeight=width,height\
  5214. if width>rtWork.width then\
  5215. popupWidth=rtWork.width\
  5216. end\
  5217. if height>rtWork.height then\
  5218. popupHeight=rtWork.height\
  5219. end\
  5220. if not parentFrame.constructor(self,desktop,ID_DIALOG,\
  5221. math.floor((rtWork.width-popupWidth)/2),\
  5222. math.floor((rtWork.height-popupHeight)/2),\
  5223. popupWidth,popupHeight)then\
  5224. return nil\
  5225. end\
  5226. self.wnd__owner=ownerFrame\
  5227. ownerFrame.wnd__popup=self\
  5228. self.wnd__frameClass=FRAME_CLASS_DIALOG\
  5229. self:setColor(desktop:getColors().popupText)\
  5230. self:setBgColor(desktop:getColors().popupBack)\
  5231. return self\
  5232. end\
  5233. function popupFrame:onCreate(...)\
  5234. return true\
  5235. end\
  5236. function popupFrame:onClose()\
  5237. return false\
  5238. end\
  5239. function popupFrame:close(result)\
  5240. if self:onClose()then\
  5241. return false\
  5242. end\
  5243. self:endModal(result)\
  5244. return true\
  5245. end\
  5246. function popupFrame:onResize()\
  5247. self:move()\
  5248. return true\
  5249. end\
  5250. function popupFrame:move(x,y,width,height)\
  5251. local rtWork=self:getDesktop():getWorkArea()\
  5252. if not width then\
  5253. width=self.width\
  5254. end\
  5255. if width>rtWork.width then\
  5256. width=rtWork.width\
  5257. end\
  5258. if not height then\
  5259. height=self.height\
  5260. end\
  5261. if height>rtWork.height then\
  5262. height=rtWork.height\
  5263. end\
  5264. if not x then\
  5265. x=math.floor((rtWork.width-width)/2)\
  5266. end\
  5267. if not y then\
  5268. y=math.floor((rtWork.height-height)/2)\
  5269. end\
  5270. if x<rtWork.x then\
  5271. x=rtWork.x\
  5272. end\
  5273. if y<rtWork.y then\
  5274. y=rtWork.y\
  5275. end\
  5276. if(x+width)>(rtWork.x+rtWork.width)then\
  5277. x=(rtWork.x+rtWork.width)-width\
  5278. end\
  5279. if(y+height)>(rtWork.y+rtWork.height)then\
  5280. y=(rtWork.y+rtWork.height)-height\
  5281. end\
  5282. parentFrame.move(self,x,y,width,height)\
  5283. end\
  5284. function popupFrame:onMove()\
  5285. parentFrame.onMove(self)\
  5286. local xBtn=self:getWndById(ID_CLOSE)\
  5287. if xBtn then\
  5288. xBtn:move(self.width-1)\
  5289. end\
  5290. return false\
  5291. end\
  5292. function popupFrame:onFrameClose()\
  5293. self:close(ID_CLOSE)\
  5294. return true\
  5295. end\
  5296. function popupFrame:dress(titleText)\
  5297. self:setText(titleText)\
  5298. closeButtonWindow:new(self,self.width-1,0):setFocus()\
  5299. local titleBar=labelWindow:new(self,ID_TITLEBAR,1,0,titleText)\
  5300. titleBar:setBgColor(titleBar:getColors().titleBack)\
  5301. titleBar:setColor(titleBar:getColors().titleText)\
  5302. end\
  5303. function popupFrame:draw(gdi,bounds)\
  5304. if ccVersion()>=1.76 then\
  5305. if self:getWndById(ID_TITLEBAR)then\
  5306. gdi:setBackgroundColor(self:getColors().titleBack)\
  5307. gdi:clear(0,0,self.width,1)\
  5308. if self.width>2 and self.height>2 then\
  5309. local edge=string.char(149)\
  5310. gdi:setBackgroundColor(self:getColors().titleBack)\
  5311. gdi:setTextColor(self:getBgColor())\
  5312. gdi:writeWnd(string.char(138)..string.rep(string.char(143),self.width-2)..string.char(133),0,self.height-1)\
  5313. for l=1,self.height-2,1 do\
  5314. gdi:writeWnd(edge,self.width-1,l)\
  5315. end\
  5316. gdi:setBackgroundColor(self:getBgColor())\
  5317. gdi:setTextColor(self:getColors().titleBack)\
  5318. for l=1,self.height-2,1 do\
  5319. gdi:writeWnd(edge,0,l)\
  5320. end\
  5321. end\
  5322. end\
  5323. else\
  5324. if bounds.y<1 then\
  5325. if self:getWndById(ID_TITLEBAR)then\
  5326. gdi:setBackgroundColor(self:getColors().titleBack)\
  5327. gdi:clear(0,0,self.width,1)\
  5328. end\
  5329. end\
  5330. end\
  5331. end\
  5332. function popupFrame:setTitle(titleText)\
  5333. local tText=self:getWndById(ID_TITLEBAR)\
  5334. self:setText(titleText)\
  5335. if tText then\
  5336. tText:setText(titleText)\
  5337. tText:move(nil,nil,tText:getText():len())\
  5338. end\
  5339. end\
  5340. function popupFrame:doModal(...)\
  5341. local result;\
  5342. local enabled=true\
  5343. local success,result=pcall(self.onCreate,self,...)\
  5344. if success then\
  5345. if result then\
  5346. enabled=self.wnd__owner:isEnabled()\
  5347. self.wnd__owner:enable(false)\
  5348. self.wnd__owner:setActiveTopFrame()\
  5349. result=self:runModal()\
  5350. end\
  5351. end\
  5352. if self.wnd__owner then\
  5353. local owner=self.wnd__owner\
  5354. while owner do\
  5355. owner:invalidate()\
  5356. owner=owner.wnd__owner\
  5357. end\
  5358. self.wnd__owner:enable(enabled)\
  5359. self.wnd__owner.wnd__popup=nil\
  5360. self.wnd__owner:setActiveTopFrame()\
  5361. self.wnd__owner.wnd__popup=self\
  5362. end\
  5363. self:destroyWnd()\
  5364. if not success then\
  5365. error(result,0)\
  5366. end\
  5367. return result\
  5368. end\
  5369. local msgBoxFrame=popupFrame:base()\
  5370. function msgBoxFrame:onCreate(titleText,message)\
  5371. title=asstring(title)\
  5372. message=asstring(message)\
  5373. local desktop=self:getDesktop()\
  5374. local rtWork=desktop:getWorkArea()\
  5375. local maxWidth,maxHeight=math.floor(rtWork.width*0.8),\
  5376. math.floor(rtWork.height*0.8)\
  5377. local width,height=string.wrapSize(string.wrap(message,maxWidth-2))\
  5378. if width==(maxWidth-2)and height>=(maxHeight-3)then\
  5379. width,height=string.wrapSize(string.wrap(message,maxWidth-3))\
  5380. end\
  5381. width=width+2\
  5382. height=height+3\
  5383. if width<(title:len()+3)then\
  5384. width=title:len()+3\
  5385. end\
  5386. if height<4 then\
  5387. height=4\
  5388. elseif height>maxHeight then\
  5389. height=maxHeight\
  5390. end\
  5391. self:dress(titleText)\
  5392. textWindow:new(self,ID_MSGBOX_MSG,1,2,width-2,height-3,message)\
  5393. self:setBgColor(self:getBgColor())\
  5394. self:move(nil,nil,width,height)\
  5395. return true\
  5396. end\
  5397. function msgBoxFrame:onResize()\
  5398. popupFrame.onResize(self)\
  5399. local msg=self:getWndById(ID_MSGBOX_MSG)\
  5400. if msg then\
  5401. msg:move(1,2,self.width-2,self.height-3)\
  5402. end\
  5403. return true\
  5404. end\
  5405. function msgBoxFrame:setBgColor(color)\
  5406. popupFrame.setBgColor(self,color)\
  5407. local msg=self:getWndById(ID_MSGBOX_MSG)\
  5408. if msg then\
  5409. msg:setBgColor(color)\
  5410. end\
  5411. end\
  5412. printData=__classBase:base()\
  5413. function printData:constructor(printer,fromPage,toPage,pages,title,userData)\
  5414. self.printer=asstring(printer)\
  5415. self.fromPage=asnumber(fromPage)\
  5416. self.toPage=asnumber(toPage)\
  5417. self.pages=asnumber(pages)\
  5418. self.title=asstring(title)\
  5419. self.data=userData\
  5420. return self\
  5421. end\
  5422. applicationFrame=parentFrame:base()\
  5423. function applicationFrame:constructor(side)\
  5424. local desktop=__ccwin:getDesktop(side)\
  5425. local rtWork=desktop:getWorkArea()\
  5426. if not parentFrame.constructor(self,desktop,ID_FRAME,rtWork:unpack())then\
  5427. return nil\
  5428. end\
  5429. self.wnd__frameClass=FRAME_CLASS_APPLICATION\
  5430. self.appFrame__appRoutine=nil\
  5431. self.appFrame__appPath=nil\
  5432. self.appFrame__yieldPoint=\"modal\"\
  5433. return self\
  5434. end\
  5435. function applicationFrame:onCreate()\
  5436. return true\
  5437. end\
  5438. function applicationFrame:getAppPath()\
  5439. return self.appFrame__appPath\
  5440. end\
  5441. function applicationFrame:onResize()\
  5442. self:move(self:getDesktop():getWorkArea():unpack())\
  5443. local tText=self:getWndById(ID_TITLEBAR)\
  5444. if tText then\
  5445. tText:move(math.floor((self.width-tText:getText():len())/2))\
  5446. end\
  5447. local xBtn=self:getWndById(ID_CLOSE)\
  5448. if xBtn then\
  5449. xBtn:move(self.width-1)\
  5450. end\
  5451. return true\
  5452. end\
  5453. function applicationFrame:quitApp()\
  5454. if self:onQuit()then\
  5455. return\
  5456. end\
  5457. self:endModal(0)\
  5458. end\
  5459. function applicationFrame:onQuit()\
  5460. return false\
  5461. end\
  5462. function applicationFrame:onFrameClose()\
  5463. self:quitApp()\
  5464. return true\
  5465. end\
  5466. function applicationFrame:dress(titleText)\
  5467. self:setText(titleText)\
  5468. closeButtonWindow:new(self,self.width-1,0):setFocus()\
  5469. local titleBar=labelWindow:new(self,ID_TITLEBAR,\
  5470. math.floor((self.width-titleText:len())/2),\
  5471. 0,titleText)\
  5472. titleBar:setBgColor(titleBar:getColors().titleBack)\
  5473. titleBar:setColor(titleBar:getColors().titleText)\
  5474. end\
  5475. function applicationFrame:draw(gdi,bounds)\
  5476. if bounds.y<1 then\
  5477. if self:getWndById(ID_TITLEBAR)then\
  5478. gdi:setBackgroundColor(self:getColors().titleBack)\
  5479. gdi:clear(0,0,self.width,1)\
  5480. end\
  5481. end\
  5482. end\
  5483. function applicationFrame:setTitle(titleText)\
  5484. local tText=self:getWndById(ID_TITLEBAR)\
  5485. self:setText(titleText)\
  5486. if tText then\
  5487. tText:setText(titleText)\
  5488. tText:move(nil,nil,tText:getText():len())\
  5489. self:onResize()\
  5490. end\
  5491. end\
  5492. function applicationFrame:runApp()\
  5493. if self:onCreate()then\
  5494. self:runModal()\
  5495. end\
  5496. self:getDesktop():dropApp(self)\
  5497. end\
  5498. function applicationFrame:onPrintPage(gdi,page,data)\
  5499. return false\
  5500. end\
  5501. function applicationFrame:printLoop(data)\
  5502. if data then\
  5503. local continue=true\
  5504. local page=math.max(1,data.fromPage)\
  5505. local gdi=GDI:new(data.printer)\
  5506. assert(gdi,\"Failed to create printer GDI for \"..data.printer)\
  5507. while true do\
  5508. while not gdi:newPage()do\
  5509. if not cmndlg.confirm(self,\"Check Printer\",\
  5510. \"Ensure printer \\\"\"..gdi:getSide()..\
  5511. \"\\\" has paper and ink.\\nPress Ok to continue.\",\
  5512. true)then\
  5513. return\
  5514. end\
  5515. end\
  5516. continue=self:onPrintPage(gdi,page,data)\
  5517. if page==1 then\
  5518. gdi:setPageTitle(data.title)\
  5519. else\
  5520. gdi:setPageTitle(string.format(\"%s %d\",data.title,page))\
  5521. end\
  5522. page=page+1\
  5523. while not gdi:endPage()do\
  5524. if not cmndlg.confirm(self,\"Clear Tray\",\
  5525. \"Clear out tray on printer \\\"\"..gdi:getSide()..\
  5526. \"\\\".\\nPress Ok to continue.\",true)then\
  5527. return\
  5528. end\
  5529. end\
  5530. if not continue or(data.toPage>0 and page>data.toPage)then\
  5531. return\
  5532. end\
  5533. end\
  5534. end\
  5535. end\
  5536. function applicationFrame:onPrintData(title,userData,pages,bgcolor)\
  5537. local printer,fromPage,toPage=cmndlg.print(self,pages,bgcolor)\
  5538. if printer then\
  5539. return printData:new(printer,fromPage,toPage,pages,title,userData)\
  5540. end\
  5541. return nil\
  5542. end\
  5543. function applicationFrame:printDoc()\
  5544. self:printLoop(self:onPrintData())\
  5545. end\
  5546. function applicationFrame:status()\
  5547. local status=coroutine.status(self.appFrame__appRoutine)\
  5548. if status==\"suspended\" then\
  5549. return self.appFrame__yieldPoint\
  5550. end\
  5551. return status\
  5552. end\
  5553. function applicationFrame:resume(wnd,event,...)\
  5554. local status=self:status()\
  5555. local result=false\
  5556. local success=false\
  5557. local yieldPoint;\
  5558. if status==\"modal\" then\
  5559. success,yieldPoint,result=\
  5560. coroutine.resume(self.appFrame__appRoutine,wnd,event,...)\
  5561. elseif status==\"event\" then\
  5562. success,yieldPoint,result=\
  5563. coroutine.resume(self.appFrame__appRoutine,event,...)\
  5564. elseif status==\"sleep\" then\
  5565. if event==\"sleep\" then\
  5566. success,yieldPoint,result=\
  5567. coroutine.resume(self.appFrame__appRoutine,event)\
  5568. end\
  5569. elseif status==\"dead\" then\
  5570. self:getDesktop():msgBox(\"Error\",\
  5571. self:getText()..\" was not responding.\",colors.red)\
  5572. self:getDesktop():dropApp(self)\
  5573. end\
  5574. if success then\
  5575. self.appFrame__yieldPoint=yieldPoint\
  5576. if yieldPoint==\"sleep\" then\
  5577. self:getWorkSpace():sleepApp(self,result)\
  5578. result=true\
  5579. elseif yieldPoint==\"event\" then\
  5580. result=true\
  5581. elseif yieldPoint~=\"modal\" then\
  5582. self.appFrame__yieldPoint=\"modal\"\
  5583. result=true\
  5584. end\
  5585. end\
  5586. return result\
  5587. end\
  5588. local lockScrnFrame=popupFrame:base()\
  5589. function lockScrnFrame:onCreate(password)\
  5590. self:setId(ID_LOCKSCRN)\
  5591. self:setColor(self:getColors().homeText)\
  5592. self:setBgColor(self:getColors().homeBack)\
  5593. self.title=labelWindow:new(self,0,0,0,\"Locked\")\
  5594. self.title:setColor(self:getColors().homeText)\
  5595. self.title:setBgColor(self:getColors().homeBack)\
  5596. self.password=inputWindow:new(self,ID_LOCKPW,0,0,8,\"\",\"Password\")\
  5597. self.password:setMaskChar(\"*\")\
  5598. self.ok=buttonWindow:new(self,ID_LOCKOK,0,0,\" Ok \")\
  5599. self.ls__password=password\
  5600. self.password:setFocus()\
  5601. self:onResize()\
  5602. return true\
  5603. end\
  5604. function lockScrnFrame:onResize()\
  5605. local rtWork=self:getDesktop():getWorkArea()\
  5606. local pwWidth=iif(rtWork.width<20,rtWork.width-2,20)\
  5607. local pwLeft=math.floor((rtWork.width-pwWidth)/2)\
  5608. local pwTop=math.floor(rtWork.height/2)\
  5609. self:move(rtWork:unpack())\
  5610. self.title:move(math.floor((rtWork.width-6)/2),pwTop-2)\
  5611. self.password:move(pwLeft,pwTop,pwWidth)\
  5612. self.ok:move(pwLeft+pwWidth-4,pwTop+2)\
  5613. return true\
  5614. end\
  5615. function lockScrnFrame:onFrameClose()\
  5616. return true\
  5617. end\
  5618. function lockScrnFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  5619. if event==\"btn_click\" then\
  5620. if p1:getId()==ID_LOCKOK then\
  5621. if self.password:getText()==self.ls__password then\
  5622. self:close(ID_LOCKOK)\
  5623. else\
  5624. self.password:setText(\"\")\
  5625. self.password:setError(true)\
  5626. self.password:invalidate()\
  5627. self.password:setFocus()\
  5628. end\
  5629. return true\
  5630. end\
  5631. end\
  5632. return false\
  5633. end\
  5634. function lockScrnFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  5635. if popupFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  5636. return true\
  5637. end\
  5638. if not ctrl and not alt and not shift then\
  5639. if key==keys.enter then\
  5640. self:sendEvent(\"btn_click\",self.ok)\
  5641. return true\
  5642. end\
  5643. end\
  5644. return false\
  5645. end\
  5646. function parentFrame:constructor(desktop,id,x,y,width,height)\
  5647. if not window.constructor(self,desktop,id,x,y,width,height)then\
  5648. return nil\
  5649. end\
  5650. self.pFrame__focusedWnd=nil\
  5651. self.pFrame__continueModal=false\
  5652. self.pFrame__modalResult=nil\
  5653. self:setWantFocus(false)\
  5654. self:setColor(self:getColors().frameText)\
  5655. self:setBgColor(self:getColors().frameBack)\
  5656. return self\
  5657. end\
  5658. function parentFrame:getOwner()\
  5659. if self.wnd__owner then\
  5660. return self.wnd__owner\
  5661. end\
  5662. return self\
  5663. end\
  5664. function parentFrame:getPopup()\
  5665. return self.wnd__popup\
  5666. end\
  5667. function parentFrame:getActiveFrame()\
  5668. local frame=self\
  5669. while frame:getPopup()do\
  5670. frame=frame:getPopup()\
  5671. end\
  5672. return frame\
  5673. end\
  5674. function parentFrame:setActiveTopFrame()\
  5675. if self:getDesktop():setActiveFrame(self)then\
  5676. if self:getPopup()then\
  5677. return self:getPopup():setActiveTopFrame()\
  5678. end\
  5679. return true\
  5680. end\
  5681. return false\
  5682. end\
  5683. function parentFrame:onFrameActivate(active)\
  5684. end\
  5685. function parentFrame:setFocusWnd(wnd)\
  5686. local desktop=self:getDesktop()\
  5687. if wnd then\
  5688. if not wnd:isEnabled()or not wnd:isShown()then\
  5689. return false\
  5690. end\
  5691. end\
  5692. if desktop then\
  5693. if desktop:getActiveFrame()~=self then\
  5694. local focusWnd=wnd\
  5695. if not focusWnd then\
  5696. focusWnd=self:nextWnd(nil,true)\
  5697. end\
  5698. self.pFrame__focusedWnd=focusWnd\
  5699. return true\
  5700. else\
  5701. local focusWnd=wnd\
  5702. if not focusWnd then\
  5703. if self.pFrame__focusedWnd then\
  5704. focusWnd=self:priorWnd(self.pFrame__focusedWnd,true)\
  5705. if focusWnd==self.pFrame__focusedWnd then\
  5706. focusWnd=nil\
  5707. end\
  5708. else\
  5709. focusWnd=self:nextWnd(nil,true)\
  5710. end\
  5711. end\
  5712. if self.pFrame__focusedWnd then\
  5713. if not self:routeEvent(self.pFrame__focusedWnd,\"blur\",focusWnd)then\
  5714. self.pFrame__focusedWnd:sendEvent(\"blur\",focusWnd)\
  5715. end\
  5716. self.pFrame__focusedWnd:invalidate()\
  5717. end\
  5718. if focusWnd then\
  5719. if not self:routeEvent(focusWnd,\"focus\",self.pFrame__focusedWnd)then\
  5720. focusWnd:sendEvent(\"focus\",self.pFrame__focusedWnd)\
  5721. end\
  5722. focusWnd:invalidate()\
  5723. end\
  5724. self.pFrame__focusedWnd=focusWnd\
  5725. return true\
  5726. end\
  5727. end\
  5728. return false\
  5729. end\
  5730. function parentFrame:nextWnd(wnd,focusable)\
  5731. for i=self:childIndex(wnd)+1,self:children(),1 do\
  5732. local nextWnd=self:getChild(i)\
  5733. if nextWnd then\
  5734. if(nextWnd:getWantFocus()and nextWnd:isShown()\
  5735. and nextWnd:isEnabled())\
  5736. or(not focusable)then\
  5737. return nextWnd\
  5738. end\
  5739. end\
  5740. end\
  5741. for i=1,self:children(),1 do\
  5742. local nextWnd=self:getChild(i)\
  5743. if nextWnd then\
  5744. if(nextWnd:getWantFocus()and nextWnd:isShown()\
  5745. and nextWnd:isEnabled())\
  5746. or(not focusable)then\
  5747. return nextWnd\
  5748. end\
  5749. end\
  5750. end\
  5751. return nil\
  5752. end\
  5753. function parentFrame:priorWnd(wnd,focusable)\
  5754. for i=self:childIndex(wnd)-1,1,-1 do\
  5755. local nextWnd=self:getChild(i)\
  5756. if nextWnd then\
  5757. if(nextWnd:getWantFocus()and nextWnd:isShown()\
  5758. and nextWnd:isEnabled())\
  5759. or(not focusable)then\
  5760. return nextWnd\
  5761. end\
  5762. end\
  5763. end\
  5764. for i=self:children(),1,-1 do\
  5765. local nextWnd=self:getChild(i)\
  5766. if nextWnd then\
  5767. if(nextWnd:getWantFocus()and nextWnd:isShown()\
  5768. and nextWnd:isEnabled())\
  5769. or(not focusable)then\
  5770. return nextWnd\
  5771. end\
  5772. end\
  5773. end\
  5774. return nil\
  5775. end\
  5776. function parentFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  5777. if not alt and not ctrl then\
  5778. if shift then\
  5779. if key==keys.tab then\
  5780. local nextWnd=self:priorWnd(self.pFrame__focusedWnd,true)\
  5781. if nextWnd and nextWnd~=self.pFrame__focusedWnd then\
  5782. nextWnd:setFocus()\
  5783. end\
  5784. return true\
  5785. end\
  5786. else\
  5787. if key==keys.tab then\
  5788. local nextWnd=self:nextWnd(self.pFrame__focusedWnd,true)\
  5789. if nextWnd and nextWnd~=self.pFrame__focusedWnd then\
  5790. nextWnd:setFocus()\
  5791. end\
  5792. return true\
  5793. end\
  5794. end\
  5795. end\
  5796. return false\
  5797. end\
  5798. function parentFrame:msgBox(titleText,message,bgColor)\
  5799. local msgbox=msgBoxFrame:new(self)\
  5800. if asnumber(bgColor)~=0 then\
  5801. msgbox:setBgColor(bgColor)\
  5802. end\
  5803. msgbox:doModal(titleText,message)\
  5804. end\
  5805. function parentFrame:systemMsgBox(titleText,message,bgColor)\
  5806. local msgbox=msgBoxFrame:new(self)\
  5807. if asnumber(bgColor)~=0 then\
  5808. msgbox:setBgColor(bgColor)\
  5809. end\
  5810. local enabled=self:getDesktop().dt__taskBar:isEnabled()\
  5811. self:getDesktop().dt__taskBar:enable(false)\
  5812. msgbox:doModal(titleText,message)\
  5813. self:getDesktop().dt__taskBar:enable(enabled)\
  5814. end\
  5815. function parentFrame:lockScreen()\
  5816. local password=getPassword()\
  5817. if password:len()>0 then\
  5818. self:getDesktop():dismissKeyboard()\
  5819. local enabled=self:getDesktop().dt__taskBar:isEnabled()\
  5820. self:getDesktop().dt__taskBar:enable(false)\
  5821. lockScrnFrame:new(self):doModal(password)\
  5822. self:getDesktop().dt__taskBar:enable(enabled)\
  5823. end\
  5824. end\
  5825. function parentFrame:runModal()\
  5826. local lastResult=true\
  5827. self.pFrame__continueModal=true\
  5828. while self.pFrame__continueModal do\
  5829. local event={coroutine.yield(\"modal\",lastResult)}\
  5830. lastResult=true\
  5831. if event[2]==\"system_msgbox\" then\
  5832. self:systemMsgBox(event[4],event[5],event[6])\
  5833. elseif event[2]==\"lock_screen\" then\
  5834. self:lockScreen()\
  5835. elseif event[1]then\
  5836. local frame=event[1]:getParentFrame()\
  5837. if frame and(event[1]~=frame)then\
  5838. if frame:routeEvent(unpack(event))then\
  5839. event[1]=nil\
  5840. end\
  5841. end\
  5842. if event[1]then\
  5843. lastResult=event[1]:routeEvent(unpack(event))\
  5844. end\
  5845. else\
  5846. lastResult=false\
  5847. end\
  5848. end\
  5849. return self.pFrame__modalResult\
  5850. end\
  5851. function parentFrame:endModal(result)\
  5852. self.pFrame__modalResult=result\
  5853. self.pFrame__continueModal=false\
  5854. end\
  5855. function parentFrame:createPopup(width,height)\
  5856. if self.wnd__popup then\
  5857. return nil\
  5858. end\
  5859. return popupFrame:new(self,width,height)\
  5860. end\
  5861. local taskBarFrame=applicationFrame:base()\
  5862. function taskBarFrame:constructor(side)\
  5863. if not applicationFrame.constructor(self,side)then\
  5864. return nil\
  5865. end\
  5866. local width,height=self:getDesktop().gdi:getSize()\
  5867. self.wnd__id=ID_TASKBAR\
  5868. self.wnd__frameClass=FRAME_CLASS_SYSTEM\
  5869. self:setWantFocus(false)\
  5870. self:setBgColor(0)\
  5871. self:move(0,height-1,width,1,WND_TOP)\
  5872. return self\
  5873. end\
  5874. function taskBarFrame:draw(gdi,bounds)\
  5875. local minWidth=iif(self:commEnabled(),18,15)\
  5876. if self.width>minWidth then\
  5877. barText=string.format(\"[H] [L]%s%s%s\",\
  5878. string.rep(\" \",self.width-minWidth),\
  5879. iif(self:commEnabled(),\" @ \",\"\"),\
  5880. textutils.formatTime(os.time(),false,8))\
  5881. else\
  5882. barText=string.format(\"[H] [L]%s%s\",\
  5883. iif(self:commEnabled(),\" @ \",\"\"),\
  5884. textutils.formatTime(os.time(),false,8))\
  5885. end\
  5886. gdi:setTextColor(self:getColors().taskText)\
  5887. gdi:setBackgroundColor(self:getColors().taskBack)\
  5888. gdi:write(barText,0,0)\
  5889. end\
  5890. function taskBarFrame:onLeftClick(x,y)\
  5891. if x>=0 and x<3 then\
  5892. self:getDesktop():showHomePage()\
  5893. elseif x>=4 and x<7 then\
  5894. self:getDesktop():showListPage()\
  5895. elseif self.width>iif(self:commEnabled(),18,15)and x>=(self.width-8)then\
  5896. self:getDesktop():msgBox(\"Today\",\"Day: \"..tostring(os.day()))\
  5897. end\
  5898. return true\
  5899. end\
  5900. function taskBarFrame:onTouch(x,y)\
  5901. if x>=0 and x<3 then\
  5902. self:getDesktop():showHomePage()\
  5903. elseif x>=4 and x<7 then\
  5904. self:getDesktop():showListPage()\
  5905. elseif self.width>iif(self:commEnabled(),18,15)and x>=(self.width-8)then\
  5906. self:getDesktop():msgBox(\"Today\",\"Day: \"..tostring(os.day()))\
  5907. end\
  5908. return true\
  5909. end\
  5910. function taskBarFrame:onResize()\
  5911. local width,height=self:getDesktop().gdi:getSize()\
  5912. self:move(0,height-1,width,1)\
  5913. return true\
  5914. end\
  5915. function taskBarFrame:onIdle(idleCount)\
  5916. if self:getDesktop():getTaskBarIndex()==1 and self:isShown()then\
  5917. if self.width>iif(self:commEnabled(),17,14)then\
  5918. local strTime=textutils.formatTime(os.time(),false,8)\
  5919. local gdi=self:getGDI()\
  5920. gdi:setTextColor(self:getColors().taskText)\
  5921. gdi:setBackgroundColor(self:getColors().taskBack)\
  5922. gdi:write(strTime,(self.width-8),0)\
  5923. self:releaseGDI()\
  5924. end\
  5925. end\
  5926. return false\
  5927. end\
  5928. function taskBarFrame:onQuit()\
  5929. return true\
  5930. end\
  5931. local homePageFrame=applicationFrame:base()\
  5932. function homePageFrame:constructor(side,title)\
  5933. if not applicationFrame.constructor(self,side)then\
  5934. return nil\
  5935. end\
  5936. local rt=self:getDesktop():getWorkArea()\
  5937. self.wnd__id=ID_MENUFRAME\
  5938. self.wnd__frameClass=FRAME_CLASS_SYSTEM\
  5939. self:setColor(self:getColors().homeText)\
  5940. self:setBgColor(self:getColors().homeBack)\
  5941. title=asstring(title)\
  5942. if title:len()<1 then\
  5943. title=asstring(os.getComputerLabel())\
  5944. if title:len()<1 then\
  5945. title=\"Home\"\
  5946. end\
  5947. end\
  5948. self.title=labelWindow:new(self,0,math.floor((rt.width-title:len())/2),\
  5949. 1,title)\
  5950. self.title:setColor(self:getColors().homeText)\
  5951. self.title:setBgColor(self:getColors().homeBack)\
  5952. self.list=listWindow:new(self,ID_MENULIST,2,3,rt.width-4,\
  5953. rt.height-4)\
  5954. self.list:setColors(self:getColors().homeItemText,\
  5955. self:getColors().homeItemBack,\
  5956. self:getColors().homeItemBack,\
  5957. self:getColors().homeItemSelectedText,\
  5958. self:getColors().homeItemSelectedBack)\
  5959. self.lockBtn=buttonWindow:new(self,ID_HOMELOCK,rt.width-4,\
  5960. rt.height-1,\"lock\")\
  5961. self.lockBtn:setColors(self:getColors().homeText,\
  5962. self:getColors().homeBack,\
  5963. self:getColors().scrollBack)\
  5964. self.lockBtn:show(getPassword():len()>0)\
  5965. self.pFrame__focusedWnd=self.list\
  5966. return self\
  5967. end\
  5968. function homePageFrame:loadList()\
  5969. self.list:resetContent()\
  5970. local lines={}\
  5971. local line,lastLine;\
  5972. local hFile=fs.open(\"/win/\"..self:getDesktop():getSide()..\
  5973. \"/desktop.ini\",\"r\")\
  5974. if hFile then\
  5975. line=hFile.readLine()\
  5976. while line do\
  5977. lines[#lines+1]=line\
  5978. line=hFile.readLine()\
  5979. end\
  5980. hFile.close()\
  5981. lastLine=math.floor(#lines/5)*5\
  5982. for line=1,lastLine,5 do\
  5983. local app={\
  5984. name=lines[line],\
  5985. path=lines[line+1],\
  5986. arguments=lines[line+2],\
  5987. dummy1=lines[line+3],\
  5988. dummy2=lines[line+4]\
  5989. }\
  5990. self.list:addString(app.name,app)\
  5991. end\
  5992. end\
  5993. if self.list:count()>0 then\
  5994. self.list:setCurSel(1)\
  5995. end\
  5996. end\
  5997. function homePageFrame:onResize()\
  5998. local rt=self:getDesktop():getWorkArea()\
  5999. self:move(rt:unpack())\
  6000. self.title:move(math.floor((rt.width-self.title:getText():len())/2))\
  6001. self.lockBtn:move(rt.width-4,rt.height-1)\
  6002. self.list:move(2,3,rt.width-4,rt.height-4)\
  6003. return true\
  6004. end\
  6005. function homePageFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  6006. if event==\"list_click\" then\
  6007. if p1:getId()==ID_MENULIST then\
  6008. local app=self.list:getData()\
  6009. if app then\
  6010. self:getDesktop():runApp(app.path,app.arguments)\
  6011. end\
  6012. return true\
  6013. end\
  6014. elseif event==\"btn_click\" then\
  6015. if p1:getId()==ID_HOMELOCK then\
  6016. self:getDesktop():lockScreen()\
  6017. return true\
  6018. end\
  6019. end\
  6020. return false\
  6021. end\
  6022. function homePageFrame:onQuit()\
  6023. return true\
  6024. end\
  6025. function homePageFrame:onFrameActivate(active)\
  6026. if active then\
  6027. self:loadList()\
  6028. self.list:setFocus()\
  6029. self.lockBtn:show(getPassword():len()>0)\
  6030. end\
  6031. end\
  6032. local appListFrame=applicationFrame:base()\
  6033. function appListFrame:constructor(side)\
  6034. if not applicationFrame.constructor(self,side)then\
  6035. return nil\
  6036. end\
  6037. local rt=self:getDesktop():getWorkArea()\
  6038. self.wnd__id=ID_APPFRAME\
  6039. self.wnd__frameClass=FRAME_CLASS_SYSTEM\
  6040. self:setColor(self:getColors().homeText)\
  6041. self:setBgColor(self:getColors().homeBack)\
  6042. self.title=labelWindow:new(self,0,math.floor((rt.width-4)/2),1,\"List\")\
  6043. self.title:setColor(self:getColors().homeText)\
  6044. self.title:setBgColor(self:getColors().homeBack)\
  6045. self.list=listWindow:new(self,ID_APPLIST,2,3,rt.width-4,rt.height-4)\
  6046. self.list:setColors(self:getColors().homeItemText,\
  6047. self:getColors().homeItemBack,\
  6048. self:getColors().homeItemBack,\
  6049. self:getColors().homeItemSelectedText,\
  6050. self:getColors().homeItemSelectedBack)\
  6051. self.pFrame__focusedWnd=self.list\
  6052. return self\
  6053. end\
  6054. function appListFrame:loadList()\
  6055. self.list:resetContent()\
  6056. local iterator,app=self:getDesktop():enumApps()\
  6057. while app do\
  6058. self.list:addString(app:getText(),app)\
  6059. iterator,app=self:getDesktop():enumApps(iterator)\
  6060. end\
  6061. if self.list:count()>0 then\
  6062. self.list:setCurSel(1)\
  6063. end\
  6064. end\
  6065. function appListFrame:onResize()\
  6066. local rt=self:getDesktop():getWorkArea()\
  6067. self:move(rt:unpack())\
  6068. self.title:move(math.floor((rt.width-4)/2))\
  6069. self.list:move(2,3,rt.width-4,rt.height-4)\
  6070. return true\
  6071. end\
  6072. function appListFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  6073. if event==\"list_click\" then\
  6074. if p1:getId()==ID_APPLIST then\
  6075. local app=self.list:getData()\
  6076. if app then\
  6077. app:setActiveTopFrame()\
  6078. end\
  6079. return true\
  6080. end\
  6081. end\
  6082. return false\
  6083. end\
  6084. function appListFrame:onQuit()\
  6085. return true\
  6086. end\
  6087. function appListFrame:onFrameActivate(active)\
  6088. if active then\
  6089. self:loadList()\
  6090. end\
  6091. end\
  6092. local function kbKeydef(charEvent,code,char,shiftChar,capsChar,shiftCapsChar,colorFunc)\
  6093. return{\
  6094. charEvent=charEvent,\
  6095. code=code,\
  6096. char=char,\
  6097. shiftChar=shiftChar,\
  6098. capsChar=capsChar,\
  6099. shiftCapsChar=shiftCapsChar,\
  6100. color=colorFunc\
  6101. }\
  6102. end\
  6103. local keyboardFrame=applicationFrame:base()\
  6104. function keyboardFrame:constructor(side,targetWnd)\
  6105. if not applicationFrame.constructor(self,side)then\
  6106. return nil\
  6107. end\
  6108. self.wnd__id=ID_KEYBOARD\
  6109. self.wnd__frameClass=FRAME_CLASS_SYSTEM\
  6110. self.keyTextColor=self:getColors().kbText\
  6111. self.kbBgColor=self:getColors().kbBack\
  6112. self.stdColor=self:getColors().kbKey\
  6113. self.cmdColor=self:getColors().kbCmd\
  6114. self.cancelColor=self:getColors().kbCancel\
  6115. self.toggleColor=self:getColors().kbToggle\
  6116. self.capsState=false\
  6117. self.shiftState=false\
  6118. self.ctrlState=false\
  6119. self.altState=false\
  6120. self.keysLeft=0\
  6121. self.keysTop=0\
  6122. self.targetWnd=targetWnd\
  6123. self.targetParent=nil\
  6124. self.targetRect=nil\
  6125. self.targetZ=nil\
  6126. if targetWnd then\
  6127. self.targetWnd=targetWnd\
  6128. self.targetParent=targetWnd:getParent()\
  6129. self.targetRect=targetWnd:getWndRect()\
  6130. if targetWnd:getParent()then\
  6131. self.targetZ=targetWnd:getParent():childIndex(targetWnd)\
  6132. end\
  6133. self.targetWnd:setParent(self)\
  6134. end\
  6135. self:setColor(self.kbTextColor)\
  6136. self:setBgColor(self.kbBgColor)\
  6137. self.mapFull={\
  6138. {\
  6139. kbKeydef(false,300,\"x\",\"x\",\"x\",\"x\",self.cancelKeyColor),\
  6140. kbKeydef(true,41,\"~\",\"~\",\"~\",\"~\",self.stdKeyColor),\
  6141. kbKeydef(true,2,\"1\",\"!\",\"1\",\"!\",self.stdKeyColor),\
  6142. kbKeydef(true,3,\"2\",\"@\",\"2\",\"@\",self.stdKeyColor),\
  6143. kbKeydef(true,4,\"3\",\"#\",\"3\",\"#\",self.stdKeyColor),\
  6144. kbKeydef(true,5,\"4\",\"$\",\"4\",\"$\",self.stdKeyColor),\
  6145. kbKeydef(true,6,\"5\",\"%\",\"5\",\"%\",self.stdKeyColor),\
  6146. kbKeydef(true,7,\"6\",\"^\",\"6\",\"^\",self.stdKeyColor),\
  6147. kbKeydef(true,8,\"7\",\"&\",\"7\",\"&\",self.stdKeyColor),\
  6148. kbKeydef(true,9,\"8\",\"*\",\"8\",\"*\",self.stdKeyColor),\
  6149. kbKeydef(true,10,\"9\",\"(\",\"9\",\"(\",self.stdKeyColor),\
  6150. kbKeydef(true,11,\"0\",\")\",\"0\",\")\",self.stdKeyColor),\
  6151. kbKeydef(true,12,\"-\",\"_\",\"-\",\"_\",self.stdKeyColor),\
  6152. kbKeydef(true,13,\"=\",\"+\",\"=\",\"+\",self.stdKeyColor),\
  6153. kbKeydef(false,14,\"b\",\"b\",\"b\",\"b\",self.cmdKeyColor),\
  6154. kbKeydef(false,14,\"s\",\"s\",\"s\",\"s\",self.cmdKeyColor),\
  6155. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6156. kbKeydef(false,210,\"I\",\"I\",\"I\",\"I\",self.cmdKeyColor),\
  6157. kbKeydef(false,199,\"H\",\"H\",\"H\",\"H\",self.cmdKeyColor),\
  6158. kbKeydef(false,201,\"P\",\"P\",\"P\",\"P\",self.cmdKeyColor)\
  6159. },\
  6160. {\
  6161. kbKeydef(false,15,\"t\",\"t\",\"t\",\"t\",self.cmdKeyColor),\
  6162. kbKeydef(false,15,\"b\",\"b\",\"b\",\"b\",self.cmdKeyColor),\
  6163. kbKeydef(true,16,\"q\",\"Q\",\"Q\",\"q\",self.stdKeyColor),\
  6164. kbKeydef(true,17,\"w\",\"W\",\"W\",\"w\",self.stdKeyColor),\
  6165. kbKeydef(true,18,\"e\",\"E\",\"E\",\"e\",self.stdKeyColor),\
  6166. kbKeydef(true,19,\"r\",\"R\",\"R\",\"r\",self.stdKeyColor),\
  6167. kbKeydef(true,20,\"t\",\"T\",\"T\",\"t\",self.stdKeyColor),\
  6168. kbKeydef(true,21,\"y\",\"Y\",\"Y\",\"y\",self.stdKeyColor),\
  6169. kbKeydef(true,22,\"u\",\"U\",\"U\",\"u\",self.stdKeyColor),\
  6170. kbKeydef(true,23,\"i\",\"I\",\"I\",\"i\",self.stdKeyColor),\
  6171. kbKeydef(true,24,\"o\",\"O\",\"O\",\"o\",self.stdKeyColor),\
  6172. kbKeydef(true,25,\"p\",\"P\",\"P\",\"p\",self.stdKeyColor),\
  6173. kbKeydef(true,26,\"[\",\"{\",\"[\",\"{\",self.stdKeyColor),\
  6174. kbKeydef(true,27,\"]\",\"}\",\"]\",\"}\",self.stdKeyColor),\
  6175. kbKeydef(true,43,\"\\\\\",\"|\",\"\\\\\",\"|\",self.stdKeyColor),\
  6176. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6177. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6178. kbKeydef(false,211,\"D\",\"D\",\"D\",\"D\",self.cmdKeyColor),\
  6179. kbKeydef(false,207,\"E\",\"E\",\"E\",\"E\",self.cmdKeyColor),\
  6180. kbKeydef(false,209,\"N\",\"N\",\"N\",\"N\",self.cmdKeyColor)\
  6181. },\
  6182. {\
  6183. kbKeydef(false,58,\"c\",\"c\",\"c\",\"c\",self.capsKeyColor),\
  6184. kbKeydef(false,58,\"l\",\"l\",\"l\",\"l\",self.capsKeyColor),\
  6185. kbKeydef(true,30,\"a\",\"A\",\"A\",\"a\",self.stdKeyColor),\
  6186. kbKeydef(true,31,\"s\",\"S\",\"S\",\"s\",self.stdKeyColor),\
  6187. kbKeydef(true,32,\"d\",\"D\",\"D\",\"d\",self.stdKeyColor),\
  6188. kbKeydef(true,33,\"f\",\"F\",\"F\",\"f\",self.stdKeyColor),\
  6189. kbKeydef(true,34,\"g\",\"G\",\"G\",\"g\",self.stdKeyColor),\
  6190. kbKeydef(true,35,\"h\",\"H\",\"H\",\"h\",self.stdKeyColor),\
  6191. kbKeydef(true,36,\"j\",\"J\",\"J\",\"j\",self.stdKeyColor),\
  6192. kbKeydef(true,37,\"k\",\"K\",\"K\",\"k\",self.stdKeyColor),\
  6193. kbKeydef(true,38,\"l\",\"L\",\"L\",\"l\",self.stdKeyColor),\
  6194. kbKeydef(true,39,\";\",\":\",\";\",\":\",self.stdKeyColor),\
  6195. kbKeydef(true,40,\"'\",\"\\\"\",\"'\",\"\\\"\",self.stdKeyColor),\
  6196. kbKeydef(false,28,\"e\",\"e\",\"e\",\"e\",self.cmdKeyColor),\
  6197. kbKeydef(false,28,\"n\",\"n\",\"n\",\"n\",self.cmdKeyColor),\
  6198. kbKeydef(false,28,\"t\",\"t\",\"t\",\"t\",self.cmdKeyColor),\
  6199. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6200. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6201. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6202. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6203. },\
  6204. {\
  6205. kbKeydef(false,42,\"s\",\"s\",\"s\",\"s\",self.shiftKeyColor),\
  6206. kbKeydef(false,42,\"f\",\"f\",\"f\",\"f\",self.shiftKeyColor),\
  6207. kbKeydef(false,42,\"t\",\"t\",\"t\",\"t\",self.shiftKeyColor),\
  6208. kbKeydef(true,44,\"z\",\"Z\",\"Z\",\"z\",self.stdKeyColor),\
  6209. kbKeydef(true,45,\"x\",\"X\",\"X\",\"x\",self.stdKeyColor),\
  6210. kbKeydef(true,46,\"c\",\"C\",\"C\",\"c\",self.stdKeyColor),\
  6211. kbKeydef(true,47,\"v\",\"V\",\"V\",\"v\",self.stdKeyColor),\
  6212. kbKeydef(true,48,\"b\",\"B\",\"B\",\"b\",self.stdKeyColor),\
  6213. kbKeydef(true,49,\"n\",\"N\",\"N\",\"n\",self.stdKeyColor),\
  6214. kbKeydef(true,50,\"m\",\"M\",\"M\",\"m\",self.stdKeyColor),\
  6215. kbKeydef(true,51,\",\",\"<\",\",\",\"<\",self.stdKeyColor),\
  6216. kbKeydef(true,52,\".\",\">\",\".\",\">\",self.stdKeyColor),\
  6217. kbKeydef(true,53,\"/\",\"?\",\"/\",\"?\",self.stdKeyColor),\
  6218. kbKeydef(false,42,\"s\",\"s\",\"s\",\"s\",self.shiftKeyColor),\
  6219. kbKeydef(false,42,\"f\",\"f\",\"f\",\"f\",self.shiftKeyColor),\
  6220. kbKeydef(false,42,\"t\",\"t\",\"t\",\"t\",self.shiftKeyColor),\
  6221. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6222. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6223. kbKeydef(false,200,\"^\",\"^\",\"^\",\"^\",self.cmdKeyColor),\
  6224. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor)\
  6225. },\
  6226. {\
  6227. kbKeydef(false,29,\"c\",\"c\",\"c\",\"c\",self.ctrlKeyColor),\
  6228. kbKeydef(false,29,\"t\",\"t\",\"t\",\"t\",self.ctrlKeyColor),\
  6229. kbKeydef(false,29,\"l\",\"l\",\"l\",\"l\",self.ctrlKeyColor),\
  6230. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6231. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6232. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6233. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6234. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6235. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6236. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6237. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6238. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6239. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6240. kbKeydef(false,56,\"a\",\"a\",\"a\",\"a\",self.altKeyColor),\
  6241. kbKeydef(false,56,\"l\",\"l\",\"l\",\"l\",self.altKeyColor),\
  6242. kbKeydef(false,56,\"t\",\"t\",\"t\",\"t\",self.altKeyColor),\
  6243. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6244. kbKeydef(false,203,\"<\",\"<\",\"<\",\"<\",self.cmdKeyColor),\
  6245. kbKeydef(false,208,\"v\",\"v\",\"v\",\"v\",self.cmdKeyColor),\
  6246. kbKeydef(false,205,\">\",\">\",\">\",\">\",self.cmdKeyColor)\
  6247. }\
  6248. }\
  6249. self.mapBrief={\
  6250. {\
  6251. kbKeydef(true,41,\"~\",\"~\",\"~\",\"~\",self.stdKeyColor),\
  6252. kbKeydef(true,2,\"1\",\"!\",\"1\",\"!\",self.stdKeyColor),\
  6253. kbKeydef(true,3,\"2\",\"@\",\"2\",\"@\",self.stdKeyColor),\
  6254. kbKeydef(true,4,\"3\",\"#\",\"3\",\"#\",self.stdKeyColor),\
  6255. kbKeydef(true,5,\"4\",\"$\",\"4\",\"$\",self.stdKeyColor),\
  6256. kbKeydef(true,6,\"5\",\"%\",\"5\",\"%\",self.stdKeyColor),\
  6257. kbKeydef(true,7,\"6\",\"^\",\"6\",\"^\",self.stdKeyColor),\
  6258. kbKeydef(true,8,\"7\",\"&\",\"7\",\"&\",self.stdKeyColor),\
  6259. kbKeydef(true,9,\"8\",\"*\",\"8\",\"*\",self.stdKeyColor),\
  6260. kbKeydef(true,10,\"9\",\"(\",\"9\",\"(\",self.stdKeyColor),\
  6261. kbKeydef(true,11,\"0\",\")\",\"0\",\")\",self.stdKeyColor),\
  6262. kbKeydef(true,12,\"-\",\"_\",\"-\",\"_\",self.stdKeyColor),\
  6263. kbKeydef(true,13,\"=\",\"+\",\"=\",\"+\",self.stdKeyColor),\
  6264. kbKeydef(false,14,\"b\",\"b\",\"b\",\"b\",self.cmdKeyColor),\
  6265. kbKeydef(false,14,\"s\",\"s\",\"s\",\"s\",self.cmdKeyColor)\
  6266. },\
  6267. {\
  6268. kbKeydef(false,300,\"x\",\"x\",\"x\",\"x\",self.cancelKeyColor),\
  6269. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6270. kbKeydef(true,16,\"q\",\"Q\",\"Q\",\"q\",self.stdKeyColor),\
  6271. kbKeydef(true,17,\"w\",\"W\",\"W\",\"w\",self.stdKeyColor),\
  6272. kbKeydef(true,18,\"e\",\"E\",\"E\",\"e\",self.stdKeyColor),\
  6273. kbKeydef(true,19,\"r\",\"R\",\"R\",\"r\",self.stdKeyColor),\
  6274. kbKeydef(true,20,\"t\",\"T\",\"T\",\"t\",self.stdKeyColor),\
  6275. kbKeydef(true,21,\"y\",\"Y\",\"Y\",\"y\",self.stdKeyColor),\
  6276. kbKeydef(true,22,\"u\",\"U\",\"U\",\"u\",self.stdKeyColor),\
  6277. kbKeydef(true,23,\"i\",\"I\",\"I\",\"i\",self.stdKeyColor),\
  6278. kbKeydef(true,24,\"o\",\"O\",\"O\",\"o\",self.stdKeyColor),\
  6279. kbKeydef(true,25,\"p\",\"P\",\"P\",\"p\",self.stdKeyColor),\
  6280. kbKeydef(true,26,\"[\",\"{\",\"[\",\"{\",self.stdKeyColor),\
  6281. kbKeydef(true,27,\"]\",\"}\",\"]\",\"}\",self.stdKeyColor),\
  6282. kbKeydef(true,43,\"\\\\\",\"|\",\"\\\\\",\"|\",self.stdKeyColor)\
  6283. },\
  6284. {\
  6285. kbKeydef(false,58,\"c\",\"c\",\"c\",\"c\",self.capsKeyColor),\
  6286. kbKeydef(false,58,\"l\",\"l\",\"l\",\"l\",self.capsKeyColor),\
  6287. kbKeydef(true,30,\"a\",\"A\",\"A\",\"a\",self.stdKeyColor),\
  6288. kbKeydef(true,31,\"s\",\"S\",\"S\",\"s\",self.stdKeyColor),\
  6289. kbKeydef(true,32,\"d\",\"D\",\"D\",\"d\",self.stdKeyColor),\
  6290. kbKeydef(true,33,\"f\",\"F\",\"F\",\"f\",self.stdKeyColor),\
  6291. kbKeydef(true,34,\"g\",\"G\",\"G\",\"g\",self.stdKeyColor),\
  6292. kbKeydef(true,35,\"h\",\"H\",\"H\",\"h\",self.stdKeyColor),\
  6293. kbKeydef(true,36,\"j\",\"J\",\"J\",\"j\",self.stdKeyColor),\
  6294. kbKeydef(true,37,\"k\",\"K\",\"K\",\"k\",self.stdKeyColor),\
  6295. kbKeydef(true,38,\"l\",\"L\",\"L\",\"l\",self.stdKeyColor),\
  6296. kbKeydef(true,39,\";\",\":\",\";\",\":\",self.stdKeyColor),\
  6297. kbKeydef(true,40,\"'\",\"\\\"\",\"'\",\"\\\"\",self.stdKeyColor),\
  6298. kbKeydef(false,28,\"e\",\"e\",\"e\",\"e\",self.cmdKeyColor),\
  6299. kbKeydef(false,28,\"n\",\"n\",\"n\",\"n\",self.cmdKeyColor)\
  6300. },\
  6301. {\
  6302. kbKeydef(false,42,\"s\",\"s\",\"s\",\"s\",self.shiftKeyColor),\
  6303. kbKeydef(false,42,\"h\",\"h\",\"h\",\"h\",self.shiftKeyColor),\
  6304. kbKeydef(true,44,\"z\",\"Z\",\"Z\",\"z\",self.stdKeyColor),\
  6305. kbKeydef(true,45,\"x\",\"X\",\"X\",\"x\",self.stdKeyColor),\
  6306. kbKeydef(true,46,\"c\",\"C\",\"C\",\"c\",self.stdKeyColor),\
  6307. kbKeydef(true,47,\"v\",\"V\",\"V\",\"v\",self.stdKeyColor),\
  6308. kbKeydef(true,48,\"b\",\"B\",\"B\",\"b\",self.stdKeyColor),\
  6309. kbKeydef(true,49,\"n\",\"N\",\"N\",\"n\",self.stdKeyColor),\
  6310. kbKeydef(true,50,\"m\",\"M\",\"M\",\"m\",self.stdKeyColor),\
  6311. kbKeydef(true,51,\",\",\"<\",\",\",\"<\",self.stdKeyColor),\
  6312. kbKeydef(true,52,\".\",\">\",\".\",\">\",self.stdKeyColor),\
  6313. kbKeydef(true,53,\"/\",\"?\",\"/\",\"?\",self.stdKeyColor),\
  6314. kbKeydef(false,0,\" \",\" \",\" \",\" \",self.noKeyColor),\
  6315. kbKeydef(false,42,\"s\",\"s\",\"s\",\"s\",self.shiftKeyColor),\
  6316. kbKeydef(false,42,\"h\",\"h\",\"h\",\"h\",self.shiftKeyColor)\
  6317. },\
  6318. {\
  6319. kbKeydef(false,0,\"[\",\"[\",\"[\",\"[\",self.noKeyColor),\
  6320. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6321. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6322. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6323. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6324. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6325. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6326. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6327. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6328. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6329. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6330. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6331. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6332. kbKeydef(true,57,\" \",\" \",\" \",\" \",self.stdKeyColor),\
  6333. kbKeydef(false,0,\"]\",\"]\",\"]\",\"]\",self.noKeyColor)\
  6334. }\
  6335. }\
  6336. self.keyMap=self.mapFull\
  6337. if self:getDesktop()then\
  6338. self:onResize()\
  6339. end\
  6340. if targetWnd then\
  6341. self.targetWnd:setFocus()\
  6342. end\
  6343. return self\
  6344. end\
  6345. function keyboardFrame:stdKeyColor()\
  6346. return self.stdColor\
  6347. end\
  6348. function keyboardFrame:noKeyColor()\
  6349. return self.kbBgColor\
  6350. end\
  6351. function keyboardFrame:cmdKeyColor()\
  6352. return self.cmdColor\
  6353. end\
  6354. function keyboardFrame:cancelKeyColor()\
  6355. return self.cancelColor\
  6356. end\
  6357. function keyboardFrame:ctrlKeyColor()\
  6358. if self.ctrlState then\
  6359. return self.toggleColor\
  6360. end\
  6361. return self.cmdColor\
  6362. end\
  6363. function keyboardFrame:shiftKeyColor()\
  6364. if self.shiftState then\
  6365. return self.toggleColor\
  6366. end\
  6367. return self.cmdColor\
  6368. end\
  6369. function keyboardFrame:capsKeyColor()\
  6370. if self.capsState then\
  6371. return self.toggleColor\
  6372. end\
  6373. return self.cmdColor\
  6374. end\
  6375. function keyboardFrame:altKeyColor()\
  6376. if self.altState then\
  6377. return self.toggleColor\
  6378. end\
  6379. return self.cmdColor\
  6380. end\
  6381. function keyboardFrame:getKeyDef(x,y)\
  6382. local cx,cy=x-self.keysLeft+1,y-self.keysTop+1\
  6383. if cy>0 and cy<=table.maxn(self.keyMap)and\
  6384. cx>0 and cx<=table.maxn(self.keyMap[1])then\
  6385. return self.keyMap[cy][cx]\
  6386. end\
  6387. return nil\
  6388. end\
  6389. function keyboardFrame:dismiss()\
  6390. self:endModal(0)\
  6391. end\
  6392. function keyboardFrame:draw(gdi,bounds)\
  6393. gdi:setTextColor(self.keyTextColor)\
  6394. for y=1,table.maxn(self.keyMap),1 do\
  6395. for x=1,table.maxn(self.keyMap[y]),1 do\
  6396. local kd=self.keyMap[y][x]\
  6397. gdi:setBackgroundColor(kd.color(self))\
  6398. if self.capsState then\
  6399. if self.shiftState then\
  6400. gdi:write(kd.shiftCapsChar,self.keysLeft+x-1,self.keysTop+y-1)\
  6401. else\
  6402. gdi:write(kd.capsChar,self.keysLeft+x-1,self.keysTop+y-1)\
  6403. end\
  6404. else\
  6405. if self.shiftState then\
  6406. gdi:write(kd.shiftChar,self.keysLeft+x-1,self.keysTop+y-1)\
  6407. else\
  6408. gdi:write(kd.char,self.keysLeft+x-1,self.keysTop+y-1)\
  6409. end\
  6410. end\
  6411. end\
  6412. end\
  6413. end\
  6414. function keyboardFrame:onTouch(x,y)\
  6415. local kd=self:getKeyDef(x,y)\
  6416. if kd then\
  6417. if kd.code~=0 then\
  6418. if kd.code==keys.leftAlt then\
  6419. if self.altState then\
  6420. self.altState=false\
  6421. else\
  6422. self.altState=true\
  6423. self.targetWnd:sendEvent(\"key\",kd.code,self.ctrlState,self.altState,self.shiftState)\
  6424. end\
  6425. self:invalidate()\
  6426. return true\
  6427. elseif kd.code==keys.leftCtrl then\
  6428. if self.ctrlState then\
  6429. self.ctrlState=false\
  6430. else\
  6431. self.ctrlState=true\
  6432. self.targetWnd:sendEvent(\"key\",kd.code,self.ctrlState,self.altState,self.shiftState)\
  6433. end\
  6434. self:invalidate()\
  6435. return true\
  6436. elseif kd.code==keys.leftShift then\
  6437. if self.shiftState then\
  6438. self.shiftState=false\
  6439. else\
  6440. self.shiftState=true\
  6441. self.targetWnd:sendEvent(\"key\",kd.code,self.ctrlState,self.altState,self.shiftState)\
  6442. end\
  6443. self:invalidate()\
  6444. return true\
  6445. elseif kd.code==keys.capsLock then\
  6446. if self.capsState then\
  6447. self.capsState=false\
  6448. else\
  6449. self.capsState=true\
  6450. self.targetWnd:sendEvent(\"key\",kd.code,self.ctrlState,self.altState,self.shiftState)\
  6451. end\
  6452. self:invalidate()\
  6453. return true\
  6454. end\
  6455. if kd.code~=300 then\
  6456. self.targetWnd:sendEvent(\"key\",kd.code,self.ctrlState,self.altState,self.shiftState)\
  6457. if not self.ctrlState and not self.altState and kd.charEvent then\
  6458. if self.capsState then\
  6459. if self.shiftState then\
  6460. self.targetWnd:sendEvent(\"char\",kd.shiftCapsChar)\
  6461. else\
  6462. self.targetWnd:sendEvent(\"char\",kd.capsChar)\
  6463. end\
  6464. else\
  6465. if self.shiftState then\
  6466. self.targetWnd:sendEvent(\"char\",kd.shiftChar)\
  6467. else\
  6468. self.targetWnd:sendEvent(\"char\",kd.char)\
  6469. end\
  6470. end\
  6471. end\
  6472. if kd.charEvent then\
  6473. if self.ctrlState or self.altState or self.shiftState then\
  6474. self.ctrlState=false\
  6475. self.altState=false\
  6476. self.shiftState=false\
  6477. self:invalidate()\
  6478. return true\
  6479. end\
  6480. end\
  6481. end\
  6482. if kd.code==300 then\
  6483. self:dismiss()\
  6484. return true\
  6485. elseif kd.code==keys.enter then\
  6486. if self.targetWnd:getWantKeyInput()==KEYINPUT_LINE then\
  6487. self:dismiss()\
  6488. return true\
  6489. end\
  6490. end\
  6491. end\
  6492. end\
  6493. return true\
  6494. end\
  6495. function keyboardFrame:onResize()\
  6496. local szWidth,szHeight=self.gdi:getSize()\
  6497. local tLeft,tTop,tWidth,tHeight=self.targetRect:unpack()\
  6498. self.keyMap=iif((szWidth<20),self.mapBrief,self.mapFull)\
  6499. self.keysLeft=math.floor((szWidth-iif(szWidth<20,15,20))/2)\
  6500. self.keysTop=iif((szHeight-self:getTheme().keyboardHeight)<4,4,\
  6501. (szHeight-self:getTheme().keyboardHeight))\
  6502. tHeight=iif((tHeight>(self.keysTop-2)),(self.keysTop-2),tHeight)\
  6503. tWidth=iif((tWidth>szWidth),szWidth,tWidth)\
  6504. tLeft=math.floor((szWidth-tWidth)/2)\
  6505. tTop=self.keysTop-tHeight-1\
  6506. self:move(0,0,szWidth,szHeight,WND_TOP)\
  6507. self.targetWnd:move(tLeft,tTop,tWidth,tHeight)\
  6508. return true\
  6509. end\
  6510. function keyboardFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  6511. if p1==self.targetWnd then\
  6512. if self.targetParent then\
  6513. self.targetParent:sendEvent(event,p1,p2,p3,p4,p5)\
  6514. end\
  6515. end\
  6516. return true\
  6517. end\
  6518. function keyboardFrame:runApp()\
  6519. local tZ;\
  6520. if self:onCreate()then\
  6521. self:runModal()\
  6522. end\
  6523. self.targetWnd:setParent(self.targetParent)\
  6524. if self.targetParent and self.targetZ then\
  6525. tZ=(self.targetZ-self.targetParent:childIndex(self.targetWnd))\
  6526. tZ=iif((tZ==0),nil,tZ)\
  6527. end\
  6528. self.targetWnd:move(self.targetRect.x,self.targetRect.y,\
  6529. self.targetRect.width,self.targetRect.height,tZ)\
  6530. self:getDesktop().dt__keyboard=nil\
  6531. self:destroyWnd()\
  6532. self.targetWnd:setFocus()\
  6533. self:getDesktop():update(true)\
  6534. end\
  6535. local function runAppFrame(frame)\
  6536. frame.appFrame__appRoutine=coroutine.create(frame.runApp)\
  6537. if not frame.appFrame__appRoutine then\
  6538. error(\"Failed to create system frame\",2)\
  6539. end\
  6540. local success,msg=coroutine.resume(frame.appFrame__appRoutine,frame)\
  6541. if not success then\
  6542. error(\"Error initialising system frame \"..\"\\n\"..msg,2)\
  6543. end\
  6544. end\
  6545. local desktopWindow=window:base()\
  6546. function desktopWindow:constructor(side,buffer)\
  6547. if not window.constructor(self,nil,ID_DESKTOP,0,0,0,0)then\
  6548. return nil\
  6549. end\
  6550. self.dt__taskBar=nil\
  6551. self.dt__homePage=nil\
  6552. self.dt__appList=nil\
  6553. self.dt__keyboard=nil\
  6554. self.dt__captureMouseWnd=nil\
  6555. self.dt__dragWnd=nil\
  6556. self.dt__cursorColor=colors.black\
  6557. self.dt__bufferDisplay=buffer\
  6558. self.dt__clipboardData=nil\
  6559. self.dt__clipboardType=CB_EMPTY\
  6560. self.gdi=GDI:new(side,self)\
  6561. self.dt__theme=self:createTheme()\
  6562. self:setBgColor(self:getColors().desktopBack)\
  6563. local szWidth,szHeight=self.gdi:getSize()\
  6564. self:move(0,0,szWidth,szHeight,nil)\
  6565. return self\
  6566. end\
  6567. function desktopWindow:getTheme()\
  6568. return self.dt__theme\
  6569. end\
  6570. function desktopWindow:getTaskBarIndex()\
  6571. for i=1,self:children(),1 do\
  6572. if self:getChild(i)==self.dt__taskBar then\
  6573. return i\
  6574. end\
  6575. end\
  6576. return 0\
  6577. end\
  6578. function desktopWindow:getActiveAppFrame()\
  6579. if self:children()>0 then\
  6580. for i=self:getTaskBarIndex()+1,self:children(),1 do\
  6581. local frame=self:getChild(i)\
  6582. if frame.wnd__frameClass==FRAME_CLASS_APPLICATION then\
  6583. return frame\
  6584. end\
  6585. end\
  6586. end\
  6587. return nil\
  6588. end\
  6589. function desktopWindow:getActiveFrame()\
  6590. if self:children()>0 then\
  6591. return self:getChild(self:getTaskBarIndex()+1)\
  6592. end\
  6593. return nil\
  6594. end\
  6595. function desktopWindow:getNextAppFrame(frame)\
  6596. local start=self:childIndex(frame)\
  6597. if start>0 then\
  6598. for i=start+1,self:children(),1 do\
  6599. local top=self:getChild(i)\
  6600. if top.wnd__frameClass==FRAME_CLASS_APPLICATION then\
  6601. return top\
  6602. end\
  6603. end\
  6604. end\
  6605. return nil\
  6606. end\
  6607. function desktopWindow:getFocusWnd()\
  6608. local frame=self:getActiveFrame()\
  6609. if frame then\
  6610. return frame.pFrame__focusedWnd\
  6611. end\
  6612. return nil\
  6613. end\
  6614. function desktopWindow:setActiveFrame(frame)\
  6615. local curFrame=self:getActiveFrame()\
  6616. if frame and frame~=curFrame then\
  6617. self.dt__captureMouseWnd=nil\
  6618. self.dt__dragWnd=nil\
  6619. local i=self:childIndex(frame)\
  6620. if i>0 then\
  6621. if not curFrame or curFrame:getId()~=ID_LOCKSCRN then\
  6622. if curFrame then\
  6623. local success,msg=pcall(curFrame.onFrameActivate,curFrame,false)\
  6624. if not success then\
  6625. syslog(curFrame:getText()..\" onFrameActivate \"..msg)\
  6626. end\
  6627. curFrame:invalidate()\
  6628. if curFrame.pFrame__focusedWnd then\
  6629. curFrame.pFrame__focusedWnd:sendEvent(\"blur\",nil)\
  6630. end\
  6631. end\
  6632. i=self:getTaskBarIndex()-i+1\
  6633. if i~=0 then\
  6634. window.move(frame,nil,nil,nil,nil,i)\
  6635. end\
  6636. frame:invalidate()\
  6637. local focus=frame.pFrame__focusedWnd\
  6638. if not focus then\
  6639. focus=frame:nextWnd(nil,true)\
  6640. end\
  6641. if focus then\
  6642. frame.pFrame__focusedWnd=nil\
  6643. focus:setFocus()\
  6644. end\
  6645. local success,msg=pcall(frame.onFrameActivate,frame,true)\
  6646. if not success then\
  6647. syslog(frame:getText()..\" onFrameActivate \"..msg)\
  6648. end\
  6649. return true\
  6650. end\
  6651. end\
  6652. end\
  6653. return(frame==curFrame)\
  6654. end\
  6655. function desktopWindow:update(force)\
  6656. if force then\
  6657. self:invalidate()\
  6658. end\
  6659. if not self.wnd__invalid:isEmpty()then\
  6660. local first=self:children()+1\
  6661. local rt=self:getWorkArea()\
  6662. rt.width=rt.width-1\
  6663. rt.height=rt.height-1\
  6664. self.gdi:store()\
  6665. self.gdi:setDraw(false)\
  6666. self.gdi:addBounds(self.wnd__invalid)\
  6667. for i=1,self:children(),1 do\
  6668. local frame=self:getChild(i)\
  6669. local rtWnd=frame:getScreenRect()\
  6670. if rtWnd:contains(rt.x,rt.y)and\
  6671. rtWnd:contains(rt.x+rt.width-1,rt.y+rt.height-1)then\
  6672. first=i\
  6673. break\
  6674. end\
  6675. end\
  6676. if first>self:children()then\
  6677. first=self:children()\
  6678. if self:getBgColor()>0 then\
  6679. self.gdi:setBackgroundColor(self:getBgColor())\
  6680. self.gdi:clear(self.wnd__invalid:unpack())\
  6681. end\
  6682. self:draw(self.gdi,rect:new(self.wnd__invalid:unpack()))\
  6683. end\
  6684. for i=first,1,-1 do\
  6685. local frame=self:getChild(i)\
  6686. if frame:getScreenRect():overlap(self.gdi:getBounds())then\
  6687. self.gdi:addBounds(frame:update(force or i<first))\
  6688. end\
  6689. end\
  6690. self:validate()\
  6691. self.gdi:setDraw(true)\
  6692. self.gdi:restore()\
  6693. end\
  6694. return self.gdi:getBounds(true)\
  6695. end\
  6696. function desktopWindow:doIdle(count)\
  6697. for i=1,self:children(),1 do\
  6698. self:getChild(i):sendEvent(\"idle\",count)\
  6699. end\
  6700. end\
  6701. function desktopWindow:loadAppList()\
  6702. self.dt__appList:loadList()\
  6703. end\
  6704. function desktopWindow:runApp(path,...)\
  6705. self:getWorkSpace():runApp(self:getSide(),path,unpack(parseCmdLine(...)))\
  6706. self:loadAppList()\
  6707. end\
  6708. function desktopWindow:onResize()\
  6709. self:move(0,0,self.gdi:getSize())\
  6710. for i=1,self:children(),1 do\
  6711. self:getChild(i):sendEvent(\"monitor_resize\")\
  6712. end\
  6713. return true\
  6714. end\
  6715. function desktopWindow:getFullscreen()\
  6716. if self.dt__taskBar then\
  6717. return self.dt__taskBar.wnd__hidden~=false\
  6718. end\
  6719. return false\
  6720. end\
  6721. function desktopWindow:setFullscreen(fullscreen)\
  6722. if fullscreen==nil then\
  6723. fullscreen=not self:getFullscreen()\
  6724. end\
  6725. if fullscreen~=self:getFullscreen()then\
  6726. local focusWnd=self:getFocusWnd()\
  6727. self.dt__taskBar:show(not fullscreen)\
  6728. self:onResize()\
  6729. if focusWnd then\
  6730. pcall(focusWnd.onMove,focusWnd)\
  6731. end\
  6732. end\
  6733. end\
  6734. function desktopWindow:getWorkArea()\
  6735. local rt=rect:new(0,0,self.gdi:getSize())\
  6736. if not self:getFullscreen()then\
  6737. rt.height=rt.height-1\
  6738. end\
  6739. return rt\
  6740. end\
  6741. function desktopWindow:captureMouse(wnd)\
  6742. self.dt__captureMouseWnd=wnd\
  6743. end\
  6744. function desktopWindow:capturedMouse()\
  6745. return self.dt__captureMouseWnd\
  6746. end\
  6747. function desktopWindow:getClipboard()\
  6748. return self.dt__clipboardType,self.dt__clipboardData\
  6749. end\
  6750. function desktopWindow:setClipboard(data,cbType)\
  6751. if data==nil then\
  6752. self.dt__clipboardType=CB_EMPTY\
  6753. self.dt__clipboardData=nil\
  6754. else\
  6755. self.dt__clipboardData=data\
  6756. if cbType==nil then\
  6757. self.dt__clipboardType=CB_TEXT\
  6758. else\
  6759. self.dt__clipboardType=cbType\
  6760. end\
  6761. end\
  6762. end\
  6763. function desktopWindow:dropApp(frame)\
  6764. local app=self:getActiveFrame()\
  6765. if app then\
  6766. app=app:getAppFrame()\
  6767. end\
  6768. if frame==app then\
  6769. local nextFrame=self:getNextAppFrame(frame)\
  6770. if nextFrame then\
  6771. nextFrame:setActiveTopFrame()\
  6772. else\
  6773. self:showHomePage()\
  6774. end\
  6775. end\
  6776. frame:destroyWnd()\
  6777. self:loadAppList()\
  6778. end\
  6779. function desktopWindow:enumApps(iterator)\
  6780. if iterator==nil then\
  6781. iterator=self:getTaskBarIndex()+1\
  6782. end\
  6783. local frame=self:getChild(iterator)\
  6784. while frame do\
  6785. if frame.wnd__frameClass==FRAME_CLASS_APPLICATION then\
  6786. iterator=iterator+1\
  6787. return iterator,frame\
  6788. end\
  6789. iterator=iterator+1\
  6790. frame=self:getChild(iterator)\
  6791. end\
  6792. return iterator,nil\
  6793. end\
  6794. function desktopWindow:setTextScale(scale)\
  6795. if self.gdi:isMonitor()then\
  6796. self.gdi:setTextScale(scale)\
  6797. self:onResize()\
  6798. end\
  6799. end\
  6800. function desktopWindow:showHomePage()\
  6801. self.dt__homePage:setActiveTopFrame()\
  6802. end\
  6803. function desktopWindow:showListPage()\
  6804. self.dt__appList:setActiveTopFrame()\
  6805. end\
  6806. function desktopWindow:saveTheme(theme)\
  6807. local themeFile=\"/win/\"..self:getSide()..\"/theme.ini\"\
  6808. local result=false\
  6809. local hFile=fs.open(themeFile,\"w\")\
  6810. if hFile then\
  6811. local data=textutils.serialize(theme)\
  6812. if data then\
  6813. hFile.write(data)\
  6814. result=true\
  6815. end\
  6816. hFile.close()\
  6817. end\
  6818. return result\
  6819. end\
  6820. function desktopWindow:loadTheme()\
  6821. local themeFile=\"/win/\"..self:getSide()..\"/theme.ini\"\
  6822. local theme=nil\
  6823. if fs.exists(themeFile)and not fs.isDir(themeFile)then\
  6824. local hFile=fs.open(themeFile,\"r\")\
  6825. if hFile then\
  6826. local data=hFile.readAll()\
  6827. if data then\
  6828. theme=textutils.unserialize(data)\
  6829. end\
  6830. hFile.close()\
  6831. end\
  6832. end\
  6833. return theme\
  6834. end\
  6835. function desktopWindow:createTheme()\
  6836. local theme=self:loadTheme()\
  6837. if not theme then\
  6838. theme=desktopTheme:new()\
  6839. self:saveTheme(theme)\
  6840. end\
  6841. if theme.keyboardHeight<5 then\
  6842. theme.keyboardHeight=5\
  6843. end\
  6844. theme.closeBtnChar=asstring(theme.closeBtnChar)\
  6845. if theme.closeBtnChar:len()>1 then\
  6846. theme.closeBtnChar=theme.closeBtnChar:sub(1,1)\
  6847. end\
  6848. return theme\
  6849. end\
  6850. function desktopWindow:doKeyboard(targetWnd)\
  6851. if not self.dt__keyboard then\
  6852. self.dt__keyboard=keyboardFrame:new(self:getSide(),targetWnd)\
  6853. runAppFrame(self.dt__keyboard)\
  6854. end\
  6855. end\
  6856. function desktopWindow:dismissKeyboard()\
  6857. if self.dt__keyboard then\
  6858. self.dt__keyboard:dismiss()\
  6859. self.dt__keyboard=nil\
  6860. end\
  6861. end\
  6862. function desktopWindow:createBars()\
  6863. local title;\
  6864. local iniFile=fs.loadIniFile(\"/win/\"..self:getSide()..\"/startup.ini\")\
  6865. if iniFile then\
  6866. title=iniFile:find(\"home\")\
  6867. end\
  6868. self.dt__taskBar=taskBarFrame:new(self:getSide())\
  6869. runAppFrame(self.dt__taskBar)\
  6870. self.dt__homePage=homePageFrame:new(self:getSide(),title)\
  6871. runAppFrame(self.dt__homePage)\
  6872. self.dt__appList=appListFrame:new(self:getSide())\
  6873. runAppFrame(self.dt__appList)\
  6874. self.dt__homePage:loadList()\
  6875. self:showHomePage()\
  6876. end\
  6877. function desktopWindow:msgBox(titleText,message,bgColor)\
  6878. os.queueEvent(\"system_msgbox\",self:getSide(),titleText,message,bgColor)\
  6879. end\
  6880. function desktopWindow:lockScreen()\
  6881. if not self:isLocked()then\
  6882. os.queueEvent(\"lock_screen\",self:getSide())\
  6883. end\
  6884. end\
  6885. function desktopWindow:isLocked()\
  6886. return self:getWndById(ID_LOCKSCRN)~=nil\
  6887. end\
  6888. function desktopWindow:canLock()\
  6889. return getPassword():len()>0\
  6890. end\
  6891. function desktopWindow:getPassword()\
  6892. return getPassword()\
  6893. end\
  6894. local workSpace=__classBase:base()\
  6895. function workSpace:constructor()\
  6896. self.ws__desktops={}\
  6897. self.ws__doLockScreen=false\
  6898. self.ws__keyctrl=-1\
  6899. self.ws__keyalt=-1\
  6900. self.ws__keyshift=-1\
  6901. self.ws__lastEventIdle=true\
  6902. self.ws__eventCount=0\
  6903. self.ws__lastUpdate=-1\
  6904. self.ws__idleCount=1\
  6905. self.ws__idleTime=-1\
  6906. self.ws__idleTimerId=0\
  6907. self.ws__lockEvents=false\
  6908. self.ws__appRoutine=nil\
  6909. self.ws__appSide=nil\
  6910. self.ws__appPath=nil\
  6911. self.ws__appFrame=nil\
  6912. self.ws__syscomms=0\
  6913. self.ws__comms={}\
  6914. self.ws__timers={}\
  6915. self.ws__wndEvents={}\
  6916. return self\
  6917. end\
  6918. function workSpace:commEnabled()\
  6919. return(self.ws__syscomms>0)\
  6920. end\
  6921. function workSpace:commFind(name,wireless)\
  6922. if name then\
  6923. for i=1,#self.ws__comms,1 do\
  6924. if name==self.ws__comms[i]:getName()then\
  6925. return self.ws__comms[i]\
  6926. end\
  6927. end\
  6928. return nil\
  6929. end\
  6930. if wireless~=nil then\
  6931. for i=1,#self.ws__comms,1 do\
  6932. if wireless==self.ws__comms[i]:getWireless()then\
  6933. return self.ws__comms[i]\
  6934. end\
  6935. end\
  6936. return nil\
  6937. end\
  6938. return self.ws__comms[1]\
  6939. end\
  6940. function workSpace:commOpen(name,wireless,port,timeout,relay)\
  6941. if not name then\
  6942. local count=0\
  6943. repeat\
  6944. name=\"comm_\"..tostring(count)\
  6945. count=count+1\
  6946. until not self:commFind(name)\
  6947. end\
  6948. local com=comm:new(name,wireless,port,timeout,relay)\
  6949. if com:connect()then\
  6950. self.ws__comms[#self.ws__comms+1]=com\
  6951. return com\
  6952. end\
  6953. return nil\
  6954. end\
  6955. function workSpace:commClose(name)\
  6956. if name then\
  6957. local index;\
  6958. for i=self.ws__syscomms+1,1,-1 do\
  6959. if name==self.ws__comms[i]:getName()then\
  6960. index=i\
  6961. break\
  6962. end\
  6963. end\
  6964. if index then\
  6965. local close=true\
  6966. for i=#self.ws__comms,1,-1 do\
  6967. if(i~=index)and\
  6968. (self.ws__comms[i]:getPort()==\
  6969. self.ws__comms[index]:getPort())then\
  6970. close=false\
  6971. break\
  6972. end\
  6973. end\
  6974. if close then\
  6975. self.ws__comms[index]:disconnect()\
  6976. end\
  6977. table.remove(self.ws__comms,index)\
  6978. return true\
  6979. end\
  6980. end\
  6981. return false\
  6982. end\
  6983. function workSpace:commRegister(wnd,application,name,wireless)\
  6984. local com=self:commFind(name,wireless)\
  6985. if com then\
  6986. com:register(wnd,application)\
  6987. return true\
  6988. end\
  6989. return false\
  6990. end\
  6991. function workSpace:commUnregister(wnd,application,name,wireless)\
  6992. if name or wireless then\
  6993. local com=self:commFind(name,wireless)\
  6994. if com then\
  6995. com:unregister(wnd,application)\
  6996. return true\
  6997. end\
  6998. else\
  6999. for i=1,#self.ws__comms,1 do\
  7000. self.ws__comms[i]:unregister(wnd,application)\
  7001. end\
  7002. return true\
  7003. end\
  7004. return false\
  7005. end\
  7006. function workSpace:commSend(recipient,application,context,data,name,wireless)\
  7007. local com=self:commFind(name,wireless)\
  7008. if com then\
  7009. return com:send(recipient,application,context,data)\
  7010. end\
  7011. return nil\
  7012. end\
  7013. function workSpace:getDesktop(side)\
  7014. return self.ws__desktops[asstring(side)]\
  7015. end\
  7016. function workSpace:desktops()\
  7017. local sides={}\
  7018. for side,desktop in pairs(self.ws__desktops)do\
  7019. sides[#sides+1]=side\
  7020. end\
  7021. return sides\
  7022. end\
  7023. function workSpace:getFocusWnd(side)\
  7024. if self:getDesktop(side)then\
  7025. return self:getDesktop(side):getFocusWnd()\
  7026. end\
  7027. return nil\
  7028. end\
  7029. function workSpace:startTimer(wnd,timeout)\
  7030. local id=os.startTimer(asnumber(timeout))\
  7031. self.ws__timers[#self.ws__timers+1]={id,wnd,\"timer\"}\
  7032. return id\
  7033. end\
  7034. function workSpace:setAlarm(wnd,time)\
  7035. local id=os.setAlarm(asnumber(time))\
  7036. self.ws__timers[#self.ws__timers+1]={id,wnd,\"alarm\"}\
  7037. return id\
  7038. end\
  7039. function workSpace:sleepApp(wnd,timeout)\
  7040. self.ws__timers[#self.ws__timers+1]={os.startTimer(asnumber(timeout)),wnd,\"sleep\"}\
  7041. end\
  7042. function workSpace:killTimers(wnd)\
  7043. for i=#self.ws__timers,1,-1 do\
  7044. if self.ws__timers[i][2]==wnd then\
  7045. table.remove(self.ws__timers,i)\
  7046. end\
  7047. end\
  7048. end\
  7049. function workSpace:wantEvent(wnd,event)\
  7050. event=asstring(event)\
  7051. for i=1,#self.ws__wndEvents,1 do\
  7052. if self.ws__wndEvents[i][1]==wnd and\
  7053. (self.ws__wndEvents[i][2]==event or\
  7054. self.ws__wndEvents[i][2]==\"*\" or event==\"*\")then\
  7055. return false\
  7056. end\
  7057. end\
  7058. self.ws__wndEvents[#self.ws__wndEvents+1]={wnd,event}\
  7059. return true\
  7060. end\
  7061. function workSpace:unwantEvent(wnd,event)\
  7062. event=asstring(event)\
  7063. if event:len()>0 then\
  7064. for i=1,#self.ws__wndEvents,1 do\
  7065. if self.ws__wndEvents[i][1]==wnd and\
  7066. self.ws__wndEvents[i][2]==event then\
  7067. table.remove(self.ws__wndEvents,i)\
  7068. return true\
  7069. end\
  7070. end\
  7071. else\
  7072. local count=0\
  7073. for i=#self.ws__wndEvents,1,-1 do\
  7074. if self.ws__wndEvents[i][1]==wnd then\
  7075. table.remove(self.ws__wndEvents,i)\
  7076. count=count+1\
  7077. end\
  7078. end\
  7079. return(count>0)\
  7080. end\
  7081. return false\
  7082. end\
  7083. function workSpace:runApp(side,path,...)\
  7084. local result,msg=loadfile(path)\
  7085. if not result then\
  7086. error(\"Failed to load program \"..path..\"\\n\"..msg,0)\
  7087. end\
  7088. self.ws__appRoutine=coroutine.create(result)\
  7089. if not self.ws__appRoutine then\
  7090. error(\"Failed to create application \"..fs.getName(path),0)\
  7091. end\
  7092. self.ws__appSide=side\
  7093. self.ws__appPath=path\
  7094. result,msg=coroutine.resume(self.ws__appRoutine,...)\
  7095. if not result then\
  7096. if self.ws__appFrame then\
  7097. msg=self.ws__appFrame:getText()..\"\\n\"..msg\
  7098. self:getDesktop(side):dropApp(self.ws__appFrame)\
  7099. self.ws__appFrame=nil\
  7100. end\
  7101. error(msg,0)\
  7102. end\
  7103. self.ws_appFrame=nil\
  7104. end\
  7105. function workSpace:assessKey(key,keyup)\
  7106. if ccVersion()>=1.74 then\
  7107. if key then\
  7108. if key==keys.leftCtrl or key==keys.rightCtrl then\
  7109. self.ws__keyctrl=os.clock()+100000\
  7110. elseif key==keys.leftAlt or key==keys.rightAlt then\
  7111. self.ws__keyalt=os.clock()+100000\
  7112. elseif key==keys.leftShift or key==keys.rightShift then\
  7113. self.ws__keyshift=os.clock()+100000\
  7114. end\
  7115. else\
  7116. if keyup==keys.leftCtrl or keyup==keys.rightCtrl then\
  7117. self.ws__keyctrl=-1\
  7118. elseif keyup==keys.leftAlt or keyup==keys.rightAlt then\
  7119. self.ws__keyalt=-1\
  7120. elseif keyup==keys.leftShift or keyup==keys.rightShift then\
  7121. self.ws__keyshift=-1\
  7122. end\
  7123. end\
  7124. else\
  7125. if key==keys.leftCtrl or key==keys.rightCtrl then\
  7126. self.ws__keyctrl=os.clock()\
  7127. elseif key==keys.leftAlt or key==keys.rightAlt then\
  7128. self.ws__keyalt=os.clock()\
  7129. elseif key==keys.leftShift or key==keys.rightShift then\
  7130. self.ws__keyshift=os.clock()\
  7131. end\
  7132. end\
  7133. end\
  7134. function workSpace:ctrlKey()\
  7135. return(os.clock()-self.ws__keyctrl)<=0.75\
  7136. end\
  7137. function workSpace:altKey()\
  7138. return(os.clock()-self.ws__keyalt)<=0.75\
  7139. end\
  7140. function workSpace:shiftKey()\
  7141. return(os.clock()-self.ws__keyshift)<=0.75\
  7142. end\
  7143. function workSpace:comboKeys(ctrl,alt,shift)\
  7144. local bCtrl,bAlt,bShift;\
  7145. if ctrl then\
  7146. bCtrl=self:ctrlKey()\
  7147. else\
  7148. bCtrl=not self:ctrlKey()\
  7149. end\
  7150. if alt then\
  7151. bAlt=self:altKey()\
  7152. else\
  7153. bAlt=not self:altKey()\
  7154. end\
  7155. if shift then\
  7156. bShift=self:shiftKey()\
  7157. else\
  7158. bShift=not self:shiftKey()\
  7159. end\
  7160. return(bCtrl and bAlt and bShift)\
  7161. end\
  7162. function workSpace:getShell()\
  7163. return __shell\
  7164. end\
  7165. function workSpace:createDesktop(side)\
  7166. local desktopFile=\"/win/\"..side..\"/desktop.ini\"\
  7167. local buffer=false\
  7168. local iniFile=fs.loadIniFile(\"/win/\"..side..\"/startup.ini\")\
  7169. if iniFile then\
  7170. buffer=asstring((iniFile:find(\"buffer\")),\"false\")==\"true\"\
  7171. end\
  7172. if side==\"term\" and fs.exists(desktopFile)and not fs.isDir(desktopFile)then\
  7173. return desktopWindow:new(side,buffer)\
  7174. end\
  7175. if fs.exists(desktopFile)and not fs.isDir(desktopFile)and peripheral.getType(side)==\"monitor\" then\
  7176. local desktop=desktopWindow:new(side,buffer)\
  7177. if desktop then\
  7178. desktop:setTextScale(desktop:getTheme().textScale)\
  7179. end\
  7180. return desktop\
  7181. end\
  7182. return nil\
  7183. end\
  7184. function workSpace:desktopStartup(side)\
  7185. local desktop=self:getDesktop(side)\
  7186. if desktop then\
  7187. local iniFile=fs.loadIniFile(\"/win/\"..side..\"/startup.ini\")\
  7188. if iniFile then\
  7189. if asstring(iniFile:find(\"fullscreen\"),\"false\")==\"true\" then\
  7190. desktop:setFullscreen(true)\
  7191. end\
  7192. for path in iniFile:next(\"run\")do\
  7193. if path:len()>0 then\
  7194. self:runApp(side,unpack(parseCmdLine(path)))\
  7195. desktop:loadAppList()\
  7196. end\
  7197. end\
  7198. end\
  7199. end\
  7200. end\
  7201. function workSpace:startIdleTimer()\
  7202. if(os.clock()-self.ws__idleTime)>0.3 then\
  7203. self.ws__idleTimerId=os.startTimer(0.35)\
  7204. self.ws__idleTime=os.clock()\
  7205. end\
  7206. end\
  7207. function workSpace:createDesktops()\
  7208. local devices=peripheral.getNames()\
  7209. local sides={\"term\"}\
  7210. for i=1,#devices,1 do\
  7211. if peripheral.getType(devices[i])==\"monitor\" then\
  7212. sides[#sides+1]=devices[i]\
  7213. end\
  7214. end\
  7215. for _,side in pairs(sides)do\
  7216. self.ws__desktops[side]=self:createDesktop(side)\
  7217. if self.ws__desktops[side]then\
  7218. self.ws__desktops[side]:createBars()\
  7219. end\
  7220. end\
  7221. for _,side in pairs(sides)do\
  7222. self:desktopStartup(side)\
  7223. end\
  7224. end\
  7225. function workSpace:lockScreens()\
  7226. if self.ws__doLockScreen then\
  7227. for k,desktop in pairs(self.ws__desktops)do\
  7228. if desktop then\
  7229. desktop:lockScreen()\
  7230. end\
  7231. end\
  7232. self.ws__doLockScreen=false\
  7233. end\
  7234. end\
  7235. function workSpace:pumpEvent(wnd,event,...)\
  7236. if wnd then\
  7237. local app=wnd:getAppFrame()\
  7238. if app then\
  7239. return app:resume(wnd,event,...)\
  7240. end\
  7241. end\
  7242. return false\
  7243. end\
  7244. function workSpace:startup()\
  7245. local function safeTermColor(color)\
  7246. if term.isColor()then\
  7247. term.setTextColor(color)\
  7248. end\
  7249. end\
  7250. local hadKey=false\
  7251. local timerID;\
  7252. local delayTime=3.5\
  7253. local iniFile=fs.loadIniFile(\"/win/startup.ini\")\
  7254. if term.isColor()then\
  7255. term.setBackgroundColor(colors.black)\
  7256. end\
  7257. if iniFile then\
  7258. local pw=asstring(iniFile:find(\"password\"),\"\")\
  7259. local delayKey=iniFile:find(\"delay\")\
  7260. if delayKey then\
  7261. delayTime=asnumber(delayKey)\
  7262. if delayTime<=0 then\
  7263. self.ws__doLockScreen=true\
  7264. end\
  7265. end\
  7266. if pw:len()>0 and not self.ws__doLockScreen then\
  7267. local pwCount,correct=0,false\
  7268. while pwCount<3 and not correct do\
  7269. term.clear()\
  7270. term.setCursorPos(1,3)\
  7271. safeTermColor(colors.white)\
  7272. term.write(\"Password:\")\
  7273. safeTermColor(colors.red)\
  7274. correct=(safeRead(\"*\")==pw)\
  7275. pwCount=pwCount+1\
  7276. end\
  7277. if not correct then\
  7278. os.shutdown()\
  7279. end\
  7280. end\
  7281. end\
  7282. if delayTime>0 then\
  7283. term.clear()\
  7284. term.setCursorPos(1,3)\
  7285. safeTermColor(colors.white)\
  7286. term.write(\"Starting \")\
  7287. safeTermColor(colors.yellow)\
  7288. term.write(\"CCWindows \"..tostring(version()))\
  7289. term.setCursorPos(1,5)\
  7290. safeTermColor(colors.lightGray)\
  7291. term.write(\"Press key for console ...\")\
  7292. timerID=os.startTimer(delayTime)\
  7293. while timerID do\
  7294. local event=os.pullEventRaw()\
  7295. if event==\"key\" then\
  7296. term.setCursorPos(1,5)\
  7297. term.write(\"Starting console ...     \")\
  7298. hadKey=true\
  7299. elseif event==\"timer\" then\
  7300. timerID=nil\
  7301. end\
  7302. end\
  7303. if hadKey then\
  7304. term.clear()\
  7305. term.setCursorPos(1,1)\
  7306. safeTermColor(colors.yellow)\
  7307. term.write(os.version())\
  7308. term.setCursorPos(1,2)\
  7309. return false\
  7310. end\
  7311. end\
  7312. if iniFile then\
  7313. local hadError=false\
  7314. term.clear()\
  7315. term.setCursorPos(1,1)\
  7316. for value in iniFile:next(\"path\")do\
  7317. if value:len()>0 then\
  7318. __shell.setPath(__shell.path()..\":\"..value)\
  7319. end\
  7320. end\
  7321. for value in iniFile:next(\"pre\")do\
  7322. if value:len()>0 then\
  7323. local success,func,msg=false,loadfile(value)\
  7324. if func then\
  7325. success,msg=pcall(func)\
  7326. end\
  7327. if not success then\
  7328. safeTermColor(colors.red)\
  7329. print(msg)\
  7330. hadError=true\
  7331. end\
  7332. end\
  7333. end\
  7334. for value in iniFile:next(\"api\")do\
  7335. if value:len()>0 then\
  7336. if not loadAPI(value,true)then\
  7337. hadError=true\
  7338. end\
  7339. end\
  7340. end\
  7341. for value in iniFile:next(\"comm\")do\
  7342. local timeout=asnumber(iniFile:find(value..\"timeout\"),5)\
  7343. local port=asnumber(iniFile:find(value..\"port\"),80)\
  7344. local reply=asstring(iniFile:find(value..\"relay\"),\"false\")==\"true\"\
  7345. local wireless=iniFile:find(value..\"wireless\")\
  7346. if wireless then\
  7347. wireless=wireless==\"true\"\
  7348. end\
  7349. if self:commOpen(value,wireless,port,timeout,relay)then\
  7350. self.ws__syscomms=self.ws__syscomms+1\
  7351. else\
  7352. safeTermColor(colors.red)\
  7353. print(\"Could not open comm \"..value)\
  7354. hadError=true\
  7355. end\
  7356. end\
  7357. if hadError then\
  7358. safeTermColor(colors.white)\
  7359. print(\"Press key...\")\
  7360. while(os.pullEventRaw())~=\"key\" do\
  7361. end\
  7362. end\
  7363. end\
  7364. local global=getfenv(0)\
  7365. local global_os_pullEventRaw=global.os.pullEventRaw\
  7366. function global.os.pullEventRaw(target)\
  7367. if __ccwin.ws__lockEvents then\
  7368. local result;\
  7369. repeat\
  7370. result={coroutine.yield(\"event\")}\
  7371. until not target or result[1]==target\
  7372. return unpack(result)\
  7373. end\
  7374. while true do\
  7375. __ccwin:run(global_os_pullEventRaw())\
  7376. end\
  7377. end\
  7378. function global.os.pullEvent(target)\
  7379. local result;\
  7380. repeat\
  7381. result={coroutine.yield(\"event\")}\
  7382. if result[1]==\"terminate\" then\
  7383. error(\"Terminated\",0)\
  7384. end\
  7385. until not target or result[1]==target\
  7386. return unpack(result)\
  7387. end\
  7388. function global.sleep(seconds)\
  7389. if tostring(coroutine.yield(\"sleep\",seconds))==\"terminate\" then\
  7390. error(\"Terminated\",0)\
  7391. end\
  7392. end\
  7393. function global.os.sleep(seconds)\
  7394. global.sleep(seconds)\
  7395. end\
  7396. self:createDesktops()\
  7397. if not self.ws__desktops.term then\
  7398. term.clear()\
  7399. term.setCursorPos(1,3)\
  7400. safeTermColor(colors.white)\
  7401. term.write(\"Running \")\
  7402. safeTermColor(colors.yellow)\
  7403. term.write(\"CCWindows \"..tostring(version()))\
  7404. end\
  7405. term.setCursorPos(-1,-1)\
  7406. self.ws__lastEventIdle=true\
  7407. self.ws__eventCount=0\
  7408. self.ws__lastUpdate=os.clock()-1\
  7409. self.ws__idleCount=1\
  7410. self.ws__idleTimerId=os.startTimer(0.1)\
  7411. self.ws__idleTime=os.clock()-1\
  7412. return true\
  7413. end\
  7414. function workSpace:run(event,p1,p2,p3,p4,p5,...)\
  7415. local wnd;\
  7416. self.ws__lockEvents=true\
  7417. self.ws__eventCount=self.ws__eventCount+1\
  7418. if event==\"timer\" and p1==self.ws__idleTimerId then\
  7419. self:lockScreens()\
  7420. self.ws__eventCount=0\
  7421. if self.ws__lastEventIdle then\
  7422. for k,desktop in pairs(self.ws__desktops)do\
  7423. if desktop then\
  7424. desktop:doIdle(self.ws__idleCount)\
  7425. end\
  7426. end\
  7427. self.ws__idleCount=self.ws__idleCount+1\
  7428. else\
  7429. self.ws__idleCount=1\
  7430. end\
  7431. for i=1,#self.ws__comms,1 do\
  7432. self.ws__comms[i]:process()\
  7433. end\
  7434. self.ws__lastEventIdle=true\
  7435. self:startIdleTimer()\
  7436. elseif event==\"timer\" or event==\"alarm\" then\
  7437. for i=1,#self.ws__timers,1 do\
  7438. if self.ws__timers[i][1]==p1 then\
  7439. wnd=self.ws__timers[i][2]\
  7440. event=self.ws__timers[i][3]\
  7441. table.remove(self.ws__timers,i)\
  7442. break\
  7443. end\
  7444. end\
  7445. if not wnd then\
  7446. for i=1,#self.ws__wndEvents,1 do\
  7447. if self.ws__wndEvents[i][2]==event or self.ws__wndEvents[i][2]==\"*\" then\
  7448. self:pumpEvent(self.ws__wndEvents[i][1],event,p1,p2,p3,p4,p5,...)\
  7449. end\
  7450. end\
  7451. end\
  7452. self.ws__lastEventIdle=false\
  7453. elseif event==\"mouse_click\" then\
  7454. if self.ws__desktops.term then\
  7455. p2=asnumber(p2)-1\
  7456. p3=asnumber(p3)-1\
  7457. if self.ws__desktops.term:capturedMouse()then\
  7458. wnd=self.ws__desktops.term:capturedMouse()\
  7459. else\
  7460. wnd=self.ws__desktops.term:wndFromPoint(p2,p3)\
  7461. end\
  7462. self.ws__desktops.term.dt__dragWnd=wnd\
  7463. end\
  7464. self.ws__lastEventIdle=false\
  7465. elseif event==\"mouse_up\" then\
  7466. if self.ws__desktops.term then\
  7467. p2=asnumber(p2)-1\
  7468. p3=asnumber(p3)-1\
  7469. if self.ws__desktops.term:capturedMouse()then\
  7470. wnd=self.ws__desktops.term:capturedMouse()\
  7471. else\
  7472. wnd=self.ws__desktops.term:wndFromPoint(p2,p3)\
  7473. end\
  7474. self.ws__desktops.term.dt__dragWnd=wnd\
  7475. end\
  7476. self.ws__lastEventIdle=false\
  7477. elseif event==\"mouse_drag\" then\
  7478. if self.ws__desktops.term then\
  7479. p2=asnumber(p2)-1\
  7480. p3=asnumber(p3)-1\
  7481. if self.ws__desktops.term:capturedMouse()then\
  7482. wnd=self.ws__desktops.term:capturedMouse()\
  7483. else\
  7484. wnd=self.ws__desktops.term.dt__dragWnd\
  7485. end\
  7486. end\
  7487. self.ws__lastEventIdle=false\
  7488. elseif event==\"monitor_touch\" then\
  7489. local desktop=self:getDesktop(p1)\
  7490. if desktop then\
  7491. p2=asnumber(p2)-1\
  7492. p3=asnumber(p3)-1\
  7493. if desktop:capturedMouse()then\
  7494. wnd=desktop:capturedMouse()\
  7495. else\
  7496. wnd=desktop:wndFromPoint(p2,p3)\
  7497. end\
  7498. end\
  7499. self.ws__lastEventIdle=false\
  7500. elseif event==\"char\" or event==\"paste\" then\
  7501. if self.ws__desktops.term then\
  7502. wnd=self.ws__desktops.term:getFocusWnd()\
  7503. end\
  7504. self.ws__lastEventIdle=false\
  7505. elseif event==\"key\" then\
  7506. self:assessKey(p1,nil)\
  7507. if self.ws__desktops.term~=nil then\
  7508. if p1==keys.x and self:comboKeys(true,true,false)then\
  7509. wnd=self.ws__desktops.term:getActiveFrame()\
  7510. if wnd then\
  7511. event=\"frame_close\"\
  7512. p1=nil\
  7513. end\
  7514. elseif p1==keys.h and self:comboKeys(false,true,false)then\
  7515. if self.ws__desktops.term.dt__taskBar:isEnabled()then\
  7516. self.ws__desktops.term:showHomePage()\
  7517. end\
  7518. elseif p1==keys.l and self:comboKeys(false,true,false)then\
  7519. if self.ws__desktops.term.dt__taskBar:isEnabled()then\
  7520. self.ws__desktops.term:showListPage()\
  7521. end\
  7522. elseif p1==keys.k and self:comboKeys(true,true,false)then\
  7523. if self.ws__desktops.term.dt__taskBar:isEnabled()then\
  7524. self.ws__desktops.term:lockScreen()\
  7525. end\
  7526. elseif p1==keys.f10 and self:comboKeys(false,false,false)then\
  7527. self.ws__desktops.term:setFullscreen()\
  7528. else\
  7529. wnd=self.ws__desktops.term:getFocusWnd()\
  7530. p2=self:ctrlKey()\
  7531. p3=self:altKey()\
  7532. p4=self:shiftKey()\
  7533. end\
  7534. end\
  7535. self.ws__lastEventIdle=false\
  7536. elseif event==\"key_up\" then\
  7537. self:assessKey(nil,p1)\
  7538. wnd=self.ws__desktops.term:getFocusWnd()\
  7539. self.ws__lastEventIdle=false\
  7540. elseif event==\"mouse_scroll\" then\
  7541. if self.ws__desktops.term then\
  7542. p2=asnumber(p2)-1\
  7543. p3=asnumber(p3)-1\
  7544. if self.ws__desktops.term:capturedMouse()then\
  7545. wnd=self.ws__desktops.term:capturedMouse()\
  7546. else\
  7547. wnd=self.ws__desktops.term:wndFromPoint(p2,p3)\
  7548. end\
  7549. end\
  7550. self.ws__lastEventIdle=false\
  7551. elseif event==\"monitor_resize\" or event==\"term_resize\" then\
  7552. if self:getDesktop(p1)then\
  7553. self:getDesktop(p1):sendEvent(event,p1,p2,p3,p4,p5)\
  7554. end\
  7555. self.ws__lastEventIdle=false\
  7556. elseif event==\"system_msgbox\" then\
  7557. if self:getDesktop(p1)then\
  7558. wnd=self:getDesktop(p1):getActiveFrame()\
  7559. end\
  7560. self.ws__lastEventIdle=false\
  7561. elseif event==\"lock_screen\" then\
  7562. if self:getDesktop(p1)then\
  7563. wnd=self:getDesktop(p1):getActiveFrame()\
  7564. end\
  7565. self.ws__lastEventIdle=false\
  7566. else\
  7567. if event==\"peripheral_detach\" then\
  7568. if self.ws__desktops[p1]then\
  7569. self.ws__desktops[p1]:destroyWnd()\
  7570. self.ws__desktops[p1]=nil\
  7571. end\
  7572. end\
  7573. if event==\"modem_message\" then\
  7574. for i=1,#self.ws__comms,1 do\
  7575. self.ws__comms[i]:receive(p1,p2,p3,p4,p5)\
  7576. end\
  7577. end\
  7578. for i=1,#self.ws__wndEvents,1 do\
  7579. if self.ws__wndEvents[i][2]==event or self.ws__wndEvents[i][2]==\"*\" then\
  7580. self:pumpEvent(self.ws__wndEvents[i][1],event,p1,p2,p3,p4,p5,...)\
  7581. end\
  7582. end\
  7583. self.ws__lastEventIdle=false\
  7584. end\
  7585. self:pumpEvent(wnd,event,p1,p2,p3,p4,p5,...)\
  7586. if self.ws__eventCount<5 or(self.ws__lastUpdate+0.2)<os.clock()then\
  7587. for k,desktop in pairs(self.ws__desktops)do\
  7588. if desktop then\
  7589. if not desktop:update(false):isEmpty()then\
  7590. self.ws__lastUpdate=os.clock()\
  7591. end\
  7592. end\
  7593. end\
  7594. end\
  7595. end\
  7596. function createAppFrame()\
  7597. local appName=fs.getName(__ccwin.ws__appPath)\
  7598. __ccwin.ws__appFrame=applicationFrame:new(__ccwin.ws__appSide)\
  7599. if not __ccwin.ws__appFrame then\
  7600. error(\"Failed to create main frame in \"..appName,0)\
  7601. end\
  7602. __ccwin.ws__appFrame:setText(appName)\
  7603. __ccwin.ws__appFrame.appFrame__appRoutine=__ccwin.ws__appRoutine\
  7604. __ccwin.ws__appFrame.appFrame__appPath=__ccwin.ws__appPath\
  7605. __ccwin.ws__appRoutine=nil\
  7606. __ccwin.ws__appSide=nil\
  7607. __ccwin.ws__appPath=nil\
  7608. return __ccwin.ws__appFrame\
  7609. end\
  7610. function startWin(_shell)\
  7611. if not __ccwin then\
  7612. __shell=_shell\
  7613. __ccwin=workSpace:new()\
  7614. return __ccwin:startup()\
  7615. end\
  7616. return true\
  7617. end\
  7618. ",
  7619. "; start up delay\
  7620. delay=2\
  7621. \
  7622. ; system password\
  7623. ;password=password\
  7624. \
  7625. ; additional paths\
  7626. ;path=path\
  7627. \
  7628. ; run before starting win\
  7629. ;pre=path\
  7630. \
  7631. ; apis to load at startup\
  7632. api=/win/apis/cmndlg\
  7633. api=/win/apis/html\
  7634. \
  7635. ; comm\
  7636. ;comm=system\
  7637. ;systemtime=5\
  7638. ;systemport=80\
  7639. ;systemrelay=true\
  7640. ;systemwireless=true\
  7641. ",
  7642. "local inputClass=win.popupFrame:base()\
  7643. function inputClass:onCreate(title,prompt,banner,initialText,\
  7644. validate,maxLen,bgColor)\
  7645. self:dress(title)\
  7646. local width=math.floor(self:getDesktop():getWorkArea().width*0.8)\
  7647. if asnumber(bgColor)==0 then\
  7648. bgColor=self:getColors().popupBack\
  7649. end\
  7650. self.prompt=win.labelWindow:new(self,2,1,2,prompt)\
  7651. self.entry=win.inputWindow:new(self,3,1,3,width-2,\
  7652. initialText,banner)\
  7653. self.entry:setMaxLength(maxLen)\
  7654. self.entry:setSel(0,-1)\
  7655. self.entry:setFocus()\
  7656. self.ok=win.buttonWindow:new(self,4,width-5,4,\" Ok \")\
  7657. self.validateFunc=validate\
  7658. self.resultOk=false\
  7659. self.userInput=nil\
  7660. self:setBgColor(bgColor)\
  7661. self.prompt:setBgColor(bgColor)\
  7662. self:move(nil,nil,width,6)\
  7663. return true\
  7664. end\
  7665. function inputClass:onClose()\
  7666. if self.validateFunc and self.resultOk then\
  7667. if self.validateFunc(self.entry:getText())==false then\
  7668. self.resultOk=false\
  7669. self.entry:setError(true)\
  7670. self.entry:setSel(0,-1)\
  7671. self.entry:setFocus()\
  7672. return true\
  7673. end\
  7674. end\
  7675. self.userInput=self.entry:getText()\
  7676. return false\
  7677. end\
  7678. function inputClass:onEvent(event,p1,p2,p3,p4,p5,...)\
  7679. if event==\"btn_click\" then\
  7680. if p1:getId()==4 then\
  7681. self.resultOk=true\
  7682. self:close(4)\
  7683. return true\
  7684. end\
  7685. end\
  7686. return false\
  7687. end\
  7688. function inputClass:onMove()\
  7689. win.popupFrame.onMove(self)\
  7690. self.prompt:move(nil,nil,self.width-2)\
  7691. self.entry:move(nil,nil,self.width-2)\
  7692. self.ok:move(self.width-5)\
  7693. end\
  7694. function input(ownerFrame,title,prompt,initialText,banner,maxLen,\
  7695. validate,bgColor)\
  7696. assert(ownerFrame,\"cmndlg.input() must have an owner frame.\")\
  7697. assert(ownerFrame.onFrameActivate,\
  7698. \"cmndlg.input() must have an owner frame.\")\
  7699. assert(ownerFrame.wnd__popup==nil,\
  7700. \"cmndlg.input() owner frame already has popup.\")\
  7701. local dlg=inputClass:new(ownerFrame)\
  7702. if dlg then\
  7703. if dlg:doModal(title,prompt,banner,initialText,validate,maxLen,bgColor)==4 then\
  7704. return dlg.userInput\
  7705. end\
  7706. end\
  7707. return nil\
  7708. end\
  7709. local confirmClass=win.popupFrame:base()\
  7710. function confirmClass:onCreate(title,message,defaultOk,bgColor)\
  7711. title=asstring(title)\
  7712. message=asstring(message)\
  7713. local rtWork=self:getDesktop():getWorkArea()\
  7714. local maxWidth,maxHeight=\
  7715. math.floor(rtWork.width*0.8),math.floor(rtWork.height*0.8)\
  7716. local width,height=string.wrapSize(string.wrap(message,maxWidth-2))\
  7717. if width==(maxWidth-2)and height>=(maxHeight-4)then\
  7718. width,height=string.wrapSize(string.wrap(message,maxWidth-3))\
  7719. end\
  7720. width=width+2\
  7721. height=height+4\
  7722. if width<(title:len()+3)then\
  7723. width=title:len()+3\
  7724. end\
  7725. if height<5 then\
  7726. height=5\
  7727. elseif height>maxHeight then\
  7728. height=maxHeight\
  7729. end\
  7730. if asnumber(bgColor)==0 then\
  7731. bgColor=self:getColors().popupBack\
  7732. end\
  7733. self:dress(title)\
  7734. self.message=win.textWindow:new(self,2,1,2,width-2,\
  7735. height-4,message)\
  7736. self.ok=win.buttonWindow:new(self,3,\
  7737. math.floor((width-4)/2),height-2,\" Ok \")\
  7738. if defaultOk then\
  7739. self.ok:setFocus()\
  7740. end\
  7741. self:setBgColor(bgColor)\
  7742. self.message:setBgColor(bgColor)\
  7743. self:move(nil,nil,width,height)\
  7744. return true\
  7745. end\
  7746. function confirmClass:onEvent(event,p1,p2,p3,p4,p5,...)\
  7747. if event==\"btn_click\" then\
  7748. if p1:getId()==3 then\
  7749. self:close(3)\
  7750. return true\
  7751. end\
  7752. end\
  7753. return false\
  7754. end\
  7755. function confirmClass:onMove()\
  7756. win.popupFrame.onMove(self)\
  7757. self.message:move(1,2,self.width-2,self.height-4)\
  7758. self.ok:move(math.floor((self.width-4)/2),self.height-2)\
  7759. end\
  7760. function confirm(ownerFrame,title,message,defaultOk,bgColor)\
  7761. assert(ownerFrame,\"cmndlg.confirm() must have an owner frame.\")\
  7762. assert(ownerFrame.onFrameActivate,\
  7763. \"cmndlg.confirm() must have an owner frame.\")\
  7764. assert(ownerFrame.wnd__popup==nil,\
  7765. \"cmndlg.confirm() owner frame already has popup.\")\
  7766. local dlg=confirmClass:new(ownerFrame)\
  7767. if dlg then\
  7768. if dlg:doModal(title,message,defaultOk,bgColor)==3 then\
  7769. return true\
  7770. end\
  7771. end\
  7772. return false\
  7773. end\
  7774. local fileDlgClass=win.popupFrame:base()\
  7775. function fileDlgClass:onCreate(title,initialPath,promptOverwrite,\
  7776. notHidden,notReadonly,hideNewDir,validate,bgColor)\
  7777. local rtWork=self:getDesktop():getWorkArea()\
  7778. local width,height=math.floor(rtWork.width*0.8),\
  7779. math.floor(rtWork.height*0.8)\
  7780. initialPath=asstring(initialPath)\
  7781. local fileName=\"\"\
  7782. self.curDir=\"/\"\
  7783. if initialPath:len()>0 then\
  7784. fileName=fs.getName(initialPath)\
  7785. if fileName:len()>0 then\
  7786. self.curDir=initialPath:sub(1,-(fileName:len()+1))\
  7787. else\
  7788. self.curDir=initialPath\
  7789. end\
  7790. end\
  7791. if self.curDir:sub(-1,-1)~=\"/\" then\
  7792. self.curDir=self.curDir..\"/\"\
  7793. end\
  7794. if asnumber(bgColor)==0 then\
  7795. bgColor=self:getColors().popupBack\
  7796. end\
  7797. self:dress(title)\
  7798. self.promptOverwrite=promptOverwrite\
  7799. self.notHidden=notHidden\
  7800. self.notReadonly=notReadonly\
  7801. self.dirLabel=win.labelWindow:new(self,2,1,1,self.curDir)\
  7802. self.dirLabel:move(nil,nil,width-7)\
  7803. self.dirLabel:setBgColor(bgColor)\
  7804. self.fileList=win.listWindow:new(self,3,1,2,width-2,height-5)\
  7805. self.fileName=win.inputWindow:new(self,4,1,height-2,\
  7806. width-6,fileName,\"File name\")\
  7807. self.fileName:setSel(0,-1)\
  7808. self.fileName:setFocus()\
  7809. self.ok=win.buttonWindow:new(self,5,width-5,height-2,\" Ok \")\
  7810. self.mkdir=win.buttonWindow:new(self,6,width-6,1,\" new \")\
  7811. self.mkdir:show(hideNewDir~=true)\
  7812. self.validateFunc=validate\
  7813. self.resultOk=false\
  7814. self.fullPath=nil\
  7815. self:setBgColor(bgColor)\
  7816. self:move(nil,nil,width,height)\
  7817. self:loadFileList()\
  7818. return true\
  7819. end\
  7820. function fileDlgClass:newDirectory()\
  7821. local bgColor=colors.orange\
  7822. if self:getBgColor()==colors.orange then\
  7823. bgColor=colors.yellow\
  7824. end\
  7825. local folder=input(self,\"New Folder\",\"Enter new folder name.\",\
  7826. \"Folder\",\"new\",nil,nil,bgColor)\
  7827. if folder then\
  7828. fs.makeDir(self.curDir..folder)\
  7829. self:loadFileList()\
  7830. end\
  7831. end\
  7832. function fileDlgClass:checkOverwrite()\
  7833. if self.promptOverwrite and fs.exists(self:getFullPath())then\
  7834. local bgColor=colors.orange\
  7835. if self:getBgColor()==colors.orange then\
  7836. bgColor=colors.yellow\
  7837. end\
  7838. if not confirm(self,\"Overwrite\",\
  7839. \"File \\\"\"..self:getFullPath()..\"\\\" already exists.\\nOverwrite?\",\
  7840. false,bgColor)then\
  7841. return\
  7842. end\
  7843. end\
  7844. self.resultOk=true\
  7845. self:close(5)\
  7846. end\
  7847. function fileDlgClass:getFullPath()\
  7848. return self.curDir..self.fileName:getText()\
  7849. end\
  7850. function fileDlgClass:loadFileList()\
  7851. if not fs.isDir(self.curDir)then\
  7852. self.curDir=\"/\"\
  7853. end\
  7854. local fileList=fs.list(self.curDir)\
  7855. table.sort(fileList)\
  7856. self.fileList:resetContent()\
  7857. if self.curDir:len()>1 then\
  7858. self.fileList:addString(\"..\",{id=0,name=\"..\"})\
  7859. end\
  7860. for i=1,#fileList,1 do\
  7861. if fs.isDir(self.curDir..fileList[i])then\
  7862. if(not self.notReadonly or not fs.isReadOnly(self.curDir..fileList[i]))then\
  7863. self.fileList:addString(\"/\"..fileList[i],{id=1,name=fileList[i]})\
  7864. end\
  7865. end\
  7866. end\
  7867. for i=1,#fileList,1 do\
  7868. if not fs.isDir(self.curDir..fileList[i])then\
  7869. if(not self.notReadonly or not fs.isReadOnly(self.curDir..fileList[i]))and\
  7870. (not self.notHidden or fileList[i]:sub(1,1)~=\".\")then\
  7871. self.fileList:addString(fileList[i],{id=2,name=fileList[i]})\
  7872. end\
  7873. end\
  7874. end\
  7875. self.dirLabel:setText(self.curDir)\
  7876. self.dirLabel:invalidate()\
  7877. end\
  7878. function fileDlgClass:onClose()\
  7879. if self.validateFunc and self.resultOk then\
  7880. if self.validateFunc(self:getFullPath())==false then\
  7881. self.resultOk=false\
  7882. self.fileName:setError(true)\
  7883. self.fileName:setSel(0,-1)\
  7884. self.fileName:setFocus()\
  7885. return true\
  7886. end\
  7887. end\
  7888. self.fullPath=self:getFullPath()\
  7889. return false\
  7890. end\
  7891. function fileDlgClass:onEvent(event,p1,p2,p3,p4,p5,...)\
  7892. if event==\"btn_click\" then\
  7893. if p1:getId()==5 then\
  7894. if self.fileName:getText():len()>0 then\
  7895. self:checkOverwrite()\
  7896. end\
  7897. return true\
  7898. elseif p1:getId()==6 then\
  7899. self:newDirectory()\
  7900. return true\
  7901. end\
  7902. elseif event==\"list_click\" then\
  7903. if p1:getId()==3 then\
  7904. if self.fileList:getData()then\
  7905. if self.fileList:getData().id==2 then\
  7906. self.fileName:setText(self.fileList:getData().name)\
  7907. self.fileName:setSel(0,-1)\
  7908. end\
  7909. end\
  7910. return true\
  7911. end\
  7912. elseif event==\"list_double_click\" then\
  7913. if p1:getId()==3 then\
  7914. if self.fileList:getData()then\
  7915. if self.fileList:getData().id==0 then\
  7916. if self.curDir:len()>1 then\
  7917. self.curDir=self.curDir:sub(1,-2)\
  7918. local lastDir=fs.getName(self.curDir)\
  7919. self.curDir=self.curDir:sub(1,-(lastDir:len()+1))\
  7920. self:loadFileList()\
  7921. end\
  7922. elseif self.fileList:getData().id==1 then\
  7923. self.curDir=self.curDir..self.fileList:getData().name..\"/\"\
  7924. self:loadFileList()\
  7925. elseif self.fileList:getData().id==2 then\
  7926. self.fileName:setText(self.fileList:getData().name)\
  7927. self.fileName:setSel(0,-1)\
  7928. self:checkOverwrite()\
  7929. end\
  7930. end\
  7931. return true\
  7932. end\
  7933. end\
  7934. return false\
  7935. end\
  7936. function fileDlgClass:onResize()\
  7937. local rtWork=self:getDesktop():getWorkArea()\
  7938. self:move(nil,nil,math.floor(rtWork.width*0.8),math.floor(rtWork.height*0.8))\
  7939. win.popupFrame.onResize(self)\
  7940. self.dirLabel:move(nil,nil,self.width-7)\
  7941. self.fileList:move(1,2,self.width-2,self.height-5)\
  7942. self.fileName:move(1,self.height-3,self.width-6)\
  7943. self.ok:move(self.width-5,self.height-2)\
  7944. self.mkdir:move(self.width-6)\
  7945. end\
  7946. function file(ownerFrame,title,initialPath,promptOverwrite,\
  7947. notHidden,notReadonly,hideNewDir,validate,bgColor)\
  7948. assert(ownerFrame,\"cmndlg.file() must have an owner frame.\")\
  7949. assert(ownerFrame.onFrameActivate,\
  7950. \"cmndlg.file() must have an owner frame.\")\
  7951. assert(ownerFrame.wnd__popup==nil,\
  7952. \"cmndlg.file() owner frame already has popup.\")\
  7953. local dlg=fileDlgClass:new(ownerFrame)\
  7954. if dlg then\
  7955. if dlg:doModal(title,initialPath,promptOverwrite,notHidden,\
  7956. notReadonly,hideNewDir,validate,bgColor)==5 then\
  7957. return dlg.fullPath\
  7958. end\
  7959. end\
  7960. return nil\
  7961. end\
  7962. function saveFile(ownerFrame,initialPath,notHidden,validate,bgColor)\
  7963. assert(ownerFrame,\"cmndlg.saveFile() must have an owner frame.\")\
  7964. assert(ownerFrame.onFrameActivate,\
  7965. \"cmndlg.saveFile() must have an owner frame.\")\
  7966. assert(ownerFrame.wnd__popup==nil,\
  7967. \"cmndlg.saveFile() owner frame already has popup.\")\
  7968. return file(ownerFrame,\"Save File\",initialPath,true,\
  7969. notHidden,true,false,validate,bgColor)\
  7970. end\
  7971. function openFile(ownerFrame,initialPath,notHidden,notReadonly,validate,bgColor)\
  7972. assert(ownerFrame,\"cmndlg.openFile() must have an owner frame.\")\
  7973. assert(ownerFrame.onFrameActivate,\
  7974. \"cmndlg.openFile() must have an owner frame.\")\
  7975. assert(ownerFrame.wnd__popup==nil,\
  7976. \"cmndlg.openFile() owner frame already has popup.\")\
  7977. local function validatePath(path)\
  7978. if not fs.exists(path)then\
  7979. return false\
  7980. end\
  7981. if validate then\
  7982. return validate(result,path)\
  7983. end\
  7984. return true\
  7985. end\
  7986. return file(ownerFrame,\"Open File\",initialPath,false,\
  7987. notHidden,notReadonly,true,validatePath,bgColor)\
  7988. end\
  7989. function getPrinters()\
  7990. local devices=peripheral.getNames()\
  7991. local printers={}\
  7992. for i=1,#devices,1 do\
  7993. if peripheral.getType(devices[i])==\"printer\" then\
  7994. printers[#printers+1]=devices[i]\
  7995. end\
  7996. end\
  7997. return printers\
  7998. end\
  7999. local printDlgClass=win.popupFrame:base()\
  8000. function printDlgClass:onCreate(totalPages,bgColor)\
  8001. local width=math.floor(self:getDesktop():getWorkArea().width*0.8)\
  8002. if asnumber(bgColor)==0 then\
  8003. bgColor=self:getColors().popupBack\
  8004. end\
  8005. self:dress(\"Print\")\
  8006. self.prompt=win.labelWindow:new(self,2,1,1,\"Select printer\")\
  8007. self.printers=win.listWindow:new(self,3,1,2,width-2,4)\
  8008. self.printers:setFocus()\
  8009. local printers=getPrinters()\
  8010. for i=1,#printers,1 do\
  8011. self.printers:addString(printers[i])\
  8012. end\
  8013. self.pagesLabel=win.labelWindow:new(self,4,1,6,\"Pages\")\
  8014. if totalPages then\
  8015. self.totalPages=asnumber(totalPages)\
  8016. if self.totalPages>0 then\
  8017. self.fromPage=win.inputWindow:new(self,5,1,7,4,\"1\",\"From\")\
  8018. self.toPage=win.inputWindow:new(self,6,6,7,4,\
  8019. asstring(totalPages),\"To\")\
  8020. else\
  8021. self.totalPages=0\
  8022. self.fromPage=win.inputWindow:new(self,5,1,7,4,\"\",\"From\")\
  8023. self.toPage=win.inputWindow:new(self,6,6,7,4,\"\",\"To\")\
  8024. end\
  8025. else\
  8026. self.totalPages=0\
  8027. self.fromPage=win.inputWindow:new(self,5,1,7,4,\"\",\"From\")\
  8028. self.toPage=win.inputWindow:new(self,6,6,7,4,\"\",\"To\")\
  8029. self.fromPage:show(false)\
  8030. self.toPage:show(false)\
  8031. self.pagesLabel:show(false)\
  8032. end\
  8033. self.ok=win.buttonWindow:new(self,7,width-5,7,\" Ok \")\
  8034. self.resultOk=false\
  8035. self.printerName=nil\
  8036. self.pageFirst=nil\
  8037. self.pageLast=nil\
  8038. self:setBgColor(bgColor)\
  8039. self.prompt:setBgColor(bgColor)\
  8040. self.pagesLabel:setBgColor(bgColor)\
  8041. self:move(nil,nil,width,9)\
  8042. return true\
  8043. end\
  8044. function printDlgClass:onClose()\
  8045. self.printerName=self.printers:getString()\
  8046. self.pageFirst=asnumber(self.fromPage:getText())\
  8047. self.pageLast=asnumber(self.toPage:getText())\
  8048. return false\
  8049. end\
  8050. function printDlgClass:onEvent(event,p1,p2,p3,p4,p5,...)\
  8051. if event==\"btn_click\" then\
  8052. if p1:getId()==7 then\
  8053. if self.printers:getCurSel()~=0 then\
  8054. self.resultOk=true\
  8055. self:close(7)\
  8056. else\
  8057. self.printers:setFocus()\
  8058. end\
  8059. return true\
  8060. end\
  8061. elseif event==\"input_change\" then\
  8062. if p1:getId()==5 or p1:getId()==6 then\
  8063. local page=asnumber(p1:getText())\
  8064. if page<1 then\
  8065. p1:setText(\"1\")\
  8066. p1:invalidate()\
  8067. elseif self.totalPages>0 and page>self.totalPages then\
  8068. p1:setText(asstring(self.totalPages))\
  8069. p1:invalidate()\
  8070. end\
  8071. return true\
  8072. end\
  8073. end\
  8074. return false\
  8075. end\
  8076. function printDlgClass:onMove()\
  8077. win.popupFrame.onMove(self)\
  8078. self.prompt:move(nil,nil,self.width-2)\
  8079. self.printers:move(nil,nil,self.width-2)\
  8080. self.ok:move(self.width-5)\
  8081. end\
  8082. function print(ownerFrame,totalPages,bgColor)\
  8083. assert(ownerFrame,\"cmndlg.print() must have an owner frame.\")\
  8084. assert(ownerFrame.onFrameActivate,\
  8085. \"cmndlg.print() must have an owner frame.\")\
  8086. assert(ownerFrame.wnd__popup==nil,\
  8087. \"cmndlg.print() owner frame already has popup.\")\
  8088. local dlg=printDlgClass:new(ownerFrame)\
  8089. if dlg then\
  8090. if dlg:doModal(totalPages,bgColor)==7 then\
  8091. return dlg.printerName,dlg.pageFirst,dlg.pageLast\
  8092. end\
  8093. end\
  8094. return nil\
  8095. end\
  8096. local pickColorClass=win.popupFrame:base()\
  8097. function pickColorClass:onCreate(initColor,bgColor)\
  8098. if asnumber(bgColor)==0 then\
  8099. bgColor=self:getColors().popupBack\
  8100. end\
  8101. self:dress(\"Color\")\
  8102. local color=colors.white\
  8103. for y=2,3,1 do\
  8104. for x=1,8,1 do\
  8105. local btn=win.buttonWindow:new(self,color,x,y,\"#\")\
  8106. btn:setColors(color,colors.white,self:getColors().buttonFocus)\
  8107. color=color*2\
  8108. end\
  8109. end\
  8110. if not initColor then\
  8111. initColor=colors.black\
  8112. end\
  8113. if not self:getWndById(initColor)then\
  8114. initColor=colors.black\
  8115. end\
  8116. self:getWndById(initColor):setFocus()\
  8117. self.selected=win.labelWindow:new(self,32770,1,5,\"  \")\
  8118. self.selected:setBgColor(initColor)\
  8119. self.ok=win.buttonWindow:new(self,32771,5,5,\" Ok \")\
  8120. self.resultOk=false\
  8121. self.userColor=nil\
  8122. self:setBgColor(bgColor)\
  8123. self:move(nil,nil,10,7)\
  8124. return true\
  8125. end\
  8126. function pickColorClass:onClose(result)\
  8127. self.userColor=self.selected:getBgColor()\
  8128. return false\
  8129. end\
  8130. function pickColorClass:onEvent(event,p1,p2,p3,p4,p5,...)\
  8131. if event==\"btn_click\" then\
  8132. if p1:getId()==32771 then\
  8133. self.resultOk=true\
  8134. self:close(32771)\
  8135. return true\
  8136. elseif p1:getId()>=colors.white and p1:getId()<=colors.black then\
  8137. self.selected:setBgColor(p1:getId())\
  8138. return true\
  8139. end\
  8140. end\
  8141. return false\
  8142. end\
  8143. function color(ownerFrame,initColor,bgColor)\
  8144. assert(ownerFrame,\"cmndlg.color() must have an owner frame.\")\
  8145. assert(ownerFrame.onFrameActivate,\
  8146. \"cmndlg.color() must have an owner frame.\")\
  8147. assert(ownerFrame.wnd__popup==nil,\
  8148. \"cmndlg.color() owner frame already has popup.\")\
  8149. local dlg=pickColorClass:new(ownerFrame)\
  8150. if dlg then\
  8151. if dlg:doModal(initColor,bgColor)==32771 then\
  8152. return dlg.userColor\
  8153. end\
  8154. end\
  8155. return nil\
  8156. end\
  8157. ",
  8158. "local htmlColors=\
  8159. {\
  8160. [\"white\"]=1,\
  8161. [\"1\"]=1,\
  8162. [\"orange\"]=2,\
  8163. [\"2\"]=2,\
  8164. [\"magenta\"]=4,\
  8165. [\"4\"]=4,\
  8166. [\"lightBlue\"]=8,\
  8167. [\"sky\"]=8,\
  8168. [\"8\"]=8,\
  8169. [\"yellow\"]=16,\
  8170. [\"16\"]=16,\
  8171. [\"lime\"]=32,\
  8172. [\"32\"]=32,\
  8173. [\"pink\"]=64,\
  8174. [\"64\"]=64,\
  8175. [\"gray\"]=128,\
  8176. [\"grey\"]=128,\
  8177. [\"128\"]=128,\
  8178. [\"lightGray\"]=256,\
  8179. [\"lightGrey\"]=256,\
  8180. [\"light\"]=256,\
  8181. [\"silver\"]=256,\
  8182. [\"256\"]=256,\
  8183. [\"cyan\"]=512,\
  8184. [\"512\"]=512,\
  8185. [\"purple\"]=1024,\
  8186. [\"1024\"]=1024,\
  8187. [\"blue\"]=2048,\
  8188. [\"2048\"]=2048,\
  8189. [\"brown\"]=4096,\
  8190. [\"4096\"]=4096,\
  8191. [\"green\"]=8192,\
  8192. [\"8192\"]=8192,\
  8193. [\"red\"]=16384,\
  8194. [\"16384\"]=16384,\
  8195. [\"black\"]=32768,\
  8196. [\"32768\"]=32768\
  8197. }\
  8198. local htmlColorNames=\
  8199. {\
  8200. [\"1\"]=\"white\",\
  8201. [\"2\"]=\"orange\",\
  8202. [\"4\"]=\"magenta\",\
  8203. [\"8\"]=\"sky\",\
  8204. [\"16\"]=\"yellow\",\
  8205. [\"32\"]=\"lime\",\
  8206. [\"64\"]=\"pink\",\
  8207. [\"128\"]=\"gray\",\
  8208. [\"256\"]=\"silver\",\
  8209. [\"512\"]=\"cyan\",\
  8210. [\"1024\"]=\"purple\",\
  8211. [\"2048\"]=\"blue\",\
  8212. [\"4096\"]=\"brown\",\
  8213. [\"8192\"]=\"green\",\
  8214. [\"16384\"]=\"red\",\
  8215. [\"32768\"]=\"black\"\
  8216. }\
  8217. htmlDoc=win.__classBase:base()\
  8218. function htmlDoc:constructor(doc)\
  8219. self.html__type=\"text\"\
  8220. self:parse(doc)\
  8221. return self\
  8222. end\
  8223. function htmlDoc:color(color)\
  8224. return htmlColors[tostring(color or \"none\")]\
  8225. end\
  8226. function htmlDoc:colorName(color)\
  8227. return htmlColorNames[tostring(htmlDoc:color(color)or \"none\")]\
  8228. end\
  8229. function htmlDoc:type()\
  8230. return self.html__type\
  8231. end\
  8232. function htmlDoc:isHtml(doc)\
  8233. if type(doc)==\"table\" then\
  8234. if type(doc.html)==\"table\" then\
  8235. return doc\
  8236. end\
  8237. end\
  8238. local success,newDoc=pcall(textutils.unserialize,tostring(doc or \"\"))\
  8239. if success and type(newDoc)==\"table\" then\
  8240. if type(newDoc.html)==\"table\" then\
  8241. return newDoc\
  8242. end\
  8243. end\
  8244. return nil\
  8245. end\
  8246. function htmlDoc:parseNode(node,defTag)\
  8247. if type(node)==\"table\" then\
  8248. local tag={}\
  8249. for k,v in pairs(node)do\
  8250. if type(k)==\"string\" then\
  8251. if type(v)==\"string\" or type(v)==\"number\" then\
  8252. if k==\"color\" or k==\"bgcolor\" or k==\"linkcolor\" then\
  8253. tag[k]=htmlDoc:color(v)\
  8254. elseif k==\"width\" then\
  8255. tag[k]=tonumber(v)\
  8256. else\
  8257. if k==\"protocol\" then\
  8258. v=tostring(v)\
  8259. if v:sub(-1,-1)~=\":\" then\
  8260. v=v..\":\"\
  8261. end\
  8262. end\
  8263. tag[k]=v\
  8264. end\
  8265. end\
  8266. end\
  8267. end\
  8268. if defTag and not tag.tag then\
  8269. tag.tag=defTag\
  8270. end\
  8271. for i=1,#node,1 do\
  8272. tag[#tag+1]=self:parseNode(node[i])\
  8273. end\
  8274. for i=1,#tag,1 do\
  8275. if type(tag[i])==\"string\" then\
  8276. while(i+1)<=#tag and type(tag[i+1])==\"string\" do\
  8277. tag[i]=tag[i]..tag[i+1]\
  8278. table.remove(tag,i+1)\
  8279. end\
  8280. end\
  8281. end\
  8282. return tag\
  8283. end\
  8284. return tostring(node or \"\")\
  8285. end\
  8286. function htmlDoc:parse(content)\
  8287. local doc=htmlDoc:isHtml(content)\
  8288. self.html=\
  8289. {\
  8290. head={},\
  8291. body={tostring(content or \"\")}\
  8292. }\
  8293. self.html__type=\"text\"\
  8294. if doc then\
  8295. self.html__type=\"html\"\
  8296. if type(doc.html.head)==\"table\" then\
  8297. self.html.head=self:parseNode(doc.html.head)\
  8298. end\
  8299. if type(doc.html.body)==\"table\" then\
  8300. self.html.body=self:parseNode(doc.html.body)\
  8301. end\
  8302. return\
  8303. end\
  8304. end\
  8305. function htmlDoc:serializeNode(node,indent)\
  8306. local didBreak=false\
  8307. local str=\"{\"\
  8308. if node.tag then\
  8309. str=string.format(\"%s tag = %q,\",str,tostring(node.tag))\
  8310. end\
  8311. for k,v in pairs(node)do\
  8312. if type(k)==\"string\" and k~=\"tag\"then\
  8313. if k==\"color\" or k==\"bgcolor\" or k==\"linkcolor\" then\
  8314. v=htmlDoc:colorName(v)\
  8315. end\
  8316. if type(v)==\"number\" then\
  8317. str=string.format(\"%s %s = %s,\",str,k,tostring(v))\
  8318. elseif type(v)==\"string\" then\
  8319. str=string.format(\"%s %s = %q,\",str,k,v)\
  8320. end\
  8321. end\
  8322. end\
  8323. if node.tag==\"p\" and #node>0 then\
  8324. str=str..\"\\n \"..indent\
  8325. didBreak=true\
  8326. end\
  8327. for i=1,#node,1 do\
  8328. if type(node[i])==\"table\" then\
  8329. if node[i].tag==\"p\" then\
  8330. str=string.format(\"%s\\n  %s%s\",str,indent,\
  8331. self:serializeNode(node[i],indent..\"  \"))\
  8332. didBreak=true\
  8333. else\
  8334. str=str..\" \"..self:serializeNode(node[i],indent..\"  \")\
  8335. end\
  8336. elseif type(node[i])==\"string\" then\
  8337. str=string.format(\"%s %q,\",str,node[i])\
  8338. end\
  8339. end\
  8340. if didBreak then\
  8341. return str:sub(1,-2)..\"\\n\"..indent..\"},\"\
  8342. end\
  8343. return str:sub(1,-2)..\" },\"\
  8344. end\
  8345. function htmlDoc:getHtml()\
  8346. return string.format(\"{\\n  html = {\\n    head = %s\\n    body = %s\\n  }\\n}\",\
  8347. self:serializeNode(self.html.head,\"    \"),\
  8348. self:serializeNode(self.html.body,\"    \"))\
  8349. end\
  8350. local function html_nodeToText(node)\
  8351. local str=\"\"\
  8352. for i=1,#node,1 do\
  8353. if type(node[i])==\"table\" then\
  8354. str=str..html_nodeToText(node[i])\
  8355. elseif type(node[i])==\"string\" then\
  8356. str=str..node[i]\
  8357. end\
  8358. end\
  8359. if node.tag==\"p\" then\
  8360. str=str..\"\\n\\n\"\
  8361. end\
  8362. return str\
  8363. end\
  8364. function htmlDoc:getText()\
  8365. if self:type()==\"text\" then\
  8366. return self.html.body[1]\
  8367. end\
  8368. return html_nodeToText(self.html.body)\
  8369. end\
  8370. function htmlDoc:serialize()\
  8371. if self:type()==\"text\" then\
  8372. return self:getText()\
  8373. end\
  8374. return self:getHtml()\
  8375. end\
  8376. function htmlDoc:getWidth()\
  8377. if type(self.html)==\"table\" then\
  8378. if type(self.html.body)==\"table\" then\
  8379. if self.html.body.width then\
  8380. return asnumber(self.html.body.width)\
  8381. end\
  8382. end\
  8383. end\
  8384. return 0\
  8385. end\
  8386. local htmlMap=win.__classBase:base()\
  8387. function htmlMap:constructor(width,color,bgcolor)\
  8388. self.line=0\
  8389. self.column=0\
  8390. self.width=width\
  8391. self.color=color\
  8392. self.bgcolor=bgcolor\
  8393. return self\
  8394. end\
  8395. function htmlMap:add(color,bgcolor,align,erase,node,text)\
  8396. local current,newLine;\
  8397. text=tostring(text or \"\")\
  8398. repeat\
  8399. current,text,newLine=string.splice(text,self.width-self.column)\
  8400. if current:len()>0 then\
  8401. self[#self+1]=\
  8402. {\
  8403. node=node,\
  8404. color=color,\
  8405. bgcolor=bgcolor,\
  8406. align=align,\
  8407. erase=erase,\
  8408. line=self.line,\
  8409. column=self.column,\
  8410. text=current\
  8411. }\
  8412. self.column=self.column+current:len()\
  8413. end\
  8414. if newLine then\
  8415. self:advance(color,bgcolor,align,erase,node)\
  8416. end\
  8417. until not text\
  8418. end\
  8419. function htmlMap:lastLine()\
  8420. if #self>0 then\
  8421. return self[#self].line\
  8422. end\
  8423. return-1\
  8424. end\
  8425. function htmlMap:lines()\
  8426. return self:lastLine()+1\
  8427. end\
  8428. function htmlMap:advance(color,bgcolor,align,erase,node)\
  8429. if self:lastLine()<self.line then\
  8430. self[#self+1]=\
  8431. {\
  8432. node=node,\
  8433. color=color,\
  8434. bgcolor=bgcolor,\
  8435. align=align,\
  8436. erase=erase,\
  8437. line=self.line,\
  8438. column=self.column,\
  8439. text=\"\"\
  8440. }\
  8441. end\
  8442. self.line=self.line+1\
  8443. self.column=0\
  8444. end\
  8445. function htmlMap:startBlock(color,bgcolor,align,erase,node)\
  8446. if self.column>0 then\
  8447. self:advance(color,bgcolor,align,erase,node)\
  8448. end\
  8449. end\
  8450. function htmlMap:setAlignment()\
  8451. local first=1\
  8452. while first<=#self do\
  8453. if self[first].align==\"right\" or self[first].align==\"center\" then\
  8454. local lead=self.width\
  8455. local last=first\
  8456. for i=first+1,#self,1 do\
  8457. if self[i].line==self[first].line then\
  8458. last=i\
  8459. else\
  8460. break\
  8461. end\
  8462. end\
  8463. for i=first,last,1 do\
  8464. lead=lead-self[i].text:len()\
  8465. end\
  8466. if self[first].align==\"center\" then\
  8467. lead=math.modf(lead/2)\
  8468. end\
  8469. for i=first,last,1 do\
  8470. self[i].column=self[i].column+lead\
  8471. end\
  8472. first=last\
  8473. end\
  8474. first=first+1\
  8475. end\
  8476. end\
  8477. function htmlMap:getRange(firstLine,lastLine)\
  8478. local firstMap,lastMap=nil,nil\
  8479. lastLine=lastLine or firstLine\
  8480. for i=1,#self,1 do\
  8481. if self[i].line>=firstLine then\
  8482. firstMap=i\
  8483. break\
  8484. end\
  8485. end\
  8486. if firstMap then\
  8487. if self[firstMap].line>lastLine then\
  8488. firstMap=nil\
  8489. else\
  8490. for i=firstMap+1,#self,1 do\
  8491. if self[i].line>lastLine then\
  8492. lastMap=i-1\
  8493. break\
  8494. end\
  8495. end\
  8496. if not lastMap then\
  8497. lastMap=#self\
  8498. end\
  8499. end\
  8500. end\
  8501. return firstMap,lastMap\
  8502. end\
  8503. function htmlMap:nodeFromPoint(x,y)\
  8504. local first,last=self:getRange(y)\
  8505. if first then\
  8506. for i=first,last,1 do\
  8507. if x>=self[i].column and x<(self[i].column+self[i].text:len())then\
  8508. return self[i].node\
  8509. end\
  8510. end\
  8511. end\
  8512. return nil\
  8513. end\
  8514. function htmlMap:getWidth()\
  8515. return self.width\
  8516. end\
  8517. browserWindow=win.window:base()\
  8518. function browserWindow:constructor(parent,id,x,y,width,height)\
  8519. if not win.window.constructor(self,parent,id,x,y,width,height)then\
  8520. return nil\
  8521. end\
  8522. self.brws__doc=nil\
  8523. self.brws__map=nil\
  8524. self:setWantFocus(false)\
  8525. self:setText()\
  8526. return self\
  8527. end\
  8528. function browserWindow:getTitle(title)\
  8529. if self.brws__doc.html.head.title then\
  8530. return tostring(self.brws__doc.html.head.title)\
  8531. end\
  8532. return title\
  8533. end\
  8534. function browserWindow:mapNode(map,node,color,bgcolor,linkcolor,align,erase)\
  8535. if node.tag==\"a\" then\
  8536. color=node.color or linkcolor\
  8537. else\
  8538. color=node.color or color\
  8539. end\
  8540. bgcolor=node.bgcolor or bgcolor\
  8541. if node.tag==\"l\" then\
  8542. local lwidth=math.max(math.modf((map.width/100)*\
  8543. math.min(math.abs(node.width or 100),100)),1)\
  8544. local lchar=node.char or \"-\"\
  8545. align=node.align or align\
  8546. if lchar:len()<1 then\
  8547. lchar=\"-\"\
  8548. else\
  8549. lchar=lchar:sub(1,1)\
  8550. end\
  8551. map:startBlock(color,bgcolor,align,erase,node)\
  8552. map:add(color,bgcolor,align,erase,node,string.rep(lchar,lwidth))\
  8553. map:startBlock(color,bgcolor,align,erase,node)\
  8554. return\
  8555. end\
  8556. if node.tag==\"p\" or node.tag==\"d\" then\
  8557. align=node.align or align\
  8558. if node.bgcolor then\
  8559. erase=node.bgcolor\
  8560. end\
  8561. map:startBlock(color,bgcolor,align,erase,node)\
  8562. end\
  8563. for i=1,#node,1 do\
  8564. if type(node[i])==\"table\" then\
  8565. self:mapNode(map,node[i],color,bgcolor,linkcolor,align,erase)\
  8566. if node[i].tag==\"p\" then\
  8567. map:startBlock(color,bgcolor,align,erase,node)\
  8568. map:advance(color,bgcolor,align,erase,node)\
  8569. elseif node[i].tag==\"d\" then\
  8570. map:startBlock(color,bgcolor,align,erase,node)\
  8571. end\
  8572. elseif type(node[i])==\"string\" then\
  8573. map:add(color,bgcolor,align,erase,node,node[i])\
  8574. end\
  8575. end\
  8576. end\
  8577. function browserWindow:map(width,body,color,bgcolor,linkcolor,align)\
  8578. local map=htmlMap:new(width,color,bgcolor,align)\
  8579. if width>=1 then\
  8580. self:mapNode(map,body,color,bgcolor,linkcolor,align)\
  8581. end\
  8582. map:setAlignment()\
  8583. return map\
  8584. end\
  8585. function browserWindow:getMap(width)\
  8586. return self:map(width,self.brws__doc.html.body,\
  8587. (self.brws__doc.html.body.color or self:getColors().wndText),\
  8588. (self.brws__doc.html.body.bgcolor or self:getColors().wndBack),\
  8589. (self.brws__doc.html.body.linkcolor or colors.blue),\
  8590. (self.brws__doc.html.body.align or \"left\"))\
  8591. end\
  8592. function browserWindow:remap()\
  8593. local width=self.brws__doc:getWidth()\
  8594. if width>=self.width then\
  8595. self.brws__map=self:getMap(width)\
  8596. self:setScrollSize(width,self.brws__map:lastLine()+1)\
  8597. return\
  8598. end\
  8599. self.brws__map=self:getMap(self.width)\
  8600. if self.brws__map:lastLine()>=self.height then\
  8601. self.brws__map=self:getMap(self.width-1)\
  8602. end\
  8603. self:setScrollSize(0,self.brws__map:lastLine()+1)\
  8604. end\
  8605. function browserWindow:lines()\
  8606. return self.brws__map:lines()\
  8607. end\
  8608. function browserWindow:nodeFromPoint(x,y)\
  8609. return self.brws__map:nodeFromPoint(x,y)\
  8610. end\
  8611. function browserWindow:getHtml()\
  8612. return self.brws__doc:getHtml()\
  8613. end\
  8614. function browserWindow:getText()\
  8615. return self.brws__doc:getText()\
  8616. end\
  8617. function browserWindow:serialize()\
  8618. return self.brws__doc:serialize()\
  8619. end\
  8620. function browserWindow:docType()\
  8621. return self.brws__doc:type()\
  8622. end\
  8623. function browserWindow:mergeAddress(link,ref,protocol)\
  8624. local address;\
  8625. link=tostring(link)\
  8626. ref=tostring(ref)\
  8627. if link:find(\":\",1,true)then\
  8628. address=link\
  8629. else\
  8630. local links,current={},{}\
  8631. if ref:sub(1,5)==\"file:\" or ref:sub(1,1)==\"/\" then\
  8632. address=\"file:\"\
  8633. elseif protocol then\
  8634. address=protocol\
  8635. else\
  8636. address=\"http:\"\
  8637. end\
  8638. if ref:find(\":\",1,true)then\
  8639. ref=ref:sub(ref:find(\":\",1,true)+1)\
  8640. end\
  8641. for part in link:gmatch(\"[^%/]+\")do\
  8642. links[#links+1]=part\
  8643. end\
  8644. if links[1]==\"\" then\
  8645. table.remove(links,1)\
  8646. end\
  8647. for part in ref:gmatch(\"[^%/]+\")do\
  8648. current[#current+1]=part\
  8649. end\
  8650. if current[1]==\"\" then\
  8651. table.remove(current,1)\
  8652. end\
  8653. if #current>0 then\
  8654. table.remove(current,#current)\
  8655. end\
  8656. while links[1]==\"..\" do\
  8657. if #current>0 then\
  8658. table.remove(current,#current)\
  8659. end\
  8660. table.remove(links,1)\
  8661. end\
  8662. if #current>0 then\
  8663. if address==\"file:\" then\
  8664. address=address..\"/\"\
  8665. end\
  8666. address=address..current[1]\
  8667. for i=2,#current,1 do\
  8668. address=address..\"/\"..current[i]\
  8669. end\
  8670. end\
  8671. for i=1,#links,1 do\
  8672. address=address..\"/\"..links[i]\
  8673. end\
  8674. end\
  8675. return address\
  8676. end\
  8677. function browserWindow:splitAddress(address)\
  8678. local path,domain,protocol;\
  8679. address=tostring(address)..\"\"\
  8680. if address:sub(1,1)==\"/\" then\
  8681. protocol=\"file\"\
  8682. domain=\"\"\
  8683. path=address:sub(2)\
  8684. else\
  8685. local addr=\"\"\
  8686. if address:find(\":\",1,true)then\
  8687. protocol=address:sub(1,address:find(\":\",1,true)-1)..\"\"\
  8688. address=address:sub(address:find(\":\",1,true)+1)..\"\"\
  8689. else\
  8690. protocol=\"http\"\
  8691. end\
  8692. if address:find(\"/\",1,true)then\
  8693. domain=address:sub(1,address:find(\"/\",1,true)-1)..\"\"\
  8694. path=address:sub(address:find(\"/\",1,true)+1)..\"\"\
  8695. else\
  8696. domain=address\
  8697. path=\"\"\
  8698. end\
  8699. end\
  8700. return path,domain,protocol\
  8701. end\
  8702. function browserWindow:serverNotFound(address)\
  8703. local path,domain,protocol=self:splitAddress(address)\
  8704. local fmt=\"\\n\\nThe server \\\"%s\\\" was not found. It may be temporarily down or the address was entered incorrectly.\"\
  8705. self:setText(string.format(fmt,domain))\
  8706. end\
  8707. function browserWindow:draw(gdi,bounds)\
  8708. local first,last=self.brws__map:getRange(self.wnd__scrollY,\
  8709. self.wnd__scrollY+self.height)\
  8710. if first then\
  8711. local eraseLine=-1\
  8712. local erase=\"\"\
  8713. if self.width>0 then\
  8714. erase=string.rep(\" \",self.brws__map:getWidth())\
  8715. end\
  8716. for index=first,last,1 do\
  8717. local map=self.brws__map[index]\
  8718. if map.erase and map.line~=eraseLine then\
  8719. gdi:setBackgroundColor(map.erase)\
  8720. gdi:write(erase,0,map.line)\
  8721. eraseLine=map.line\
  8722. end\
  8723. if map.text:len()>0 then\
  8724. gdi:setBackgroundColor(map.bgcolor)\
  8725. gdi:setTextColor(map.color)\
  8726. gdi:write(map.text,map.column,map.line)\
  8727. end\
  8728. end\
  8729. end\
  8730. end\
  8731. function browserWindow:onMove()\
  8732. self:remap()\
  8733. return false\
  8734. end\
  8735. function browserWindow:setText(doc)\
  8736. self.brws__doc=htmlDoc:new(doc)\
  8737. self:remap()\
  8738. self:setColor(self.brws__map.color)\
  8739. self:setBgColor(self.brws__map.bgcolor)\
  8740. self:setScrollOrg(0,0)\
  8741. self:invalidate()\
  8742. end\
  8743. function browserWindow:onLeftClick(x,y)\
  8744. if win.window.onLeftClick(self,x,y)then\
  8745. return true\
  8746. end\
  8747. local node=self:nodeFromPoint(self:wndToScroll(x,y))\
  8748. if type(node)==\"table\" then\
  8749. if node.tag==\"a\" and self:getParent()then\
  8750. self:getParent():sendEvent(\"link_click\",self,node.href,node.protocol)\
  8751. end\
  8752. end\
  8753. return true\
  8754. end\
  8755. function browserWindow:onTouch(x,y)\
  8756. if win.window.onTouch(self,x,y)then\
  8757. return true\
  8758. end\
  8759. local node=self:nodeFromPoint(self:wndToScroll(x,y))\
  8760. if type(node)==\"table\" then\
  8761. if node.tag==\"a\" and self:getParent()then\
  8762. self:getParent():sendEvent(\"link_click\",self,node.href,node.protocol)\
  8763. end\
  8764. end\
  8765. return true\
  8766. end\
  8767. ",
  8768. "local appArgs={...}\
  8769. local appFrame=win.createAppFrame()\
  8770. local APP_TITLE=\"notePad\"\
  8771. local ID_MENUBTN=100\
  8772. local ID_EDITOR=101\
  8773. local ID_FINDTEXT=102\
  8774. local ID_REPLACETEXT=103\
  8775. local ID_FIND=104\
  8776. local ID_REPLACE=105\
  8777. local ID_REPLACEALL=106\
  8778. local IDM_NEW=1001\
  8779. local IDM_OPEN=1002\
  8780. local IDM_SAVE=1003\
  8781. local IDM_SAVEAS=1004\
  8782. local IDM_PRINT=1005\
  8783. local IDM_UNDO=1006\
  8784. local IDM_REDO=1007\
  8785. local IDM_CUT=1008\
  8786. local IDM_COPY=1009\
  8787. local IDM_PASTE=1010\
  8788. local IDM_FIND=1011\
  8789. local IDM_FINDNEXT=1012\
  8790. local IDM_REPLACE=1013\
  8791. local IDM_QUITAPP=1014\
  8792. local function mergePath(name,path)\
  8793. path=asstring(path)\
  8794. name=asstring(name)\
  8795. if path:len()>1 then\
  8796. return path:sub(1,-(fs.getName(path):len()+1))..name\
  8797. else\
  8798. return \"/\"..name\
  8799. end\
  8800. end\
  8801. local findDlg=win.popupFrame:base()\
  8802. function findDlg:onCreate(findText)\
  8803. local width=math.floor(self:getOwner().width/2)\
  8804. self:dress(\"Find\")\
  8805. self.fd_find=win.inputWindow:new(self,ID_FINDTEXT,1,2,\
  8806. width-2,findText,\"Find\")\
  8807. win.buttonWindow:new(self,ID_FIND,width-5,3,\"Find\")\
  8808. self.fd_find:setSel(0,-1)\
  8809. self.fd_find:setFocus()\
  8810. self:move(self:getOwner().width-width,0,width,5)\
  8811. return true\
  8812. end\
  8813. function findDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  8814. if event==\"btn_click\" then\
  8815. if p1:getId()==ID_FIND then\
  8816. self:getOwner():sendEvent(\"find_next\",self.fd_find:getText())\
  8817. return true\
  8818. end\
  8819. end\
  8820. return false\
  8821. end\
  8822. function findDlg:onChildKey(wnd,key,ctrl,alt,shift)\
  8823. if win.popupFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  8824. return true\
  8825. end\
  8826. if ctrl and not alt and not shift then\
  8827. if key==keys.f then\
  8828. self:getOwner():sendEvent(\"find_next\",self.fd_find:getText())\
  8829. return true\
  8830. end\
  8831. end\
  8832. return false\
  8833. end\
  8834. local replaceDlg=win.popupFrame:base()\
  8835. function replaceDlg:onCreate(findText,replaceText)\
  8836. local width=math.floor(self:getOwner().width/2)\
  8837. self:dress(\"Replace\")\
  8838. self.rd_find=win.inputWindow:new(self,ID_FINDTEXT,1,2,\
  8839. width-2,findText,\"Find\")\
  8840. self.rd_replace=win.inputWindow:new(self,ID_REPLACETEXT,1,4,\
  8841. width-2,replaceText,\"Replace\")\
  8842. win.buttonWindow:new(self,ID_FIND,width-17,5,\"Find\")\
  8843. win.buttonWindow:new(self,ID_REPLACE,width-12,5,\"Replace\")\
  8844. win.buttonWindow:new(self,ID_REPLACEALL,width-4,5,\"All\")\
  8845. self.rd_replace:setSel(0,-1)\
  8846. self.rd_replace:setFocus()\
  8847. self:move(self:getOwner().width-width,0,width,7)\
  8848. return true\
  8849. end\
  8850. function replaceDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  8851. if event==\"btn_click\" then\
  8852. if p1:getId()==ID_FIND then\
  8853. self:getOwner():sendEvent(\"find_next\",self.rd_find:getText())\
  8854. return true\
  8855. end\
  8856. if p1:getId()==ID_REPLACE then\
  8857. self:getOwner():sendEvent(\"replace_one\",self.rd_find:getText(),\
  8858. self.rd_replace:getText())\
  8859. return true\
  8860. end\
  8861. if p1:getId()==ID_REPLACEALL then\
  8862. self:getOwner():sendEvent(\"replace_all\",self.rd_find:getText(),\
  8863. self.rd_replace:getText())\
  8864. self:close(win.ID_CLOSE)\
  8865. return true\
  8866. end\
  8867. end\
  8868. return false\
  8869. end\
  8870. function replaceDlg:onChildKey(wnd,key,ctrl,alt,shift)\
  8871. if win.popupFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  8872. return true\
  8873. end\
  8874. if ctrl and not alt and not shift then\
  8875. if key==keys.f then\
  8876. self:getOwner():sendEvent(\"find_next\",self.rd_find:getText())\
  8877. return true\
  8878. end\
  8879. if key==keys.r then\
  8880. self:getOwner():sendEvent(\"replace_one\",self.rd_find:getText(),\
  8881. self.rd_replace:getText())\
  8882. return true\
  8883. end\
  8884. if key==keys.a then\
  8885. self:getOwner():sendEvent(\"replace_all\",self.rd_find:getText(),\
  8886. self.rd_replace:getText())\
  8887. self:close(win.ID_CLOSE)\
  8888. return true\
  8889. end\
  8890. end\
  8891. return false\
  8892. end\
  8893. function appFrame:onMenu(x,y)\
  8894. local menu=win.menuWindow:new(self)\
  8895. x=x or 0\
  8896. y=y or 1\
  8897. menu:addString(\"New     Ctrl+N\",IDM_NEW)\
  8898. menu:addString(\"Open    Ctrl+O\",IDM_OPEN)\
  8899. if self.app_editor:getModified()then\
  8900. menu:addString(\"Save    Ctrl+S\",IDM_SAVE)\
  8901. end\
  8902. menu:addString(\"Save as\",IDM_SAVEAS)\
  8903. menu:addString(\"Print\",IDM_PRINT)\
  8904. menu:addString(\"--------------\")\
  8905. local doSep=false\
  8906. if self.app_editor:canUndo()then\
  8907. menu:addString(\"Undo    Ctrl+Z\",IDM_UNDO)\
  8908. doSep=true\
  8909. end\
  8910. if self.app_editor:canRedo()then\
  8911. menu:addString(\"Redo    Ctrl+Y\",IDM_REDO)\
  8912. doSep=true\
  8913. end\
  8914. if doSep then\
  8915. menu:addString(\"--------------\")\
  8916. end\
  8917. doSep=false\
  8918. local ss,se=self.app_editor:getSel()\
  8919. if ss~=se then\
  8920. menu:addString(\"Cut     Ctrl+X\",IDM_CUT)\
  8921. menu:addString(\"Copy    Ctrl+C\",IDM_COPY)\
  8922. doSep=true\
  8923. end\
  8924. if(self:getClipboard())==win.CB_TEXT then\
  8925. menu:addString(\"Paste   Ctrl+B\",IDM_PASTE)\
  8926. doSep=true\
  8927. end\
  8928. if doSep then\
  8929. menu:addString(\"--------------\")\
  8930. end\
  8931. menu:addString(\"Find    Ctrl+F\",IDM_FIND)\
  8932. if self.app_findText:len()>0 then\
  8933. menu:addString(\"Next        F3\",IDM_FINDNEXT)\
  8934. end\
  8935. menu:addString(\"Replace Ctrl+H\",IDM_REPLACE)\
  8936. menu:addString(\"--------------\")\
  8937. menu:addString(\"Quit\",IDM_QUITAPP)\
  8938. menu:track(x,y)\
  8939. end\
  8940. function appFrame:onCommand(cmdId)\
  8941. if cmdId==IDM_NEW then\
  8942. self:onNewFile()\
  8943. return true\
  8944. end\
  8945. if cmdId==IDM_OPEN then\
  8946. self:onOpenFile()\
  8947. return true\
  8948. end\
  8949. if cmdId==IDM_SAVE then\
  8950. if self.app_editor:getModified()then\
  8951. self:saveFile()\
  8952. end\
  8953. return true\
  8954. end\
  8955. if cmdId==IDM_SAVEAS then\
  8956. self:onSaveFileAs()\
  8957. return true\
  8958. end\
  8959. if cmdId==IDM_PRINT then\
  8960. self:printDoc()\
  8961. return true\
  8962. end\
  8963. if cmdId==IDM_UNDO then\
  8964. self.app_editor:undo()\
  8965. self.app_editor:setFocus()\
  8966. return true\
  8967. end\
  8968. if cmdId==IDM_REDO then\
  8969. self.app_editor:redo()\
  8970. self.app_editor:setFocus()\
  8971. return true\
  8972. end\
  8973. if cmdId==IDM_CUT then\
  8974. self.app_editor:cut()\
  8975. self.app_editor:setFocus()\
  8976. return true\
  8977. end\
  8978. if cmdId==IDM_COPY then\
  8979. self.app_editor:copy()\
  8980. self.app_editor:setFocus()\
  8981. return true\
  8982. end\
  8983. if cmdId==IDM_PASTE then\
  8984. self.app_editor:paste()\
  8985. self.app_editor:setFocus()\
  8986. return true\
  8987. end\
  8988. if cmdId==IDM_FIND then\
  8989. self:find()\
  8990. self.app_editor:setFocus()\
  8991. return true\
  8992. end\
  8993. if cmdId==IDM_FINDNEXT then\
  8994. self:findNext()\
  8995. self.app_editor:setFocus()\
  8996. return true\
  8997. end\
  8998. if cmdId==IDM_REPLACE then\
  8999. self:replace()\
  9000. self.app_editor:setFocus()\
  9001. return true\
  9002. end\
  9003. if cmdId==IDM_QUITAPP then\
  9004. self:quitApp()\
  9005. return true\
  9006. end\
  9007. return false\
  9008. end\
  9009. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  9010. if event==\"btn_click\" then\
  9011. if p1:getId()==ID_MENUBTN then\
  9012. self:onMenu()\
  9013. return true\
  9014. end\
  9015. elseif event==\"menu_cmd\" then\
  9016. return self:onCommand(p1)\
  9017. elseif event==\"selection_change\" then\
  9018. if p1:getId()==ID_EDITOR then\
  9019. local ss,se=p1:getSel()\
  9020. local ln,cr=p1:lineFromChar(se)\
  9021. self.app_curPos:setText(string.format(\"l:%d c:%d\",(ln+1),(cr+1)))\
  9022. return true\
  9023. end\
  9024. elseif event==\"modified\" then\
  9025. if p1:getId()==ID_EDITOR then\
  9026. self.app_mod:setText(iif(p1:getModified(),\"mod\",\"\"))\
  9027. return true\
  9028. end\
  9029. elseif event==\"find_next\" then\
  9030. self:findNext(p1)\
  9031. elseif event==\"replace_one\" then\
  9032. self:replaceOne(p1,p2)\
  9033. elseif event==\"replace_all\" then\
  9034. self:replaceAll(p1,p2)\
  9035. return true\
  9036. end\
  9037. return false\
  9038. end\
  9039. function appFrame:newFile()\
  9040. self.app_editor:setText()\
  9041. self.app_editor:setFocus()\
  9042. self.app_curFile=\"untitled\"\
  9043. self.app_curPath=nil\
  9044. self:updateTitle()\
  9045. end\
  9046. function appFrame:onNewFile()\
  9047. if self.app_editor:getModified()then\
  9048. if not cmndlg.confirm(self,\
  9049. \"Modified\",\"\\\"\"..self.app_curFile..\
  9050. \"\\\" is not saved.\\nRenew anyway?\")then\
  9051. return\
  9052. end\
  9053. end\
  9054. self:newFile()\
  9055. end\
  9056. function appFrame:openFile(path)\
  9057. local hFile=fs.open(path,\"r\")\
  9058. if hFile then\
  9059. self.app_editor:setText(hFile.readAll())\
  9060. hFile.close()\
  9061. self.app_editor:setSel(0,0)\
  9062. self.app_curPath=path\
  9063. self.app_lastPath=path\
  9064. self.app_curFile=fs.getName(self.app_curPath)\
  9065. self:updateTitle()\
  9066. else\
  9067. self:msgBox(\"File Error\",\"Could not read file \"..path,colors.red)\
  9068. end\
  9069. end\
  9070. function appFrame:onOpenFile()\
  9071. if self.app_editor:getModified()then\
  9072. if not cmndlg.confirm(self,\
  9073. \"Modified\",\"\\\"\"..self.app_curFile..\
  9074. \"\\\" is not saved.\\nOpen file anyway?\")then\
  9075. return\
  9076. end\
  9077. end\
  9078. local path=cmndlg.openFile(self,mergePath(self.app_curFile,self.app_lastPath))\
  9079. if path then\
  9080. self:openFile(path)\
  9081. end\
  9082. end\
  9083. function appFrame:saveFileAs(path)\
  9084. local hFile=fs.open(path,\"w\")\
  9085. if hFile then\
  9086. hFile.write(self.app_editor:getText())\
  9087. hFile.close()\
  9088. self.app_editor:setModified(false)\
  9089. self.app_curPath=path\
  9090. self.app_lastPath=path\
  9091. self.app_curFile=fs.getName(self.app_curPath)\
  9092. self:updateTitle()\
  9093. else\
  9094. self:msgBox(\"File Error\",\"Could not write file \"..path,colors.red)\
  9095. end\
  9096. end\
  9097. function appFrame:onSaveFileAs()\
  9098. local path=cmndlg.saveFile(self,mergePath(self.app_curFile,self.app_lastPath))\
  9099. if path then\
  9100. self:saveFileAs(path)\
  9101. end\
  9102. end\
  9103. function appFrame:saveFile()\
  9104. if self.app_curPath then\
  9105. self:saveFileAs(self.app_curPath)\
  9106. else\
  9107. self:onSaveFileAs()\
  9108. end\
  9109. end\
  9110. function appFrame:find()\
  9111. local dlg=findDlg:new(self)\
  9112. local findText=self.app_editor:getSelectedText()\
  9113. if findText:len()<1 then\
  9114. findText=self.app_findText\
  9115. end\
  9116. dlg:doModal(findText)\
  9117. end\
  9118. function appFrame:findNext(findText,from)\
  9119. findText=tostring(findText or self.app_findText)\
  9120. if findText:len()>0 then\
  9121. self.app_findText=findText\
  9122. local ss,se=self.app_editor:getSel(true)\
  9123. local editText=self.app_editor:getText()\
  9124. local first,last=editText:find(self.app_findText,from or se,true)\
  9125. if first then\
  9126. self.app_editor:setSel(first-1,last)\
  9127. return first-1,last\
  9128. end\
  9129. end\
  9130. return nil\
  9131. end\
  9132. function appFrame:replace()\
  9133. local dlg=replaceDlg:new(self)\
  9134. local findText=self.app_editor:getSelectedText()\
  9135. if findText:len()<1 then\
  9136. findText=self.app_findText\
  9137. end\
  9138. dlg:doModal(findText,self.app_replaceText)\
  9139. end\
  9140. function appFrame:replaceOne(findText,replaceText)\
  9141. self.app_replaceText=tostring(replaceText or \"\")\
  9142. local first,last=appFrame:findNext(findText,(self.app_editor:getSel(true)))\
  9143. if first then\
  9144. self.app_editor:setSel(first,last,false)\
  9145. self.app_editor:replaceSel(self.app_replaceText,false)\
  9146. self.app_editor:setSel(first,first+self.app_replaceText:len())\
  9147. appFrame:findNext(findText)\
  9148. end\
  9149. end\
  9150. function appFrame:replaceAll(findText,replaceText)\
  9151. self.app_replaceText=tostring(replaceText or \"\")\
  9152. findText=tostring(findText or self.app_findText)\
  9153. if findText:len()>0 then\
  9154. self.app_findText=findText\
  9155. local invoked=os.clock()\
  9156. local editText=self.app_editor:getText()\
  9157. local first,last=editText:find(self.app_findText,(self.app_editor:getSel(true)),true)\
  9158. while first do\
  9159. if(os.clock()-invoked)>3.0 then\
  9160. sleep(0.1)\
  9161. invoked=os.clock()\
  9162. end\
  9163. self.app_editor:setSel(first-1,last,false)\
  9164. self.app_editor:replaceSel(self.app_replaceText,false)\
  9165. editText=editText:sub(1,first-1)..self.app_replaceText..editText:sub(last+1)\
  9166. last=first-1+self.app_replaceText:len()\
  9167. self.app_editor:setSel(first-1,last)\
  9168. first,last=editText:find(self.app_findText,last,true)\
  9169. end\
  9170. end\
  9171. end\
  9172. function appFrame:onPrintPage(gdi,page,data)\
  9173. local width,height=gdi:getPageSize()\
  9174. if not data.data.lines then\
  9175. data.data.lines=string.wrap(data.data.raw,width)\
  9176. end\
  9177. local topLine=((page-1)*height)+1\
  9178. local lastLine=iif((topLine+height)>#data.data.lines,\
  9179. #data.data.lines,topLine+height)\
  9180. for line=topLine,lastLine,1 do\
  9181. gdi:write(data.data.lines[line],0,line-topLine)\
  9182. end\
  9183. return(lastLine<#data.data.lines)\
  9184. end\
  9185. function appFrame:onPrintData()\
  9186. local pages;\
  9187. local title=self.app_curFile\
  9188. local data={}\
  9189. local ss,se=self.app_editor:getSel(true)\
  9190. if ss==se then\
  9191. local width,height=string.wrapSize(string.wrap(self.app_editor:getText(),25))\
  9192. pages=math.ceil(height/21)\
  9193. title=self.app_curFile\
  9194. data.raw=self.app_editor:getText()\
  9195. else\
  9196. pages=nil\
  9197. title=self.app_curFile..\" (range)\"\
  9198. data.raw=self.app_editor:getSelectedText()\
  9199. end\
  9200. return win.applicationFrame.onPrintData(self,title,data,pages)\
  9201. end\
  9202. function appFrame:onQuit()\
  9203. if self.app_editor:getModified()then\
  9204. if not cmndlg.confirm(self,\
  9205. \"Modified\",\"\\\"\"..self.app_curFile..\
  9206. \"\\\" is not saved.\\nQuit anyway?\")then\
  9207. return true\
  9208. end\
  9209. end\
  9210. return false\
  9211. end\
  9212. function appFrame:updateTitle()\
  9213. self:setTitle(self.app_curFile..\":\"..APP_TITLE)\
  9214. end\
  9215. function appFrame:onMove()\
  9216. self.app_editor:move(1,1,self.width-2,self.height-2)\
  9217. self.app_curPos:move(1,self.height-1)\
  9218. self.app_mod:move(self.width-4,self.height-1)\
  9219. return false\
  9220. end\
  9221. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  9222. if key==keys.tab then\
  9223. if not ctrl and not alt and not shift and wnd==self.app_editor then\
  9224. return false\
  9225. end\
  9226. end\
  9227. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  9228. return true\
  9229. end\
  9230. if ctrl and not alt and not shift then\
  9231. if key==keys.n then\
  9232. return self:onCommand(IDM_NEW)\
  9233. end\
  9234. if key==keys.o then\
  9235. return self:onCommand(IDM_OPEN)\
  9236. end\
  9237. if key==keys.s then\
  9238. return self:onCommand(IDM_SAVE)\
  9239. end\
  9240. if key==keys.f then\
  9241. return self:onCommand(IDM_FIND)\
  9242. end\
  9243. if key==keys.h then\
  9244. return self:onCommand(IDM_REPLACE)\
  9245. end\
  9246. elseif not ctrl and alt and not shift then\
  9247. if key==keys.m then\
  9248. self:onMenu()\
  9249. return true\
  9250. end\
  9251. elseif not ctrl and not alt and not shift then\
  9252. if key==keys.f3 then\
  9253. return self:onCommand(IDM_FINDNEXT)\
  9254. end\
  9255. end\
  9256. return false\
  9257. end\
  9258. function appFrame:onChildRightClick(child,x,y)\
  9259. if child==self.app_editor then\
  9260. self.app_editor:setFocus()\
  9261. self:onMenu(self:screenToWnd(x,y))\
  9262. return true\
  9263. end\
  9264. return false\
  9265. end\
  9266. function appFrame:onCreate()\
  9267. self:dress(APP_TITLE)\
  9268. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  9269. menuBtn:setColors(menuBtn:getColors().frameText,\
  9270. menuBtn:getColors().titleBack,\
  9271. menuBtn:getColors().frameBack)\
  9272. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  9273. self.app_editor=win.editWindow:new(self,ID_EDITOR,1,1,self.width-2,self.height-2)\
  9274. self.app_editor:setColors(self:getColors().inputText,\
  9275. self:getColors().inputBack,\
  9276. self:getColors().inputBack,\
  9277. self:getColors().inputBanner,\
  9278. self:getColors().inputError)\
  9279. self.app_editor:setFocus()\
  9280. self.app_curPos=win.labelWindow:new(self,0,1,self.height-1,\"l:1 c:1        \")\
  9281. self.app_mod=win.labelWindow:new(self,0,self.width-4,self.height-1,\"    \")\
  9282. self.app_curPath=nil\
  9283. self.app_lastPath=nil\
  9284. self.app_curFile=\"untitled\"\
  9285. self.app_findText=\"\"\
  9286. self.app_replaceText=\"\"\
  9287. local iniFile=fs.loadIniFile(self:getAppPath()..\".ini\")\
  9288. local tabSize=2\
  9289. if iniFile then\
  9290. tabSize=asnumber(iniFile:find(\"tab\"),2)\
  9291. end\
  9292. self.app_editor:setTabWidth(tabSize)\
  9293. if #appArgs>0 then\
  9294. self:openFile(appArgs[1])\
  9295. else\
  9296. self:newFile()\
  9297. end\
  9298. self:setActiveTopFrame()\
  9299. return true\
  9300. end\
  9301. appFrame:runApp()",
  9302. "tab=2",
  9303. "local appArgs={...}\
  9304. local appFrame=win.createAppFrame()\
  9305. local APP_TITLE=\"explore\"\
  9306. local ID_MENUBTN=100\
  9307. local ID_FILELIST=101\
  9308. local ID_STATUS=102\
  9309. local IDM_UPDIR=1000\
  9310. local IDM_OPEN=1001\
  9311. local IDM_RUN=1002\
  9312. local IDM_NEWDIR=1003\
  9313. local IDM_RENAME=1004\
  9314. local IDM_LABEL=1005\
  9315. local IDM_DELETE=1006\
  9316. local IDM_COPY=1007\
  9317. local IDM_PASTE=1008\
  9318. local IDM_QUITAPP=1009\
  9319. local TYPE_UP=0\
  9320. local TYPE_DIR=1\
  9321. local TYPE_FILE=2\
  9322. local function pathFolder(path)\
  9323. path=asstring(path)\
  9324. if path:len()>1 then\
  9325. if path:sub(-1,-1)==\"/\" then\
  9326. path=path:sub(1,-2)\
  9327. end\
  9328. local lastName=fs.getName(path)\
  9329. path=path:sub(1,-(lastName:len()+1))\
  9330. else\
  9331. path=\"/\"\
  9332. end\
  9333. return path\
  9334. end\
  9335. local function isSubOf(parent,sub)\
  9336. if parent:sub(-1,-1)~=\"/\" then\
  9337. parent=parent..\"/\"\
  9338. end\
  9339. if sub:sub(-1,-1)~=\"/\" then\
  9340. sub=sub..\"/\"\
  9341. end\
  9342. while sub~=\"/\" do\
  9343. if sub==parent then\
  9344. return true\
  9345. end\
  9346. sub=pathFolder(sub)\
  9347. end\
  9348. return false\
  9349. end\
  9350. local function canPaste(itemPath,toDir)\
  9351. if fs.exists(itemPath)and not fs.isReadOnly(toDir)then\
  9352. if pathFolder(itemPath)~=toDir then\
  9353. local copyPath=toDir..fs.getName(itemPath)\
  9354. if isSubOf(itemPath,copyPath)and fs.isDir(itemPath)then\
  9355. return false\
  9356. end\
  9357. if isSubOf(copyPath,itemPath)then\
  9358. return false\
  9359. end\
  9360. end\
  9361. return true\
  9362. end\
  9363. return false\
  9364. end\
  9365. local function getDrive(path)\
  9366. path=tostring(path or \"\")\
  9367. if fs.getDrive(path)then\
  9368. if path:sub(1,1)==\"/\" then\
  9369. path=path:sub(2)\
  9370. end\
  9371. for k,v in pairs(peripheral.getNames())do\
  9372. if peripheral.getType(v)==\"drive\" then\
  9373. if disk.hasData(v)then\
  9374. if path==disk.getMountPath(v)then\
  9375. return v\
  9376. end\
  9377. end\
  9378. end\
  9379. end\
  9380. end\
  9381. return nil\
  9382. end\
  9383. local function getLabel(path)\
  9384. local drive=getDrive(path)\
  9385. if drive then\
  9386. return disk.getLabel(drive)\
  9387. end\
  9388. return nil\
  9389. end\
  9390. function appFrame:onMenu(x,y)\
  9391. local menu=win.menuWindow:new(self)\
  9392. local sep=false\
  9393. x=x or 0\
  9394. y=y or 1\
  9395. if self.app_items:getData(1)then\
  9396. if self.app_items:getData(1).type==TYPE_UP then\
  9397. if self.app_curDir:len()>1 then\
  9398. menu:addString(\"Up      Ctrl+^\",IDM_UPDIR)\
  9399. sep=true\
  9400. end\
  9401. end\
  9402. end\
  9403. if not fs.isReadOnly(self.app_curDir)then\
  9404. menu:addString(\"New     Ctrl+N\",IDM_NEWDIR)\
  9405. sep=true\
  9406. end\
  9407. if self.app_items:getData()then\
  9408. menu:addString(\"Open    Ctrl+O\",IDM_OPEN)\
  9409. sep=true\
  9410. end\
  9411. if self.app_items:getData()then\
  9412. if self.app_items:getData().type==TYPE_FILE then\
  9413. menu:addString(\"Run     Ctrl+P\",IDM_RUN)\
  9414. sep=true\
  9415. end\
  9416. end\
  9417. if self:getSelectedPath()then\
  9418. if not fs.isReadOnly(self:getSelectedPath())and\
  9419. not getDrive(self:getSelectedPath())then\
  9420. menu:addString(\"Rename  Ctrl+R\",IDM_RENAME)\
  9421. menu:addString(\"Delete  Del\",IDM_DELETE)\
  9422. sep=true\
  9423. end\
  9424. end\
  9425. if self:getSelectedPath()then\
  9426. if not fs.isReadOnly(self:getSelectedPath())and\
  9427. getDrive(self:getSelectedPath())then\
  9428. menu:addString(\"Label   Ctrl+L\",IDM_LABEL)\
  9429. sep=true\
  9430. end\
  9431. end\
  9432. if sep then\
  9433. menu:addString(\"--------------\")\
  9434. sep=false\
  9435. end\
  9436. if self:getSelectedPath()then\
  9437. menu:addString(\"Copy    Ctrl+C\",IDM_COPY)\
  9438. sep=true\
  9439. end\
  9440. local cbType,cbPath=self:getClipboard()\
  9441. if cbType==win.CB_TEXT then\
  9442. if canPaste(cbPath,self.app_curDir)then\
  9443. menu:addString(\"Paste   Ctrl+B\",IDM_PASTE)\
  9444. sep=true\
  9445. end\
  9446. end\
  9447. if sep then\
  9448. menu:addString(\"--------------\")\
  9449. end\
  9450. menu:addString(\"Quit\",IDM_QUITAPP)\
  9451. menu:track(x,y)\
  9452. end\
  9453. function appFrame:onCommand(cmdId)\
  9454. if cmdId==IDM_UPDIR then\
  9455. if self.app_items:getData(1)then\
  9456. if self.app_items:getData(1).type==TYPE_UP then\
  9457. if self.app_curDir:len()>1 then\
  9458. self.app_curDir=pathFolder(self.app_curDir)\
  9459. self:fillList()\
  9460. end\
  9461. end\
  9462. end\
  9463. return true\
  9464. end\
  9465. if cmdId==IDM_OPEN then\
  9466. self:openFile()\
  9467. return true\
  9468. end\
  9469. if cmdId==IDM_RUN then\
  9470. self:runFile()\
  9471. return true\
  9472. end\
  9473. if cmdId==IDM_NEWDIR then\
  9474. self:onNewDir()\
  9475. return true\
  9476. end\
  9477. if cmdId==IDM_RENAME then\
  9478. self:onRename()\
  9479. return true\
  9480. end\
  9481. if cmdId==IDM_LABEL then\
  9482. self:onLabelDisk()\
  9483. return true\
  9484. end\
  9485. if cmdId==IDM_DELETE then\
  9486. self:onDelete()\
  9487. return true\
  9488. end\
  9489. if cmdId==IDM_COPY then\
  9490. self:copy(self:getSelectedPath())\
  9491. return true\
  9492. end\
  9493. if cmdId==IDM_PASTE then\
  9494. self:paste()\
  9495. return true\
  9496. end\
  9497. if cmdId==IDM_QUITAPP then\
  9498. self:quitApp()\
  9499. return true\
  9500. end\
  9501. return false\
  9502. end\
  9503. function appFrame:fillList()\
  9504. if not fs.isDir(self.app_curDir)then\
  9505. self.app_curDir=\"/\"\
  9506. end\
  9507. local sel=self.app_items:getCurSel()\
  9508. local item=self.app_items:getString()\
  9509. local items=fs.list(self.app_curDir)\
  9510. table.sort(items)\
  9511. self.app_items:resetContent()\
  9512. if self.app_curDir:len()>1 then\
  9513. self.app_items:addString(\"..\",{type=TYPE_UP,name=\"..\"})\
  9514. end\
  9515. for i=1,#items,1 do\
  9516. if fs.isDir(self.app_curDir..items[i])then\
  9517. local name=\"/\"..items[i]\
  9518. local label=getLabel(self.app_curDir..items[i])\
  9519. if label then\
  9520. name=name..\" [\"..label..\"]\"\
  9521. end\
  9522. self.app_items:addString(name,{type=TYPE_DIR,name=items[i]})\
  9523. end\
  9524. end\
  9525. for i=1,#items,1 do\
  9526. if not fs.isDir(self.app_curDir..items[i])then\
  9527. self.app_items:addString(items[i],{type=TYPE_FILE,name=items[i]})\
  9528. end\
  9529. end\
  9530. if item then\
  9531. local index=self.app_items:find(item,0,true)\
  9532. if index>0 then\
  9533. self.app_items:setCurSel(index)\
  9534. sel=0\
  9535. end\
  9536. end\
  9537. if sel>0 then\
  9538. self.app_items:setCurSel(sel)\
  9539. end\
  9540. self:updateTitle()\
  9541. self:updateStatus()\
  9542. end\
  9543. function appFrame:getSelectedPath()\
  9544. if self.app_items:getData()then\
  9545. if self.app_items:getData().type~=TYPE_UP then\
  9546. return(self.app_curDir..self.app_items:getData().name)\
  9547. end\
  9548. end\
  9549. return nil\
  9550. end\
  9551. function appFrame:doDefaultAction()\
  9552. if self.app_items:getData()then\
  9553. if self.app_items:getData().type==TYPE_UP then\
  9554. if self.app_curDir:len()>1 then\
  9555. self.app_curDir=pathFolder(self.app_curDir)\
  9556. self.app_items:setCurSel(0)\
  9557. self:fillList()\
  9558. end\
  9559. elseif self.app_items:getData().type==TYPE_DIR then\
  9560. self.app_curDir=self:getSelectedPath()..\"/\"\
  9561. self.app_items:setCurSel(0)\
  9562. self:fillList()\
  9563. elseif self.app_items:getData().type==TYPE_FILE then\
  9564. self:openFile(self:getSelectedPath())\
  9565. end\
  9566. end\
  9567. end\
  9568. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  9569. if event==\"btn_click\" then\
  9570. if p1:getId()==ID_MENUBTN then\
  9571. self:onMenu()\
  9572. return true\
  9573. end\
  9574. elseif event==\"menu_cmd\" then\
  9575. return self:onCommand(p1)\
  9576. elseif event==\"selection_change\" then\
  9577. if p1:getId()==ID_FILELIST then\
  9578. self:updateStatus()\
  9579. return true\
  9580. end\
  9581. elseif event==\"list_click\" then\
  9582. if p1:getId()==ID_FILELIST then\
  9583. return true\
  9584. end\
  9585. elseif event==\"list_double_click\" then\
  9586. if p1:getId()==ID_FILELIST then\
  9587. self:doDefaultAction()\
  9588. return true\
  9589. end\
  9590. elseif event==\"disk_eject\" then\
  9591. if self.app_curDir==\"/\" then\
  9592. self:fillList()\
  9593. elseif not fs.exists(self.app_curDir)then\
  9594. self.app_curDir=\"/\"\
  9595. self:fillList()\
  9596. end\
  9597. return true\
  9598. elseif event==\"disk\" then\
  9599. if self.app_curDir==\"/\" then\
  9600. self:fillList()\
  9601. end\
  9602. return true\
  9603. end\
  9604. return false\
  9605. end\
  9606. function appFrame:newDir(path)\
  9607. fs.makeDir(path)\
  9608. self:fillList()\
  9609. end\
  9610. local function validateNewDir(name)\
  9611. return(not fs.exists(appFrame.app_curDir..name))and\
  9612. (not name:find(\"/\",1,true))and\
  9613. (not name:find(\" \",1,true))\
  9614. end\
  9615. function appFrame:onNewDir()\
  9616. if not fs.isReadOnly(self.app_curDir)then\
  9617. local folder=cmndlg.input(self,\"New Folder\",\"Enter new folder name.\",\
  9618. \"new\",\"Name\",nil,validateNewDir)\
  9619. if folder then\
  9620. self:newDir(self.app_curDir..folder)\
  9621. end\
  9622. end\
  9623. end\
  9624. function appFrame:openFile(path)\
  9625. if not path then\
  9626. if not self.app_items:getData()then\
  9627. return\
  9628. end\
  9629. if self.app_items:getData().type==TYPE_UP then\
  9630. path=pathFolder(self.app_curDir)\
  9631. else\
  9632. path=self:getSelectedPath()\
  9633. end\
  9634. end\
  9635. if fs.isDir(path)then\
  9636. self:getDesktop():runApp(appFrame:getAppPath(),path)\
  9637. else\
  9638. local iniFile=fs.loadIniFile(appFrame:getAppPath()..\".asc\")\
  9639. if iniFile then\
  9640. local progPath=iniFile:find(fs.getExtension(path))\
  9641. if not progPath then\
  9642. progPath=iniFile:find(\"<default>\")\
  9643. end\
  9644. if progPath then\
  9645. self:getDesktop():runApp(progPath,\"\\\"\"..path..\"\\\"\")\
  9646. end\
  9647. end\
  9648. end\
  9649. end\
  9650. function appFrame:runFile(path)\
  9651. if not path then\
  9652. if not self.app_items:getData()then\
  9653. return\
  9654. end\
  9655. if self.app_items:getData().type==TYPE_UP then\
  9656. self:openFile(pathFolder(self.app_curDir))\
  9657. return\
  9658. elseif self.app_items:getData().type==TYPE_DIR then\
  9659. self:openFile(self:getSelectedPath())\
  9660. return\
  9661. else\
  9662. path=self:getSelectedPath()\
  9663. end\
  9664. end\
  9665. local file=fs.open(path,\"r\")\
  9666. if not file then\
  9667. self:msgBox(\"Error\",\"File error \"..path,colors.red)\
  9668. return\
  9669. end\
  9670. local content=file.readAll()\
  9671. local isApp=(content:find(\"win.createAppFrame\",1,true)and\
  9672. content:find(\"runApp\",1,true))or\
  9673. not fs.exists(\"/win/apps/cmd\")\
  9674. file.close()\
  9675. if isApp then\
  9676. self:getDesktop():runApp(path)\
  9677. else\
  9678. self:getWorkSpace():runApp(self:getSide(),\"/win/apps/cmd\",\"\\\"\"..path..\"\\\"\")\
  9679. self:getDesktop():loadAppList()\
  9680. end\
  9681. end\
  9682. function appFrame:rename(path,newName)\
  9683. fs.move(path,pathFolder(path)..newName)\
  9684. self:fillList()\
  9685. end\
  9686. local function validateRename(name)\
  9687. return(not fs.exists(pathFolder(appFrame:getSelectedPath())..name))and\
  9688. (not name:find(\"/\",1,true))\
  9689. end\
  9690. function appFrame:onRename()\
  9691. local path=self:getSelectedPath()\
  9692. if path then\
  9693. if not fs.isReadOnly(path)and not getDrive(path)then\
  9694. local name=cmndlg.input(self,\"Rename\",\
  9695. \"Rename \"..fs.getName(path)..\" to:\",\
  9696. fs.getName(path),\
  9697. \"Name\",nil,validateRename)\
  9698. if name then\
  9699. self:rename(path,name)\
  9700. end\
  9701. end\
  9702. end\
  9703. end\
  9704. function appFrame:labelDisk(drive,label)\
  9705. disk.setLabel(drive,label)\
  9706. self:fillList()\
  9707. end\
  9708. function appFrame:onLabelDisk()\
  9709. local drive=getDrive(self:getSelectedPath())\
  9710. if drive then\
  9711. local curLabel=disk.getLabel(drive)or \"\"\
  9712. local label=cmndlg.input(self,\"Label\",\
  9713. \"Label disk \"..tostring(disk.getID(drive))..\" from \"..curLabel..\" to:\",\
  9714. curLabel,\"Label\")\
  9715. if label then\
  9716. if label:len()<1 then\
  9717. label=nil\
  9718. end\
  9719. self:labelDisk(drive,label)\
  9720. end\
  9721. end\
  9722. end\
  9723. function appFrame:delete(path)\
  9724. fs.delete(path)\
  9725. self:fillList()\
  9726. end\
  9727. function appFrame:onDelete()\
  9728. local path=self:getSelectedPath()\
  9729. if path then\
  9730. if not fs.isReadOnly(path)then\
  9731. if fs.isDir(path)then\
  9732. if not cmndlg.confirm(self,\"Delete Folder\",\
  9733. \"Delete \"..fs.getName(path)..\" and all of its contents?\",\
  9734. false,colors.orange)then\
  9735. return\
  9736. end\
  9737. else\
  9738. if not cmndlg.confirm(self,\"Delete File\",\
  9739. \"Delete \"..fs.getName(path)..\"?\",\
  9740. false,colors.orange)then\
  9741. return\
  9742. end\
  9743. end\
  9744. self:delete(path)\
  9745. end\
  9746. end\
  9747. end\
  9748. function appFrame:copy(path)\
  9749. if path then\
  9750. self:setClipboard(path,win.CB_TEXT)\
  9751. end\
  9752. end\
  9753. function appFrame:paste()\
  9754. local cbType,cbPath=self:getClipboard()\
  9755. if cbType==win.CB_TEXT then\
  9756. if canPaste(cbPath,self.app_curDir)then\
  9757. local copyPath;\
  9758. if pathFolder(cbPath)==self.app_curDir then\
  9759. local counter=1\
  9760. copyPath=string.format(\"%s_%d\",cbPath,counter)\
  9761. while fs.exists(copyPath)do\
  9762. counter=counter+1\
  9763. copyPath=string.format(\"%s_%d\",cbPath,counter)\
  9764. end\
  9765. else\
  9766. copyPath=self.app_curDir..fs.getName(cbPath)\
  9767. if fs.exists(copyPath)then\
  9768. if fs.isDir(copyPath)then\
  9769. if not cmndlg.confirm(self,\"Overwrite\",\
  9770. \"Folder \"..fs.getName(cbPath)..\
  9771. \" already exists.\\nOverwrite all of its contents?\",\
  9772. false,colors.orange)then\
  9773. return\
  9774. end\
  9775. else\
  9776. if not cmndlg.confirm(self,\"Overwrite\",\
  9777. \"File \"..fs.getName(cbPath)..\
  9778. \" already exists.\\nOverwrite?\",\
  9779. false,colors.orange)then\
  9780. return\
  9781. end\
  9782. end\
  9783. end\
  9784. end\
  9785. if fs.exists(copyPath)then\
  9786. fs.delete(copyPath)\
  9787. end\
  9788. fs.copy(cbPath,copyPath)\
  9789. self:fillList()\
  9790. end\
  9791. end\
  9792. end\
  9793. function appFrame:updateStatus()\
  9794. local info;\
  9795. if self:getSelectedPath()then\
  9796. if fs.isDir(self:getSelectedPath())then\
  9797. local freeSize=\
  9798. math.floor((fs.getFreeSpace(self:getSelectedPath())+50)/100)/10\
  9799. info=string.format(\"%d items %fkb free\",\
  9800. table.maxn(fs.list(self:getSelectedPath())),\
  9801. freeSize)\
  9802. else\
  9803. local freeSize=\
  9804. math.floor((fs.getFreeSpace(self.app_curDir)+50)/100)/10\
  9805. local fileSize=fs.getSize(self:getSelectedPath())\
  9806. local fileFlags=iif(fs.isReadOnly(self:getSelectedPath()),\" (r)\",\"\")\
  9807. if fileSize>=1024 then\
  9808. fileSize=math.floor((fileSize+50)/100)/10\
  9809. info=string.format(\"%fkb%s %fkb free\",fileSize,fileFlags,freeSize)\
  9810. else\
  9811. info=string.format(\"%dbytes%s %fkb free\",fileSize,fileFlags,freeSize)\
  9812. end\
  9813. end\
  9814. end\
  9815. if not info then\
  9816. local freeSize=math.floor((fs.getFreeSpace(self.app_curDir)+50)/100)/10\
  9817. info=string.format(\"%fkb free\",freeSize)\
  9818. end\
  9819. self.app_status:setText(info)\
  9820. end\
  9821. function appFrame:updateTitle()\
  9822. local curPath=string.trim(self.app_curDir,\"/\")\
  9823. if curPath:len()>0 then\
  9824. self:setTitle(curPath..\":\"..APP_TITLE)\
  9825. else\
  9826. self:setTitle(APP_TITLE)\
  9827. end\
  9828. end\
  9829. function appFrame:onMove()\
  9830. self.app_items:move(1,1,self.width-2,self.height-2)\
  9831. self.app_status:move(1,self.height-1,self.width-2,1)\
  9832. return false\
  9833. end\
  9834. function appFrame:onFrameActivate(active)\
  9835. if active then\
  9836. local sel=self.app_items:getCurSel()\
  9837. self:fillList()\
  9838. self.app_items:setCurSel(sel)\
  9839. end\
  9840. end\
  9841. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  9842. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  9843. return true\
  9844. end\
  9845. if self:getFocus()==self.app_items then\
  9846. if ctrl and not alt and not shift then\
  9847. if key==keys.o then\
  9848. return self:onCommand(IDM_OPEN)\
  9849. end\
  9850. if key==keys.p then\
  9851. return self:onCommand(IDM_RUN)\
  9852. end\
  9853. if key==keys.n then\
  9854. return self:onCommand(IDM_NEWDIR)\
  9855. end\
  9856. if key==keys.r then\
  9857. return self:onCommand(IDM_RENAME)\
  9858. end\
  9859. if key==keys.l then\
  9860. return self:onCommand(IDM_LABEL)\
  9861. end\
  9862. if key==keys.c then\
  9863. return self:onCommand(IDM_COPY)\
  9864. end\
  9865. if key==keys.b then\
  9866. return self:onCommand(IDM_PASTE)\
  9867. end\
  9868. if key==keys.up then\
  9869. return self:onCommand(IDM_UPDIR)\
  9870. end\
  9871. elseif not ctrl and alt and not shift then\
  9872. if key==keys.m then\
  9873. self:onMenu()\
  9874. return true\
  9875. end\
  9876. elseif not ctrl and not alt and not shift then\
  9877. if key==keys.delete then\
  9878. return self:onCommand(IDM_DELETE)\
  9879. end\
  9880. if key==keys.enter then\
  9881. self:doDefaultAction()\
  9882. return true\
  9883. end\
  9884. end\
  9885. end\
  9886. return false\
  9887. end\
  9888. function appFrame:onChildRightClick(child,x,y)\
  9889. if child==self.app_items then\
  9890. self.app_items:setFocus()\
  9891. self:onMenu(self:screenToWnd(x,y))\
  9892. return true\
  9893. end\
  9894. return false\
  9895. end\
  9896. function appFrame:onCreate()\
  9897. self:dress(APP_TITLE)\
  9898. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  9899. menuBtn:setColors(menuBtn:getColors().frameText,\
  9900. menuBtn:getColors().titleBack,\
  9901. menuBtn:getColors().frameBack)\
  9902. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  9903. self.app_items=win.listWindow:new(self,ID_FILELIST,1,1,self.width-2,self.height-2)\
  9904. self.app_items:setColors(self:getColors().wndText,\
  9905. self:getColors().wndBack,\
  9906. self:getColors().wndBack,\
  9907. self:getColors().selectedText,\
  9908. self:getColors().selectedBack)\
  9909. self.app_items:setFocus()\
  9910. self.app_status=win.labelWindow:new(self,ID_STATUS,1,self.height-1,\"\")\
  9911. self.app_status:move(1,self.height-1,self.width-2,1)\
  9912. self:wantEvent(\"disk\")\
  9913. self:wantEvent(\"disk_eject\")\
  9914. self.app_curDir=\"/\"\
  9915. if #appArgs>0 then\
  9916. local initPath=asstring(appArgs[1])\
  9917. if initPath:len()>1 then\
  9918. if initPath:sub(-2)==\"/\" then\
  9919. if fs.isDir(initPath)then\
  9920. self.app_curDir=initPath\
  9921. end\
  9922. elseif fs.exists(initPath)then\
  9923. if fs.isDir(initPath)then\
  9924. self.app_curDir=initPath..\"/\"\
  9925. else\
  9926. initPath=initPath:sub(1,-(fs.getName(initPath):len()+1))\
  9927. if fs.isDir(initPath)then\
  9928. self.app_curDir=initPath\
  9929. end\
  9930. end\
  9931. end\
  9932. end\
  9933. end\
  9934. self:fillList()\
  9935. self:setActiveTopFrame()\
  9936. return true\
  9937. end\
  9938. appFrame:runApp()",
  9939. "<default>=/win/apps/notepad\
  9940. html=/win/apps/browse\
  9941. htm=/win/apps/browse\
  9942. email=/win/apps/emread\
  9943. ",
  9944. "local appArgs={...}\
  9945. local appFrame=win.createAppFrame()\
  9946. local APP_TITLE=\"browse\"\
  9947. local ID_MENUBTN=100\
  9948. local ID_ADDRESS=101\
  9949. local ID_REQUEST=102\
  9950. local ID_VIEWER=103\
  9951. local IDM_OPEN=1001\
  9952. local IDM_SAVEAS=1002\
  9953. local IDM_PRINT=1003\
  9954. local IDM_BACK=1004\
  9955. local IDM_FORWARD=1005\
  9956. local IDM_SHOWBAR=1006\
  9957. local IDM_QUITAPP=1007\
  9958. local history=win.__classBase:base()\
  9959. function history:constructor(strict)\
  9960. self.hist__cache={}\
  9961. self.hist__index=0\
  9962. self.strict=strict==true\
  9963. return self\
  9964. end\
  9965. function history:cache(address)\
  9966. if address:sub(1,4)~=\"ftp:\" then\
  9967. if self.strict then\
  9968. while #self.hist__cache>self.hist__index do\
  9969. table.remove(self.hist__cache,#self.hist__cache)\
  9970. end\
  9971. self.hist__index=self.hist__index+1\
  9972. self.hist__cache[self.hist__index]=address\
  9973. else\
  9974. for i=#self.hist__cache,1,-1 do\
  9975. if self.hist__cache[i]==address then\
  9976. table.remove(self.hist__cache,i)\
  9977. end\
  9978. end\
  9979. self.hist__cache[#self.hist__cache+1]=address\
  9980. self.hist__index=#self.hist__cache\
  9981. end\
  9982. end\
  9983. end\
  9984. function history:canNext()\
  9985. return self.hist__index<#self.hist__cache\
  9986. end\
  9987. function history:canPrior()\
  9988. return self.hist__index>1\
  9989. end\
  9990. function history:next()\
  9991. if self:canNext()then\
  9992. self.hist__index=self.hist__index+1\
  9993. return self.hist__cache[self.hist__index]\
  9994. end\
  9995. return nil\
  9996. end\
  9997. function history:prior()\
  9998. if self:canPrior()then\
  9999. self.hist__index=self.hist__index-1\
  10000. return self.hist__cache[self.hist__index]\
  10001. end\
  10002. return nil\
  10003. end\
  10004. function history:clear()\
  10005. self.hist__cache={}\
  10006. self.hist__index=0\
  10007. end\
  10008. function appFrame:onReceive(msg)\
  10009. if(msg.recipientName or msg.recipientId)then\
  10010. if msg.data.path and msg.data.content then\
  10011. if msg.context==\"http_response\" then\
  10012. self.app_viewer:setText(msg.data.content)\
  10013. self.app_curAddress=msg.data.path\
  10014. self.app_curFile=self.app_viewer:getTitle(fs.getName(msg.data.path))\
  10015. self:updateTitle()\
  10016. return true\
  10017. end\
  10018. if msg.context==\"ftp_response\" then\
  10019. local path=cmndlg.saveFile(self,fs.getName(msg.data.path),\
  10020. nil,nil,self:safePopupColor())\
  10021. if path then\
  10022. local hFile=fs.open(path,\"w\")\
  10023. if hFile then\
  10024. hFile.write(msg.data.content)\
  10025. hFile.close()\
  10026. self.app_curPath=path\
  10027. else\
  10028. self:msgBox(\"File Error\",\"Could not write file \"..path,colors.red)\
  10029. end\
  10030. end\
  10031. return true\
  10032. end\
  10033. end\
  10034. end\
  10035. return false\
  10036. end\
  10037. function appFrame:onSent(msg,success)\
  10038. if not success then\
  10039. if msg.context==\"ftp_request\" then\
  10040. self:msgBox(\"Error\",\
  10041. \"Could not download \"..msg.data.path..\" from \"..msg.recipientName..\
  10042. \".\\nThe server may be down or the file does not exist.\",colors.red)\
  10043. else\
  10044. self.app_viewer:serverNotFound(msg.data.address)\
  10045. end\
  10046. end\
  10047. return true\
  10048. end\
  10049. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  10050. if event==\"btn_click\" then\
  10051. if p1:getId()==ID_MENUBTN then\
  10052. self:onMenu()\
  10053. return true\
  10054. end\
  10055. if p1:getId()==ID_REQUEST then\
  10056. self:onSendRequest()\
  10057. return true\
  10058. end\
  10059. elseif event==\"menu_cmd\" then\
  10060. return self:onCommand(p1)\
  10061. elseif event==\"link_click\" then\
  10062. self:onSendRequest(self.app_viewer:mergeAddress(p2,self.app_curAddress,p3))\
  10063. return true\
  10064. end\
  10065. return false\
  10066. end\
  10067. function appFrame:onPrintPage(gdi,page,data)\
  10068. local width,height=gdi:getPageSize()\
  10069. local map=data.data.map\
  10070. local topLine=((page-1)*height)\
  10071. local firstMap,lastMap=map:getRange(topLine,topLine+height-1)\
  10072. if firstMap then\
  10073. for i=firstMap,lastMap,1 do\
  10074. if map[i].text:len()>0 then\
  10075. gdi:write(map[i].text,map[i].column,(map[i].line-topLine))\
  10076. end\
  10077. end\
  10078. end\
  10079. return(lastMap<#map)\
  10080. end\
  10081. function appFrame:onPrintData()\
  10082. local title=self.app_curFile\
  10083. local data=\
  10084. {\
  10085. map=self.app_viewer:getMap(25)\
  10086. }\
  10087. local pages=math.ceil(data.map:lines()/21)\
  10088. if title:sub(-4)==\".htm\" then\
  10089. title=title:sub(1,-5)\
  10090. elseif title:sub(-5)==\".html\" then\
  10091. title=title:sub(1,-6)\
  10092. end\
  10093. return win.applicationFrame.onPrintData(self,title,data,pages,self:safePopupColor())\
  10094. end\
  10095. function appFrame:onMove()\
  10096. if self:isBarVisible()then\
  10097. self.app_address:move(2,1,self.width-5)\
  10098. self.app_request:move(self.width-3)\
  10099. self.app_viewer:move(0,2,self.width,self.height-2)\
  10100. else\
  10101. self.app_viewer:move(0,1,self.width,self.height-1)\
  10102. end\
  10103. return false\
  10104. end\
  10105. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  10106. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  10107. return true\
  10108. end\
  10109. if not ctrl and not alt and not shift then\
  10110. if key==keys.enter then\
  10111. if wnd==self.app_address then\
  10112. self:onSendRequest()\
  10113. return true\
  10114. end\
  10115. end\
  10116. if key==keys.up then\
  10117. if wnd==self.app_address then\
  10118. self:onPriorAddress()\
  10119. return true\
  10120. end\
  10121. end\
  10122. if key==keys.down then\
  10123. if wnd==self.app_address then\
  10124. self:onNextAddress()\
  10125. return true\
  10126. end\
  10127. end\
  10128. elseif ctrl and not alt and not shift then\
  10129. if key==keys.left then\
  10130. return self:onCommand(IDM_BACK)\
  10131. end\
  10132. if key==keys.right then\
  10133. return self:onCommand(IDM_FORWARD)\
  10134. end\
  10135. if key==keys.o then\
  10136. return self:onCommand(IDM_OPEN)\
  10137. end\
  10138. if key==keys.n then\
  10139. return self:onCommand(IDM_SHOWBAR)\
  10140. end\
  10141. elseif not ctrl and alt and not shift then\
  10142. if key==keys.m then\
  10143. self:onMenu()\
  10144. return true\
  10145. end\
  10146. end\
  10147. return false\
  10148. end\
  10149. function appFrame:onQuit()\
  10150. if self.connectionName then\
  10151. self:commClose(self.connectionName)\
  10152. end\
  10153. return false\
  10154. end\
  10155. function appFrame:onCreate()\
  10156. self:dress(APP_TITLE)\
  10157. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  10158. menuBtn:setColors(menuBtn:getColors().frameText,\
  10159. menuBtn:getColors().titleBack,\
  10160. menuBtn:getColors().frameBack)\
  10161. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  10162. self.app_address=win.inputWindow:new(self,ID_ADDRESS,2,1,\
  10163. self.width-5,\"\",\"Address\")\
  10164. self.app_request=win.buttonWindow:new(self,ID_REQUEST,\
  10165. self.width-3,1,\">\")\
  10166. self.app_viewer=html.browserWindow:new(self,ID_VIEWER,0,2,\
  10167. self.width,self.height-2)\
  10168. self.app_address:setFocus()\
  10169. self.app_curAddress=nil\
  10170. self.app_curPath=nil\
  10171. self.app_curFile=\"\"\
  10172. self.app_networkId=\"wide_area_network\"\
  10173. self.app_appId=APP_TITLE..tostring(math.random(1,65535))\
  10174. self.app_addressHistory=history:new(false)\
  10175. self.app_pageHistory=history:new(true)\
  10176. if #appArgs>0 then\
  10177. if appArgs[1]==\"-a\" then\
  10178. self:showBar(false)\
  10179. if #appArgs>1 then\
  10180. self:onSendRequest(appArgs[2])\
  10181. end\
  10182. else\
  10183. self:onSendRequest(appArgs[1])\
  10184. end\
  10185. end\
  10186. self:setActiveTopFrame()\
  10187. return true\
  10188. end\
  10189. function appFrame:onMenu()\
  10190. local menu=win.menuWindow:new(self)\
  10191. menu:addString(\"Open     Ctrl+O\",IDM_OPEN)\
  10192. menu:addString(\"Save as\",IDM_SAVEAS)\
  10193. menu:addString(\"Print\",IDM_PRINT)\
  10194. menu:addString(\"----------------\")\
  10195. local sep=false\
  10196. if self.app_pageHistory:canPrior()then\
  10197. menu:addString(\"Back    Ctrl+<-\",IDM_BACK)\
  10198. sep=true\
  10199. end\
  10200. if self.app_pageHistory:canNext()then\
  10201. menu:addString(\"Forward Ctrl+->\",IDM_FORWARD)\
  10202. sep=true\
  10203. end\
  10204. if sep then\
  10205. menu:addString(\"----------------\")\
  10206. end\
  10207. if self:isBarVisible()then\
  10208. menu:addString(\"Hide bar Ctrl+N\",IDM_SHOWBAR)\
  10209. else\
  10210. menu:addString(\"Show bar Ctrl+N\",IDM_SHOWBAR)\
  10211. end\
  10212. menu:addString(\"----------------\")\
  10213. menu:addString(\"Quit\",IDM_QUITAPP)\
  10214. menu:track(0,1)\
  10215. end\
  10216. function appFrame:onCommand(cmdId)\
  10217. if cmdId==IDM_OPEN then\
  10218. self:onOpenFile()\
  10219. return true\
  10220. end\
  10221. if cmdId==IDM_SAVEAS then\
  10222. self:onSaveFileAs()\
  10223. return true\
  10224. end\
  10225. if cmdId==IDM_PRINT then\
  10226. self:printDoc()\
  10227. return true\
  10228. end\
  10229. if cmdId==IDM_BACK then\
  10230. self:onBack()\
  10231. return true\
  10232. end\
  10233. if cmdId==IDM_FORWARD then\
  10234. self:onForward()\
  10235. return true\
  10236. end\
  10237. if cmdId==IDM_SHOWBAR then\
  10238. self:showBar()\
  10239. return true\
  10240. end\
  10241. if cmdId==IDM_QUITAPP then\
  10242. self:quitApp()\
  10243. return true\
  10244. end\
  10245. return false\
  10246. end\
  10247. function appFrame:showBar(show)\
  10248. show=show or(not self:isBarVisible())\
  10249. self.app_address:show(show)\
  10250. self.app_request:show(show)\
  10251. self:onMove()\
  10252. if show then\
  10253. self.app_address:setSel(0,-1)\
  10254. self.app_address:setFocus()\
  10255. end\
  10256. end\
  10257. function appFrame:isBarVisible()\
  10258. return self.app_address:isShown()\
  10259. end\
  10260. function appFrame:connect()\
  10261. if not self.connectionName then\
  10262. local port=80\
  10263. local wireless=true\
  10264. local timeout=5\
  10265. local ini=fs.loadIniFile(self:getAppPath()..\".ini\")\
  10266. if ini then\
  10267. port=asnumber(ini:find(\"port\"),80)\
  10268. timeout=asnumber(ini:find(\"timeout\"),5)\
  10269. self.app_networkId=(ini:find(\"network\"))or self.app_networkId\
  10270. wireless=((ini:find(\"wireless\"))or \"true\")~=\"false\"\
  10271. end\
  10272. local con=self:commOpen(nil,wireless,port,timeout,false)\
  10273. if not con then\
  10274. self:msgBox(\"Connection\",\"Could not connect to modem!\",colors.red)\
  10275. return false\
  10276. end\
  10277. self.connectionName=con:getName()\
  10278. self:wantMessages(self.app_appId,self.connectionName)\
  10279. self:wantMessages(self.app_networkId,self.connectionName)\
  10280. end\
  10281. return true\
  10282. end\
  10283. function appFrame:updateTitle()\
  10284. if self.app_curFile:len()>0 then\
  10285. self:setTitle(self.app_curFile..\":\"..APP_TITLE)\
  10286. else\
  10287. self:setTitle(APP_TITLE)\
  10288. end\
  10289. end\
  10290. function appFrame:openFile(path)\
  10291. path=tostring(path)\
  10292. if path:sub(1,5)==\"file:\" then\
  10293. path=path:sub(6)\
  10294. end\
  10295. local hFile=fs.open(path,\"r\")\
  10296. if hFile then\
  10297. self.app_viewer:setText(hFile.readAll())\
  10298. hFile.close()\
  10299. self.app_curPath=path\
  10300. self.app_curAddress=\"file:\"..path\
  10301. self.app_curFile=self.app_viewer:getTitle(fs.getName(self.app_curPath))\
  10302. self:updateTitle()\
  10303. else\
  10304. self:msgBox(\"File Error\",\"Could not read file \"..path,colors.red)\
  10305. end\
  10306. end\
  10307. function appFrame:onOpenFile()\
  10308. local path=cmndlg.openFile(self,self.app_curPath,nil,nil,nil,\
  10309. self:safePopupColor())\
  10310. if path then\
  10311. self:onSendRequest(\"file:\"..path)\
  10312. end\
  10313. end\
  10314. function appFrame:saveFileAs(path)\
  10315. local hFile=fs.open(path,\"w\")\
  10316. if hFile then\
  10317. hFile.write(self.app_viewer:serialize())\
  10318. hFile.close()\
  10319. self.app_curPath=path\
  10320. self.app_curFile=fs.getName(self.app_curPath)\
  10321. self:updateTitle()\
  10322. else\
  10323. self:msgBox(\"File Error\",\"Could not write file \"..path,colors.red)\
  10324. end\
  10325. end\
  10326. function appFrame:onSaveFileAs()\
  10327. local path=cmndlg.saveFile(self,self.app_curPath,nil,nil,\
  10328. self:safePopupColor())\
  10329. if path then\
  10330. self:saveFileAs(path)\
  10331. end\
  10332. end\
  10333. function appFrame:sendRequest(address)\
  10334. if self:connect()then\
  10335. local path,domain,protocol=self.app_viewer:splitAddress(address)\
  10336. local context=protocol..\"_request\"\
  10337. self:sendMessage(domain,self.app_networkId,context,\
  10338. {\
  10339. application=self.app_appId,\
  10340. protocol=protocol,\
  10341. domain=domain,\
  10342. path=path,\
  10343. address=address\
  10344. },self.connectionName)\
  10345. end\
  10346. end\
  10347. function appFrame:onSendRequest(address,record)\
  10348. address=address or self.app_address:getText()\
  10349. if address:len()>0 then\
  10350. local path,domain,protocol=self.app_viewer:splitAddress(address)\
  10351. address=protocol..\":\"..domain..\"/\"..path\
  10352. if protocol==\"file\" then\
  10353. self:openFile(\"/\"..path)\
  10354. else\
  10355. self:sendRequest(address)\
  10356. end\
  10357. self.app_address:setText(address)\
  10358. self.app_address:setSel(0,0)\
  10359. self.app_address:setSel(0,-1)\
  10360. self.app_address:setFocus()\
  10361. self.app_addressHistory:cache(address)\
  10362. if record~=false then\
  10363. self.app_pageHistory:cache(address)\
  10364. end\
  10365. end\
  10366. end\
  10367. function appFrame:onNextAddress()\
  10368. local address=self.app_addressHistory:next()\
  10369. if address then\
  10370. self.app_address:setText(address)\
  10371. self.app_address:setSel(0,0)\
  10372. self.app_address:setSel(0,-1)\
  10373. self.app_address:setFocus()\
  10374. end\
  10375. end\
  10376. function appFrame:onPriorAddress()\
  10377. local address=self.app_addressHistory:prior()\
  10378. if address then\
  10379. self.app_address:setText(address)\
  10380. self.app_address:setSel(0,0)\
  10381. self.app_address:setSel(0,-1)\
  10382. self.app_address:setFocus()\
  10383. end\
  10384. end\
  10385. function appFrame:onForward()\
  10386. local address=self.app_pageHistory:next()\
  10387. if address then\
  10388. self:onSendRequest(address,false)\
  10389. end\
  10390. end\
  10391. function appFrame:onBack()\
  10392. local address=self.app_pageHistory:prior()\
  10393. if address then\
  10394. self:onSendRequest(address,false)\
  10395. end\
  10396. end\
  10397. function appFrame:safePopupColor()\
  10398. if self.app_viewer:getBgColor()==self:getColors().popupBack then\
  10399. if self:getColors().popupBack==colors.yellow then\
  10400. return colors.orange\
  10401. end\
  10402. return colors.yellow\
  10403. end\
  10404. return self:getColors().popupBack\
  10405. end\
  10406. appFrame:runApp()",
  10407. "port=80\
  10408. wireless=true\
  10409. network=wide_area_network\
  10410. timeout=5\
  10411. ",
  10412. "local appArgs={...}\
  10413. local appFrame=win.createAppFrame()\
  10414. local APP_TITLE=\"chat\"\
  10415. local ID_MENUBTN=101\
  10416. local ID_PARTNER=102\
  10417. local ID_EXCLUSIVE=103\
  10418. local ID_SAY=104\
  10419. local ID_SEND=105\
  10420. local ID_RESPONSE=106\
  10421. local IDM_CLEARMSGS=1001\
  10422. local IDM_QUITAPP=1002\
  10423. function appFrame:onReceive(msg)\
  10424. if msg.application==APP_TITLE and msg.context==\"message\" then\
  10425. local partner=self.app_partner:getText()\
  10426. local exclusive=(partner:len()>0 and self.app_exclusive:getChecked())\
  10427. if(exclusive and msg.senderName==partner)or not exclusive then\
  10428. local name=iif(msg.recipientName,\"[\"..msg.senderName..\"]\",msg.senderName)\
  10429. self.app_response:setText(\
  10430. string.format(\"%s%s: %s\\n\\n\",self.app_response:getText(),\
  10431. name,msg.data))\
  10432. local cx,cy=self.app_response:getScrollSize()\
  10433. self.app_response:setScrollOrg(0,cy)\
  10434. return true\
  10435. end\
  10436. end\
  10437. return false\
  10438. end\
  10439. function appFrame:onSent(msg,success)\
  10440. local result=\"\"\
  10441. if not success then\
  10442. result=\"<failed> \"\
  10443. end\
  10444. if msg.recipientName then\
  10445. self.app_response:setText(\
  10446. string.format(\"%s%s%s [%s]: %s\\n\\n\",self.app_response:getText(),\
  10447. result,msg.senderName,\
  10448. msg.recipientName,msg.data))\
  10449. else\
  10450. self.app_response:setText(\
  10451. string.format(\"%s%s%s: %s\\n\\n\",self.app_response:getText(),\
  10452. result,msg.senderName,msg.data))\
  10453. end\
  10454. local cx,cy=self.app_response:getScrollSize()\
  10455. self.app_response:setScrollOrg(0,cy)\
  10456. return true\
  10457. end\
  10458. function appFrame:onSendMsg()\
  10459. if self.app_say:getText():len()>0 then\
  10460. local recipient=self.app_partner:getText()\
  10461. if recipient:len()<1 then\
  10462. recipient=nil\
  10463. end\
  10464. self:sendMessage(recipient,APP_TITLE,\"message\",self.app_say:getText())\
  10465. self.app_say:setSel(0,-1)\
  10466. self.app_say:setFocus()\
  10467. end\
  10468. end\
  10469. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  10470. if event==\"btn_click\" then\
  10471. if p1:getId()==ID_MENUBTN then\
  10472. self:onMenu()\
  10473. return true\
  10474. end\
  10475. if p1:getId()==ID_SEND then\
  10476. self:onSendMsg()\
  10477. return true\
  10478. end\
  10479. elseif event==\"menu_cmd\" then\
  10480. return self:onCommand(p1)\
  10481. end\
  10482. return false\
  10483. end\
  10484. function appFrame:onMove()\
  10485. self.app_partner:move(nil,nil,self.width-9)\
  10486. self.app_exclusive:move(self.width-7)\
  10487. self.app_response:move(nil,nil,self.width-2,self.height-7)\
  10488. self.app_say:move(nil,self.height-2,self.width-3)\
  10489. self.app_send:move(self.width-2,self.height-2)\
  10490. return false\
  10491. end\
  10492. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  10493. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  10494. return true\
  10495. end\
  10496. if ctrl and not alt and not shift then\
  10497. if key==keys.m then\
  10498. return self:onCommand(IDM_CLEARMSGS)\
  10499. end\
  10500. elseif not ctrl and not alt and not shift then\
  10501. if key==keys.enter then\
  10502. if wnd==self.app_say then\
  10503. self:onSendMsg()\
  10504. return true\
  10505. end\
  10506. end\
  10507. end\
  10508. return false\
  10509. end\
  10510. function appFrame:onQuit()\
  10511. self:unwantMessages()\
  10512. return false\
  10513. end\
  10514. function appFrame:onMenu()\
  10515. local menu=win.menuWindow:new(self)\
  10516. menu:addString(\"Clear Msgs Ctrl+M\",IDM_CLEARMSGS)\
  10517. menu:addString(\"-----------------\")\
  10518. menu:addString(\"Quit App\",IDM_QUITAPP)\
  10519. menu:track(0,1)\
  10520. end\
  10521. function appFrame:onCommand(cmdId)\
  10522. if cmdId==IDM_CLEARMSGS then\
  10523. self.app_response:setText()\
  10524. return true\
  10525. end\
  10526. if cmdId==IDM_QUITAPP then\
  10527. self:quitApp()\
  10528. return true\
  10529. end\
  10530. return false\
  10531. end\
  10532. function appFrame:onCreate()\
  10533. self:dress(string.format(\"%s [%s]\",APP_TITLE,asstring(os.getComputerLabel())))\
  10534. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  10535. menuBtn:setColors(menuBtn:getColors().frameText,\
  10536. menuBtn:getColors().titleBack,\
  10537. menuBtn:getColors().frameBack)\
  10538. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  10539. self.app_partner=win.inputWindow:new(self,ID_PARTNER,1,2,\
  10540. self.width-9,\"\",\"Recipient\")\
  10541. self.app_exclusive=win.checkWindow:new(self,ID_EXCLUSIVE,\
  10542. self.width-7,2,\"Only\",true)\
  10543. self.app_response=win.textWindow:new(self,ID_RESPONSE,1,4,\
  10544. self.width-2,self.height-7,\"\")\
  10545. self.app_response:setBgColor(colors.white)\
  10546. self.app_say=win.inputWindow:new(self,ID_SAY,1,self.height-2,\
  10547. self.width-3,\"\",\"Message\")\
  10548. self.app_send=win.buttonWindow:new(self,ID_SEND,self.width-2,\
  10549. self.height-2,\">\")\
  10550. self.app_say:setFocus()\
  10551. self:setActiveTopFrame()\
  10552. if not self:commEnabled()then\
  10553. self:msgBox(\"Connection\",\"No modem connection found to use!\",colors.red)\
  10554. return false\
  10555. end\
  10556. self:wantMessages(APP_TITLE)\
  10557. return true\
  10558. end\
  10559. appFrame:runApp()\
  10560. ",
  10561. "local appArgs={...}\
  10562. local appFrame=win.createAppFrame()\
  10563. local APP_TITLE=\"Shutdown\"\
  10564. local ID_SHUTDOWN=100\
  10565. local ID_RESTART=101\
  10566. local ID_CANCEL=102\
  10567. local ID_LOCKSCRNS=103\
  10568. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  10569. if event==\"btn_click\" then\
  10570. if p1:getId()==ID_LOCKSCRNS then\
  10571. self:lockScreens()\
  10572. self:quitApp()\
  10573. return true\
  10574. end\
  10575. if p1:getId()==ID_RESTART then\
  10576. self:clearScreens()\
  10577. os.reboot()\
  10578. return true\
  10579. end\
  10580. if p1:getId()==ID_SHUTDOWN then\
  10581. self:clearScreens()\
  10582. os.shutdown()\
  10583. return true\
  10584. end\
  10585. if p1:getId()==ID_CANCEL then\
  10586. self:quitApp()\
  10587. return true\
  10588. end\
  10589. end\
  10590. return false\
  10591. end\
  10592. function appFrame:onFrameActivate(active)\
  10593. if not active then\
  10594. self:startTimer(0.05)\
  10595. end\
  10596. end\
  10597. function appFrame:onTimer(id)\
  10598. self:quitApp()\
  10599. return false\
  10600. end\
  10601. function appFrame:onMove()\
  10602. local left,vertMid=math.floor((self.width-10)/2),\
  10603. math.floor(self.height/2)\
  10604. if self:getDesktop():canLock()==false then\
  10605. vertMid=vertMid-2\
  10606. end\
  10607. local wnd=self:getWndById(ID_LOCKSCRNS)\
  10608. if wnd then\
  10609. wnd:move(left,vertMid-3)\
  10610. end\
  10611. wnd=self:getWndById(ID_RESTART)\
  10612. if wnd then\
  10613. wnd:move(left,vertMid-1)\
  10614. end\
  10615. wnd=self:getWndById(ID_SHUTDOWN)\
  10616. if wnd then\
  10617. wnd:move(left,vertMid+1)\
  10618. end\
  10619. wnd=self:getWndById(ID_CANCEL)\
  10620. if wnd then\
  10621. wnd:move(left,vertMid+3)\
  10622. end\
  10623. return false\
  10624. end\
  10625. function appFrame:onCreate()\
  10626. self:setText(APP_TITLE)\
  10627. self:setColor(self:getColors().homeText)\
  10628. self:setBgColor(self:getColors().homeBack)\
  10629. local left,vertMid=math.floor((self.width-10)/2),\
  10630. math.floor(self.height/2)\
  10631. if self:getDesktop():canLock()==false then\
  10632. vertMid=vertMid-2\
  10633. end\
  10634. win.buttonWindow:new(self,ID_LOCKSCRNS,left,vertMid-3,\
  10635. \"   Lock   \"):show(self:getDesktop():canLock())\
  10636. win.buttonWindow:new(self,ID_RESTART,left,vertMid-1,\
  10637. \"  Restart \")\
  10638. win.buttonWindow:new(self,ID_SHUTDOWN,left,vertMid+1,\
  10639. \" Shutdown \")\
  10640. local can=win.buttonWindow:new(self,ID_CANCEL,left,vertMid+3,\
  10641. \"  Cancel  \")\
  10642. can:setColors(can:getColors().closeText,\
  10643. can:getColors().closeBack,\
  10644. can:getColors().closeFocus)\
  10645. can:setFocus()\
  10646. self:setActiveTopFrame()\
  10647. return true\
  10648. end\
  10649. function appFrame:clearScreens()\
  10650. local sides=self:getWorkSpace():desktops()\
  10651. for i=1,#sides,1 do\
  10652. local gdi=win.GDI:new(sides[i])\
  10653. if gdi then\
  10654. gdi:setBackgroundColor(colors.black)\
  10655. gdi:clear(0,0,gdi:getSize())\
  10656. end\
  10657. end\
  10658. end\
  10659. function appFrame:lockScreens()\
  10660. local sides=self:getWorkSpace():desktops()\
  10661. for i=1,#sides,1 do\
  10662. self:getWorkSpace():getDesktop(sides[i]):lockScreen()\
  10663. end\
  10664. end\
  10665. appFrame:runApp()",
  10666. "local appArgs={...}\
  10667. local appFrame=win.createAppFrame()\
  10668. local APP_TITLE=\"Manager\"\
  10669. local ID_OK=1\
  10670. local ID_DESKTOP=100\
  10671. local ID_DTSELECT=101\
  10672. local ID_APPLIST=102\
  10673. local ID_ADD=103\
  10674. local ID_DELETE=104\
  10675. local ID_EDIT=105\
  10676. local ID_MOVEUP=106\
  10677. local ID_MOVEDOWN=107\
  10678. local ID_THEME=108\
  10679. local ID_STARTUP=109\
  10680. local ID_SYSTEM=110\
  10681. local ID_LABEL=111\
  10682. local ID_LOG=112\
  10683. local ID_CLEAN=113\
  10684. local ID_VERSION=114\
  10685. local ID_NAME=200\
  10686. local ID_PATH=201\
  10687. local ID_PATHBROWSE=202\
  10688. local ID_ARGS=203\
  10689. local ID_DTLIST=300\
  10690. local ID_DEFTHEME=400\
  10691. local ID_COLORDEMO=401\
  10692. local ID_COLORLIST=402\
  10693. local ID_DTMANAGE_FRAME=34176\
  10694. local DT_STARTUP_FILE=\
  10695. \"; auto-run at startup\\n;run=fullPath [arguments]\\n\\n; name of desktop\\n;home=Home\\n\\n; buffer display drawing\\nbuffer=true\\n\\n; start in full screen\\n;fullscreen=false\"\
  10696. local SYS_STARTUP_FILE=\
  10697. \"; start up delay\\ndelay=2\\n\\n; system password\\n;password=password\\n\\n; additional paths\\n;path=path\\n\\n; run before starting win\\n;pre=path\\n\\n; apis to load at startup\\napi=/win/apis/cmndlg\\napi=/win/apis/html\\n\\n; comm\\n;comm=system\\n;systemtime=5\\n;systemport=10\\n;systemrelay=true\\n;systemwireless=true\"\
  10698. local function safeColor(color)\
  10699. return iif(color==colors.orange,colors.yellow,colors.orange)\
  10700. end\
  10701. local selectDesktop=win.popupFrame:base()\
  10702. function selectDesktop:onCreate(desktop)\
  10703. self:dress(\"Desktop\")\
  10704. local rt=self:getDesktop():getWorkArea()\
  10705. local width=rt.width*0.8\
  10706. self.sd_desktops=win.listWindow:new(self,ID_DTLIST,1,2,width-2,5)\
  10707. win.buttonWindow:new(self,ID_OK,width-5,7,\" Ok \")\
  10708. local sides=self:getWorkSpace():desktops()\
  10709. for i=1,#sides,1 do\
  10710. self.sd_desktops:addString(sides[i])\
  10711. end\
  10712. self.sd_desktops:setCurSel(self.sd_desktops:find(desktop,0,true))\
  10713. self.sd_desktops:setFocus()\
  10714. self:move(nil,nil,width,9)\
  10715. return true\
  10716. end\
  10717. function selectDesktop:onEvent(event,p1,p2,p3,p4,p5,...)\
  10718. if event==\"btn_click\" then\
  10719. if p1:getId()==ID_OK then\
  10720. if self.sd_desktops:getString()then\
  10721. self:close(ID_OK)\
  10722. end\
  10723. return true\
  10724. end\
  10725. elseif event==\"list_double_click\" then\
  10726. if p1:getId()==ID_DTLIST then\
  10727. self:sendEvent(\"btn_click\",self:getWndById(ID_OK))\
  10728. return true\
  10729. end\
  10730. end\
  10731. return false\
  10732. end\
  10733. local editItem=win.popupFrame:base()\
  10734. function editItem:onCreate(title,name,path,args)\
  10735. self:dress(title)\
  10736. local rt=self:getDesktop():getWorkArea()\
  10737. local width=rt.width*0.8\
  10738. self.ei_name=win.inputWindow:new(self,ID_NAME,1,2,width-2,\
  10739. asstring(name),\"Name\")\
  10740. self.ei_name:setFocus()\
  10741. self.ei_path=win.inputWindow:new(self,ID_PATH,1,4,width-3,\
  10742. asstring(path),\"Path\")\
  10743. win.buttonWindow:new(self,ID_PATHBROWSE,width-2,4,\"@\")\
  10744. self.ei_args=win.inputWindow:new(self,ID_ARGS,1,6,width-2,\
  10745. asstring(args),\"Arguments\")\
  10746. win.buttonWindow:new(self,ID_OK,width-5,7,\" Ok \")\
  10747. self:move(nil,nil,width,9)\
  10748. return true\
  10749. end\
  10750. function editItem:onEvent(event,p1,p2,p3,p4,p5,...)\
  10751. if event==\"btn_click\" then\
  10752. if p1:getId()==ID_OK then\
  10753. self:close(ID_OK)\
  10754. return true\
  10755. end\
  10756. if p1:getId()==ID_PATHBROWSE then\
  10757. local path=cmndlg.openFile(self,self.ei_path:getText())\
  10758. if path then\
  10759. self.ei_path:setText(path)\
  10760. end\
  10761. return true\
  10762. end\
  10763. end\
  10764. return false\
  10765. end\
  10766. local editTheme=win.popupFrame:base()\
  10767. function editTheme:onCreate(desktop)\
  10768. self:dress(\"Theme\")\
  10769. self.et_desktop=desktop\
  10770. self.et_theme=self:loadTheme()\
  10771. self.et_colorsTop=0\
  10772. local rt=self:getDesktop():getWorkArea()\
  10773. self.et_demo=win.labelWindow:new(self,ID_COLORDEMO,1,1,\"     \")\
  10774. self.et_default=win.buttonWindow:new(self,ID_DEFTHEME,1,1,\" Default \")\
  10775. self.et_ok=win.buttonWindow:new(self,ID_OK,1,1,\" Save \")\
  10776. self:buildControls()\
  10777. self:move(nil,nil,27,rt.height)\
  10778. return true\
  10779. end\
  10780. function editTheme:buildControls()\
  10781. local rt=self:getDesktop():getWorkArea()\
  10782. local id=ID_COLORLIST+1\
  10783. local keys={}\
  10784. self.et_colorsTop=2\
  10785. local wnd=self:getWndById(id)\
  10786. while wnd do\
  10787. wnd:destroyWnd()\
  10788. id=id+1\
  10789. wnd=self:getWndById(id)\
  10790. end\
  10791. wnd=self:getWndById(ID_COLORLIST)\
  10792. if wnd then\
  10793. wnd:destroyWnd()\
  10794. end\
  10795. wnd=nil\
  10796. id=ID_COLORLIST+1\
  10797. for k,v in pairs(self.et_theme)do\
  10798. if k~=\"color\" then\
  10799. keys[#keys+1]=k\
  10800. end\
  10801. end\
  10802. table.sort(keys)\
  10803. for i=1,#keys,1 do\
  10804. win.labelWindow:new(self,id,1,self.et_colorsTop,\
  10805. keys[i]):setBgColor(self:getColors().popupBack)\
  10806. win.inputWindow:new(self,id+1,21,self.et_colorsTop,5,\
  10807. self.et_theme[keys[i]])\
  10808. self.et_colorsTop=self.et_colorsTop+1\
  10809. id=id+2\
  10810. end\
  10811. self.et_colors=win.listWindow:new(self,ID_COLORLIST,1,self.et_colorsTop+1,25,\
  10812. rt.height-self.et_colorsTop-3)\
  10813. for k,v in pairs(self.et_theme.color)do\
  10814. self.et_colors:addString(k,v)\
  10815. end\
  10816. self.et_colors:sort()\
  10817. self.et_demo:move(1,rt.height-2,nil,nil,win.WND_BOTTOM)\
  10818. self.et_default:move(10,rt.height-2,nil,nil,win.WND_BOTTOM)\
  10819. self.et_ok:move(20,rt.height-2,nil,nil,win.WND_BOTTOM)\
  10820. wnd=self:getWndById(ID_COLORLIST+2)\
  10821. if wnd then\
  10822. wnd:setFocus()\
  10823. end\
  10824. self.et_colors:setCurSel(1)\
  10825. end\
  10826. function editTheme:onResize()\
  10827. local rt=self:getDesktop():getWorkArea()\
  10828. self:move(nil,nil,nil,rt.height)\
  10829. self.et_colors:move(nil,nil,nil,rt.height-self.et_colorsTop-3)\
  10830. self.et_demo:move(1,rt.height-2,nil,nil,win.WND_BOTTOM)\
  10831. self.et_default:move(10,rt.height-2,nil,nil,win.WND_BOTTOM)\
  10832. self.et_ok:move(20,rt.height-2,nil,nil,win.WND_BOTTOM)\
  10833. return false\
  10834. end\
  10835. function editTheme:onEvent(event,p1,p2,p3,p4,p5,...)\
  10836. if event==\"btn_click\" then\
  10837. if p1:getId()==ID_OK then\
  10838. if self:saveTheme()then\
  10839. self:close(ID_OK)\
  10840. else\
  10841. self:msgBox(\"Error\",\"Could not save theme.\",colors.red)\
  10842. end\
  10843. return true\
  10844. end\
  10845. if p1:getId()==ID_DEFTHEME then\
  10846. self.et_theme=win.desktopTheme:new()\
  10847. self:buildControls()\
  10848. return true\
  10849. end\
  10850. elseif event==\"selection_change\" then\
  10851. if p1:getId()==ID_COLORLIST then\
  10852. if self.et_colors:getCurSel()>0 then\
  10853. self.et_demo:setBgColor(self.et_colors:getData())\
  10854. end\
  10855. return true\
  10856. end\
  10857. elseif event==\"list_double_click\" then\
  10858. if p1:getId()==ID_COLORLIST then\
  10859. if self.et_colors:getCurSel()>0 then\
  10860. local color=cmndlg.color(self,self.et_colors:getData(),safeColor(self:getColors().popupBack))\
  10861. if color then\
  10862. self.et_colors:setData(color)\
  10863. self.et_demo:setBgColor(color)\
  10864. self.et_theme.color[self.et_colors:getString()]=color\
  10865. end\
  10866. end\
  10867. return true\
  10868. end\
  10869. elseif event==\"input_change\" then\
  10870. if p1:getId()>ID_COLORLIST then\
  10871. local label=self:getWndById(p1:getId()-1)\
  10872. if label then\
  10873. local key=label:getText()\
  10874. if type(self.et_theme[key])==\"number\" then\
  10875. self.et_theme[key]=asnumber(p1:getText())\
  10876. elseif type(self.et_theme[key])==\"string\" then\
  10877. self.et_theme[key]=p1:getText()\
  10878. end\
  10879. end\
  10880. return true\
  10881. end\
  10882. end\
  10883. return false\
  10884. end\
  10885. function editTheme:loadTheme()\
  10886. local path=\"/win/\"..self.et_desktop..\"/theme.ini\"\
  10887. local theme=nil\
  10888. if fs.exists(path)and not fs.isDir(path)then\
  10889. local hFile=fs.open(path,\"r\")\
  10890. if hFile then\
  10891. local data=hFile.readAll()\
  10892. if data then\
  10893. theme=textutils.unserialize(data)\
  10894. end\
  10895. hFile.close()\
  10896. end\
  10897. end\
  10898. if not theme then\
  10899. theme=win.desktopTheme:new()\
  10900. end\
  10901. return theme\
  10902. end\
  10903. function editTheme:saveTheme()\
  10904. local path=\"/win/\"..self.et_desktop..\"/theme.ini\"\
  10905. local result=false\
  10906. local hFile=fs.open(path,\"w\")\
  10907. if hFile then\
  10908. local data=textutils.serialize(self.et_theme)\
  10909. if data then\
  10910. hFile.write(data)\
  10911. result=true\
  10912. end\
  10913. hFile.close()\
  10914. end\
  10915. return result\
  10916. end\
  10917. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  10918. if event==\"btn_click\" then\
  10919. if p1:getId()==ID_DTSELECT then\
  10920. self:selectDesktop()\
  10921. return true\
  10922. end\
  10923. if p1:getId()==ID_ADD then\
  10924. self:addItem()\
  10925. return true\
  10926. end\
  10927. if p1:getId()==ID_DELETE then\
  10928. self:deleteItem()\
  10929. return true\
  10930. end\
  10931. if p1:getId()==ID_EDIT then\
  10932. self:editItem()\
  10933. return true\
  10934. end\
  10935. if p1:getId()==ID_MOVEUP then\
  10936. self:moveItemUp()\
  10937. return true\
  10938. end\
  10939. if p1:getId()==ID_MOVEDOWN then\
  10940. self:moveItemDown()\
  10941. return true\
  10942. end\
  10943. if p1:getId()==ID_THEME then\
  10944. self:editTheme()\
  10945. return true\
  10946. end\
  10947. if p1:getId()==ID_STARTUP then\
  10948. self:openStartup()\
  10949. return true\
  10950. end\
  10951. if p1:getId()==ID_SYSTEM then\
  10952. self:openSystem()\
  10953. return true\
  10954. end\
  10955. if p1:getId()==ID_LABEL then\
  10956. self:setLabel()\
  10957. return true\
  10958. end\
  10959. if p1:getId()==ID_LOG then\
  10960. self:openLog()\
  10961. return true\
  10962. end\
  10963. if p1:getId()==ID_CLEAN then\
  10964. self:cleansys()\
  10965. return true\
  10966. end\
  10967. elseif event==\"list_double_click\" then\
  10968. if p1:getId()==ID_APPLIST then\
  10969. self:sendEvent(\"btn_click\",self:getWndById(ID_EDIT))\
  10970. return true\
  10971. end\
  10972. end\
  10973. return false\
  10974. end\
  10975. function appFrame:onQuit()\
  10976. self:saveDesktop()\
  10977. return false\
  10978. end\
  10979. function appFrame:onMove()\
  10980. local width=self.width-2\
  10981. local top=iif(self.height<14,1,2)\
  10982. local left=(self.width-width)/2\
  10983. self.app_desktop:move(left,top,width-1)\
  10984. local wnd=self:getWndById(ID_DTSELECT)\
  10985. if wnd then\
  10986. wnd:move(left+width-1,top)\
  10987. end\
  10988. self.app_appList:move(left,top+2,width-8,\
  10989. math.max(self.height-top-3,9))\
  10990. left=width+left-7\
  10991. wnd=self:getWndById(ID_ADD)\
  10992. if wnd then\
  10993. wnd:move(left,top+2)\
  10994. end\
  10995. wnd=self:getWndById(ID_DELETE)\
  10996. if wnd then\
  10997. wnd:move(left,top+3)\
  10998. end\
  10999. wnd=self:getWndById(ID_EDIT)\
  11000. if wnd then\
  11001. wnd:move(left,top+4)\
  11002. end\
  11003. wnd=self:getWndById(ID_MOVEUP)\
  11004. if wnd then\
  11005. wnd:move(left,top+5)\
  11006. end\
  11007. wnd=self:getWndById(ID_MOVEDOWN)\
  11008. if wnd then\
  11009. wnd:move(left,top+6)\
  11010. end\
  11011. wnd=self:getWndById(ID_THEME)\
  11012. if wnd then\
  11013. wnd:move(left,top+8)\
  11014. end\
  11015. wnd=self:getWndById(ID_STARTUP)\
  11016. if wnd then\
  11017. wnd:move(left,top+9)\
  11018. end\
  11019. wnd=self:getWndById(ID_SYSTEM)\
  11020. if wnd then\
  11021. wnd:move(left,top+10)\
  11022. end\
  11023. wnd=self:getWndById(ID_LABEL)\
  11024. if wnd then\
  11025. wnd:move(left,top+11)\
  11026. end\
  11027. wnd=self:getWndById(ID_LOG)\
  11028. if wnd then\
  11029. wnd:move(left,top+12)\
  11030. end\
  11031. wnd=self:getWndById(ID_CLEAN)\
  11032. if wnd then\
  11033. wnd:move(left,top+13)\
  11034. end\
  11035. wnd=self:getWndById(ID_VERSION)\
  11036. if wnd then\
  11037. wnd:move(1,self.height-1)\
  11038. end\
  11039. return false\
  11040. end\
  11041. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  11042. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  11043. return true\
  11044. end\
  11045. return false\
  11046. end\
  11047. function appFrame:onCreate()\
  11048. local instance=self:getDesktop():getWndById(ID_DTMANAGE_FRAME,false)\
  11049. if instance then\
  11050. instance:setActiveTopFrame()\
  11051. return false\
  11052. end\
  11053. self:setId(ID_DTMANAGE_FRAME)\
  11054. self:dress(APP_TITLE..\":\"..tostring(os.getComputerID()))\
  11055. self.app_loadedDesktop=nil\
  11056. self.app_modified=false\
  11057. local width=self.width-2\
  11058. local top=iif(self.height<14,1,2)\
  11059. local left=(self.width-width)/2\
  11060. self.app_desktop=win.labelWindow:new(self,ID_DESKTOP,left,top,\
  11061. self:getSide())\
  11062. self.app_desktop:move(nil,nil,width-1)\
  11063. self.app_desktop:setColor(self:getColors().wndText)\
  11064. self.app_desktop:setBgColor(self:getColors().wndBack)\
  11065. win.buttonWindow:new(self,ID_DTSELECT,left+width-1,top,\"@\")\
  11066. self.app_appList=win.listWindow:new(self,ID_APPLIST,left,top+2,\
  11067. width-8,math.max(self.height-top-3,9))\
  11068. self.app_appList:setFocus()\
  11069. win.labelWindow:new(self,ID_VERSION,1,self.height-1,\
  11070. \"CCWindows \"..tostring(win.version()))\
  11071. left=width+left-7\
  11072. win.buttonWindow:new(self,ID_ADD,left,top+2,\"  Add  \")\
  11073. win.buttonWindow:new(self,ID_DELETE,left,top+3,\" Remove\")\
  11074. win.buttonWindow:new(self,ID_EDIT,left,top+4,\"  Edit \")\
  11075. win.buttonWindow:new(self,ID_MOVEUP,left,top+5,\"   Up  \")\
  11076. win.buttonWindow:new(self,ID_MOVEDOWN,left,top+6,\"  Down \")\
  11077. win.buttonWindow:new(self,ID_THEME,left,top+8,\" Theme \")\
  11078. win.buttonWindow:new(self,ID_STARTUP,left,top+9,\"Startup\")\
  11079. win.buttonWindow:new(self,ID_SYSTEM,left,top+10,\" System\")\
  11080. win.buttonWindow:new(self,ID_LABEL,left,top+11,\"  Name \")\
  11081. win.buttonWindow:new(self,ID_LOG,left,top+12,\"  Log  \")\
  11082. win.buttonWindow:new(self,ID_CLEAN,left,top+13,\" Clean \")\
  11083. self:loadAppList()\
  11084. self:setActiveTopFrame()\
  11085. return true\
  11086. end\
  11087. function appFrame:loadAppList()\
  11088. self:saveDesktop()\
  11089. self.app_loadedDesktop=self.app_desktop:getText()\
  11090. self.app_appList:resetContent()\
  11091. local lines={}\
  11092. local line,lastLine;\
  11093. local hFile=fs.open(\"/win/\"..self.app_loadedDesktop..\"/desktop.ini\",\"r\")\
  11094. if hFile then\
  11095. line=hFile.readLine()\
  11096. while line do\
  11097. lines[#lines+1]=line\
  11098. line=hFile.readLine()\
  11099. end\
  11100. hFile.close()\
  11101. lastLine=math.floor(#lines/5)*5\
  11102. for line=1,lastLine,5 do\
  11103. local app={\
  11104. name=lines[line],\
  11105. path=lines[line+1],\
  11106. arguments=lines[line+2],\
  11107. dummy1=lines[line+3],\
  11108. dummy2=lines[line+4]\
  11109. }\
  11110. self.app_appList:addString(app.name,app)\
  11111. end\
  11112. end\
  11113. if self.app_appList:count()>0 then\
  11114. self.app_appList:setCurSel(1)\
  11115. end\
  11116. end\
  11117. function appFrame:saveDesktop()\
  11118. if self.app_loadedDesktop and self.app_modified then\
  11119. if cmndlg.confirm(self:getActiveFrame(),\"Save\",\
  11120. \"Save desktop \"..self.app_loadedDesktop..\"?\",true)then\
  11121. local path=\"/win/\"..self.app_loadedDesktop..\"/desktop.ini\"\
  11122. if fs.exists(path..\".bak\")then\
  11123. fs.delete(path..\".bak\")\
  11124. end\
  11125. fs.copy(path,path..\".bak\")\
  11126. local hFile=fs.open(path,\"w\")\
  11127. if hFile then\
  11128. for i=1,self.app_appList:count(),1 do\
  11129. local app=self.app_appList:getData(i)\
  11130. hFile.writeLine(app.name)\
  11131. hFile.writeLine(app.path)\
  11132. hFile.writeLine(app.arguments)\
  11133. hFile.writeLine(app.dummy1)\
  11134. hFile.writeLine(app.dummy2)\
  11135. end\
  11136. hFile.close()\
  11137. end\
  11138. end\
  11139. end\
  11140. end\
  11141. function appFrame:deleteItem()\
  11142. local item=self.app_appList:getCurSel()\
  11143. if item>0 then\
  11144. if cmndlg.confirm(self,\"Remove\",\"Remove \"..self.app_appList:getString()..\"?\")then\
  11145. self.app_appList:removeString(item)\
  11146. self.app_modified=true\
  11147. end\
  11148. end\
  11149. end\
  11150. function appFrame:moveItemUp()\
  11151. local item=self.app_appList:getCurSel()\
  11152. if item>1 then\
  11153. local str,data=self.app_appList:getString(),self.app_appList:getData()\
  11154. self.app_appList:removeString(item)\
  11155. self.app_appList:addString(str,data,item-1)\
  11156. self.app_appList:setCurSel(item-1)\
  11157. self.app_modified=true\
  11158. end\
  11159. end\
  11160. function appFrame:moveItemDown()\
  11161. local item=self.app_appList:getCurSel()\
  11162. if item<self.app_appList:count()then\
  11163. local str,data=self.app_appList:getString(),self.app_appList:getData()\
  11164. self.app_appList:removeString(item)\
  11165. self.app_appList:addString(str,data,item+1)\
  11166. self.app_appList:setCurSel(item+1)\
  11167. self.app_modified=true\
  11168. end\
  11169. end\
  11170. function appFrame:addItem()\
  11171. local dlg=editItem:new(self)\
  11172. if dlg:doModal(\"New App\")==ID_OK then\
  11173. local data={\
  11174. name=dlg.ei_name:getText(),\
  11175. path=dlg.ei_path:getText(),\
  11176. arguments=dlg.ei_args:getText(),\
  11177. dummy1=\"\",\
  11178. dummy2=\"\"\
  11179. }\
  11180. self.app_appList:addString(data.name,data)\
  11181. self.app_modified=true\
  11182. end\
  11183. end\
  11184. function appFrame:editItem()\
  11185. local item=self.app_appList:getCurSel()\
  11186. if item>0 then\
  11187. local data=self.app_appList:getData(item)\
  11188. local dlg=editItem:new(self)\
  11189. if dlg:doModal(\"Edit App\",data.name,data.path,data.arguments)==ID_OK then\
  11190. data={\
  11191. name=dlg.ei_name:getText(),\
  11192. path=dlg.ei_path:getText(),\
  11193. arguments=dlg.ei_args:getText(),\
  11194. dummy1=\"\",\
  11195. dummy2=\"\"\
  11196. }\
  11197. self.app_appList:removeString(item)\
  11198. self.app_appList:addString(data.name,data,item)\
  11199. self.app_appList:setCurSel(item)\
  11200. self.app_modified=true\
  11201. end\
  11202. end\
  11203. end\
  11204. function appFrame:selectDesktop()\
  11205. local dlg=selectDesktop:new(self)\
  11206. if dlg:doModal(self.app_desktop:getText())==ID_OK then\
  11207. self.app_desktop:setText(dlg.sd_desktops:getString())\
  11208. self:loadAppList()\
  11209. end\
  11210. end\
  11211. function appFrame:openStartup()\
  11212. if self.app_loadedDesktop then\
  11213. local path=\"/win/\"..self.app_loadedDesktop..\"/startup.ini\"\
  11214. if not fs.exists(path)then\
  11215. local file=fs.open(path,\"w\")\
  11216. if not file then\
  11217. self:msgBox(\"Error\",\"Error creating \"..path,colors.red)\
  11218. return\
  11219. end\
  11220. file.write(DT_STARTUP_FILE)\
  11221. file.close()\
  11222. end\
  11223. self:getDesktop():runApp(\"/win/apps/notepad\",path)\
  11224. end\
  11225. end\
  11226. function appFrame:openSystem()\
  11227. local path=\"/win/startup.ini\"\
  11228. if not fs.exists(path)then\
  11229. local file=fs.open(path,\"w\")\
  11230. if not file then\
  11231. self:msgBox(\"Error\",\"Error creating \"..path,colors.red)\
  11232. return\
  11233. end\
  11234. file.write(SYS_STARTUP_FILE)\
  11235. file.close()\
  11236. end\
  11237. self:getDesktop():runApp(\"/win/apps/notepad\",path)\
  11238. end\
  11239. function appFrame:openLog()\
  11240. local path=\"/win/win.log\"\
  11241. if not fs.exists(path)then\
  11242. local file=fs.open(path,\"w\")\
  11243. if not file then\
  11244. self:msgBox(\"Error\",\"Error creating \"..path,colors.red)\
  11245. return\
  11246. end\
  11247. file.close()\
  11248. end\
  11249. self:getDesktop():runApp(\"/win/apps/notepad\",path)\
  11250. end\
  11251. function appFrame:cleansys()\
  11252. if cmndlg.confirm(self,\"Clean\",\
  11253. \"This action will permanently alter/erase files. Continue?\",\
  11254. false,colors.orange)then\
  11255. local path=\"/win/win.log\"\
  11256. local file=fs.open(path,\"w\")\
  11257. if not file then\
  11258. self:msgBox(\"Error\",\"Error cleaning \"..path,colors.red)\
  11259. return\
  11260. end\
  11261. file.close()\
  11262. path=\"/win/tmp\"\
  11263. if fs.exists(path)and fs.isDir(path)then\
  11264. pcall(fs.delete,path)\
  11265. pcall(fs.makeDir,path)\
  11266. end\
  11267. end\
  11268. end\
  11269. function appFrame:editTheme()\
  11270. if self.app_loadedDesktop then\
  11271. local dlg=editTheme:new(self)\
  11272. if dlg:doModal(self.app_loadedDesktop)==ID_OK then\
  11273. end\
  11274. end\
  11275. end\
  11276. function appFrame:setLabel()\
  11277. local name=cmndlg.input(self,\"Computer Name\",\"Enter the computer's name\",\
  11278. os.getComputerLabel()or \"\",\"Name\")\
  11279. if name then\
  11280. if name:len()<1 then\
  11281. os.setComputerLabel()\
  11282. else\
  11283. os.setComputerLabel(name)\
  11284. end\
  11285. end\
  11286. end\
  11287. appFrame:runApp()",
  11288. "local appArgs={...}\
  11289. local appFrame=win.createAppFrame()\
  11290. local APP_TITLE=\"emails\"\
  11291. local ID_OK=1\
  11292. local ID_MENUBTN=101\
  11293. local ID_FOLDER=102\
  11294. local ID_EMAILS=103\
  11295. local ID_ADDRESS=201\
  11296. local ID_PASSWORD=202\
  11297. local ID_NETWORK=203\
  11298. local ID_PORT=204\
  11299. local ID_WIRELESS=205\
  11300. local ID_TIMEOUT=206\
  11301. local ID_NEWPWD=207\
  11302. local ID_CONFIRMPWD=208\
  11303. local IDM_DOWNLOAD=1001\
  11304. local IDM_NEWMSG=1002\
  11305. local IDM_OPEN=1003\
  11306. local IDM_DELMSG=1004\
  11307. local IDM_ACCOUNT=1005\
  11308. local IDM_CHANGEPWD=1006\
  11309. local IDM_QUITAPP=1007\
  11310. local ID_EMAIL_FRAME=32154\
  11311. local accountDlg=win.popupFrame:base()\
  11312. function accountDlg:onCreate(address,password,network,port,wireless,timeout)\
  11313. self:dress(\"Account\")\
  11314. self.acc_address=win.inputWindow:new(self,ID_ADDRESS,1,2,17,\
  11315. address,\"Email Address\")\
  11316. self.acc_password=win.inputWindow:new(self,ID_PASSWORD,1,4,17,\
  11317. password,\"Password\")\
  11318. self.acc_network=win.inputWindow:new(self,ID_NETWORK,1,6,17,\
  11319. network,\"Network\")\
  11320. self.acc_port=win.inputWindow:new(self,ID_PORT,1,8,8,\
  11321. port,\"Port\")\
  11322. self.acc_timeout=win.inputWindow:new(self,ID_TIMEOUT,10,8,8,\
  11323. timeout,\"Timeout\")\
  11324. self.acc_wireless=win.checkWindow:new(self,ID_WIRELESS,1,10,\
  11325. \"Wireless\",wireless~=false)\
  11326. win.buttonWindow:new(self,ID_OK,14,10,\" Ok \")\
  11327. self.acc_wireless:setColors(self:getColors().popupText,\
  11328. self:getColors().popupBack,\
  11329. self:getColors().popupBack,\
  11330. self:getColors().checkText,\
  11331. self:getColors().checkBack,\
  11332. self:getColors().checkFocus)\
  11333. self.acc_password:setMaskChar(\"*\")\
  11334. self.acc_address:setSel(0,-1)\
  11335. self.acc_address:setFocus()\
  11336. self:move(nil,nil,19,12)\
  11337. return true\
  11338. end\
  11339. function accountDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  11340. if event==\"btn_click\" then\
  11341. if p1:getId()==ID_OK then\
  11342. if self.acc_address:getText():len()<3 or\
  11343. not self.acc_address:getText():find(\"@\",1,true)then\
  11344. self.acc_address:setError(true)\
  11345. self.acc_address:setFocus()\
  11346. else\
  11347. self:close(ID_OK)\
  11348. end\
  11349. return true\
  11350. end\
  11351. end\
  11352. return false\
  11353. end\
  11354. function accountDlg:onChildFocus(child,blurred)\
  11355. if child.setSel then\
  11356. child:setSel(0,-1)\
  11357. end\
  11358. return win.popupFrame.onChildFocus(self,child,blurred)\
  11359. end\
  11360. function accountDlg:onChildBlur(child,focused)\
  11361. if child.setSel then\
  11362. local len=child:getText():len()\
  11363. child:setSel(len,len,false)\
  11364. end\
  11365. return win.popupFrame.onChildBlur(self,child,focused)\
  11366. end\
  11367. local passwordDlg=win.popupFrame:base()\
  11368. function passwordDlg:onCreate(password)\
  11369. self:dress(\"Password\")\
  11370. self.pw_password=win.inputWindow:new(self,ID_PASSWORD,1,2,17,\
  11371. password,\"Password\")\
  11372. win.buttonWindow:new(self,ID_OK,14,3,\" Ok \")\
  11373. self.pw_password:setMaskChar(\"*\")\
  11374. self.pw_password:setSel(0,-1)\
  11375. self.pw_password:setFocus()\
  11376. self:move(nil,nil,19,5)\
  11377. return true\
  11378. end\
  11379. function passwordDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  11380. if event==\"btn_click\" then\
  11381. if p1:getId()==ID_OK then\
  11382. self:close(ID_OK)\
  11383. return true\
  11384. end\
  11385. end\
  11386. return false\
  11387. end\
  11388. function passwordDlg:onChildFocus(child,blurred)\
  11389. if child.setSel then\
  11390. child:setSel(0,-1)\
  11391. end\
  11392. return win.popupFrame.onChildFocus(self,child,blurred)\
  11393. end\
  11394. function passwordDlg:onChildBlur(child,focused)\
  11395. if child.setSel then\
  11396. local len=child:getText():len()\
  11397. child:setSel(len,len,false)\
  11398. end\
  11399. return win.popupFrame.onChildBlur(self,child,focused)\
  11400. end\
  11401. local newPasswordDlg=win.popupFrame:base()\
  11402. function newPasswordDlg:onCreate(password)\
  11403. self:dress(\"Password\")\
  11404. self.pw_password=win.inputWindow:new(self,ID_PASSWORD,1,2,17,\
  11405. password,\"Password\")\
  11406. self.pw_password:setMaskChar(\"*\")\
  11407. self.pw_newPassword=win.inputWindow:new(self,ID_NEWPWD,1,4,17,\
  11408. \"\",\"New\")\
  11409. self.pw_newPassword:setMaskChar(\"*\")\
  11410. self.pw_confirmPassword=win.inputWindow:new(self,ID_PASSWORD,1,6,17,\
  11411. \"\",\"Confirm\")\
  11412. self.pw_confirmPassword:setMaskChar(\"*\")\
  11413. if asstring(password):len()>0 then\
  11414. self.pw_newPassword:setFocus()\
  11415. else\
  11416. self.pw_password:setFocus()\
  11417. end\
  11418. win.buttonWindow:new(self,ID_OK,14,7,\" Ok \")\
  11419. self:move(nil,nil,19,9)\
  11420. return true\
  11421. end\
  11422. function newPasswordDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  11423. if event==\"btn_click\" then\
  11424. if p1:getId()==ID_OK then\
  11425. if self.pw_newPassword:getText():len()<1 then\
  11426. self.pw_newPassword:setFocus()\
  11427. self.pw_newPassword:setError(true)\
  11428. return true\
  11429. elseif self.pw_newPassword:getText()~=self.pw_confirmPassword:getText()then\
  11430. self.pw_confirmPassword:setSel(0,-1)\
  11431. self.pw_confirmPassword:setFocus()\
  11432. self.pw_confirmPassword:setError(true)\
  11433. return true\
  11434. end\
  11435. self:close(ID_OK)\
  11436. return true\
  11437. end\
  11438. end\
  11439. return false\
  11440. end\
  11441. function newPasswordDlg:onChildBlur(child,focused)\
  11442. if child.setError then\
  11443. child:setError(false)\
  11444. end\
  11445. if child.setSel then\
  11446. local len=child:getText():len()\
  11447. child:setSel(len,len,false)\
  11448. end\
  11449. return win.popupFrame.onChildBlur(self,child,focused)\
  11450. end\
  11451. function newPasswordDlg:onChildFocus(child,blurred)\
  11452. if child.setSel then\
  11453. child:setSel(0,-1)\
  11454. end\
  11455. return win.popupFrame.onChildFocus(self,child,blurred)\
  11456. end\
  11457. function appFrame:onReceive(msg)\
  11458. if(msg.recipientName or msg.recipientId)then\
  11459. if msg.context==\"email_response\" and type(msg.data)==\"table\" then\
  11460. if type(msg.data.email)==\"table\" then\
  11461. local email=textutils.serialize(msg.data.email)\
  11462. if email then\
  11463. local path;\
  11464. repeat\
  11465. path=self.app_dataPath..\"/inbox/r\"..\
  11466. tostring(math.random(1,65535))..\".email\"\
  11467. until not fs.exists(path)\
  11468. local file=fs.open(path,\"w\")\
  11469. if file then\
  11470. file.write(email)\
  11471. file.close()\
  11472. local domain=self.app_address:sub(self.app_address:find(\"@\",1,true)+1)\
  11473. local account=self.app_address:sub(1,self.app_address:find(\"@\",1,true)-1)\
  11474. self:sendMessage(domain,self.app_network,\"email_delete\",\
  11475. {\
  11476. account=account,\
  11477. password=self.app_password,\
  11478. id=msg.data.id\
  11479. },self.app_connName)\
  11480. self:reloadEmails(\"inbox\")\
  11481. return true\
  11482. end\
  11483. end\
  11484. end\
  11485. end\
  11486. end\
  11487. return false\
  11488. end\
  11489. function appFrame:onSent(msg,success)\
  11490. if not success then\
  11491. if msg.context==\"email_request\" then\
  11492. self:msgBox(\"Error\",\"Error getting emails from server!\",colors.red)\
  11493. elseif msg.context==\"account_password\" then\
  11494. self:msgBox(\"Error\",\"Error changing account password!\",colors.red)\
  11495. end\
  11496. end\
  11497. return true\
  11498. end\
  11499. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  11500. if event==\"btn_click\" then\
  11501. if p1:getId()==ID_MENUBTN then\
  11502. self:onMenu()\
  11503. return true\
  11504. end\
  11505. elseif event==\"menu_cmd\" then\
  11506. return self:onCommand(p1)\
  11507. elseif event==\"list_click\" then\
  11508. if p1:getId()==ID_FOLDER then\
  11509. if p1:getString()then\
  11510. self:loadEmails(p1:getString())\
  11511. end\
  11512. return true\
  11513. end\
  11514. elseif event==\"list_double_click\" then\
  11515. if p1:getId()==ID_EMAILS then\
  11516. return appFrame:onCommand(IDM_OPEN)\
  11517. end\
  11518. elseif event==\"reload_list\" then\
  11519. return self:reloadEmails(asstring(p1))\
  11520. end\
  11521. return false\
  11522. end\
  11523. function appFrame:onTimer(timerId)\
  11524. if timerId==self.app_connTimer then\
  11525. if self.app_connName then\
  11526. self:commClose(self.app_connName)\
  11527. self.app_connName=nil\
  11528. self.app_address=nil\
  11529. self.app_password=nil\
  11530. self.app_network=nil\
  11531. end\
  11532. self.app_connTimer=nil\
  11533. end\
  11534. return false\
  11535. end\
  11536. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  11537. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  11538. return true\
  11539. end\
  11540. if ctrl and not alt and not shift then\
  11541. if key==keys.g then\
  11542. return self:onCommand(IDM_DOWNLOAD)\
  11543. end\
  11544. if key==keys.n then\
  11545. return self:onCommand(IDM_NEWMSG)\
  11546. end\
  11547. if key==keys.o then\
  11548. return self:onCommand(IDM_OPEN)\
  11549. end\
  11550. elseif not ctrl and not alt and not shift then\
  11551. if key==keys.delete then\
  11552. return self:onCommand(IDM_DELMSG)\
  11553. end\
  11554. end\
  11555. return false\
  11556. end\
  11557. function appFrame:onFrameActivate(active)\
  11558. end\
  11559. function appFrame:onQuit()\
  11560. if self.app_connName then\
  11561. self:commClose(self.app_connName)\
  11562. end\
  11563. return false\
  11564. end\
  11565. function appFrame:onMenu()\
  11566. local menu=win.menuWindow:new(self)\
  11567. menu:addString(\"Get Emails Ctrl+G\",IDM_DOWNLOAD)\
  11568. menu:addString(\"New Email  Ctrl+N\",IDM_NEWMSG)\
  11569. if self.app_emails:getData()then\
  11570. menu:addString(\"Open       Ctrl+O\",IDM_OPEN)\
  11571. menu:addString(\"Delete     Del\",IDM_DELMSG)\
  11572. end\
  11573. menu:addString(\"-----------------\")\
  11574. menu:addString(\"Account\",IDM_ACCOUNT)\
  11575. menu:addString(\"Change Password\",IDM_CHANGEPWD)\
  11576. menu:addString(\"-----------------\")\
  11577. menu:addString(\"Quit App\",IDM_QUITAPP)\
  11578. menu:track(0,1)\
  11579. end\
  11580. function appFrame:onCommand(cmdId)\
  11581. if cmdId==IDM_DOWNLOAD then\
  11582. self:onGetEmails()\
  11583. return true\
  11584. end\
  11585. if cmdId==IDM_NEWMSG then\
  11586. self:onNewEmail()\
  11587. return true\
  11588. end\
  11589. if cmdId==IDM_OPEN then\
  11590. self:onOpenEmail()\
  11591. return true\
  11592. end\
  11593. if cmdId==IDM_DELMSG then\
  11594. self:onDeleteEmail()\
  11595. return true\
  11596. end\
  11597. if cmdId==IDM_ACCOUNT then\
  11598. self:onAccount()\
  11599. return true\
  11600. end\
  11601. if cmdId==IDM_CHANGEPWD then\
  11602. self:onChangePassword()\
  11603. return true\
  11604. end\
  11605. if cmdId==IDM_QUITAPP then\
  11606. self:quitApp()\
  11607. return true\
  11608. end\
  11609. return false\
  11610. end\
  11611. function appFrame:onMove()\
  11612. self.app_folder:move(0,1,7,self.height-1)\
  11613. self.app_emails:move(8,1,self.width-8,self.height-1)\
  11614. return false\
  11615. end\
  11616. function appFrame:onCreate()\
  11617. local instance=self:getDesktop():getWndById(ID_EMAIL_FRAME,false)\
  11618. if instance then\
  11619. instance:setActiveTopFrame()\
  11620. return false\
  11621. end\
  11622. self:setId(ID_EMAIL_FRAME)\
  11623. self:dress(APP_TITLE)\
  11624. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  11625. menuBtn:setColors(menuBtn:getColors().frameText,\
  11626. menuBtn:getColors().titleBack,\
  11627. menuBtn:getColors().frameBack)\
  11628. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  11629. local panelWidth=7\
  11630. self.app_folder=win.listWindow:new(self,ID_FOLDER,0,1,7,self.height-1)\
  11631. self.app_emails=win.listWindow:new(self,ID_EMAILS,8,1,\
  11632. self.width-8,self.height-1)\
  11633. self.app_appFolder=self:getAppPath():sub(1,-(fs.getName(self:getAppPath()):len()+1))\
  11634. self.app_dataPath=self.app_appFolder..\"data/email\"\
  11635. self.app_connName=nil\
  11636. self.app_connTimer=nil\
  11637. self.app_address=nil\
  11638. self.app_password=nil\
  11639. self.app_network=nil\
  11640. self:loadFolders()\
  11641. self:setActiveTopFrame()\
  11642. return true\
  11643. end\
  11644. function appFrame:loadFolders()\
  11645. self.app_folder:resetContent()\
  11646. self.app_emails:resetContent()\
  11647. if not fs.exists(self.app_dataPath)then\
  11648. fs.makeDir(self.app_dataPath)\
  11649. end\
  11650. if not fs.exists(self.app_dataPath..\"/inbox\")then\
  11651. fs.makeDir(self.app_dataPath..\"/inbox\")\
  11652. end\
  11653. if not fs.exists(self.app_dataPath..\"/sent\")then\
  11654. fs.makeDir(self.app_dataPath..\"/sent\")\
  11655. end\
  11656. local folders=fs.list(self.app_dataPath)\
  11657. for i=1,#folders,1 do\
  11658. if fs.isDir(self.app_dataPath..\"/\"..folders[i])then\
  11659. self.app_folder:addString(folders[i])\
  11660. end\
  11661. end\
  11662. self.app_folder:sort()\
  11663. end\
  11664. local function email_sorter(email1,email2)\
  11665. return(email1.time<email2.time)\
  11666. end\
  11667. function appFrame:loadEmails(folder)\
  11668. local emails={}\
  11669. local list=fs.list(self.app_dataPath..\"/\"..folder)\
  11670. self.app_emails:resetContent()\
  11671. for i=1,#list,1 do\
  11672. local file=fs.open(self.app_dataPath..\"/\"..folder..\"/\"..list[i],\"r\")\
  11673. if file then\
  11674. local email=textutils.unserialize(file.readAll())\
  11675. if email then\
  11676. emails[#emails+1]={\
  11677. recipient=email.recipient,\
  11678. sender=email.sender,\
  11679. subject=email.subject,\
  11680. time=email.time,\
  11681. path=self.app_dataPath..\"/\"..folder..\"/\"..list[i]\
  11682. }\
  11683. end\
  11684. file.close()\
  11685. end\
  11686. end\
  11687. table.sort(emails,email_sorter)\
  11688. for i=1,#emails,1 do\
  11689. local who,subject=\
  11690. asstring(iif(folder==\"sent\",emails[i].recipient,emails[i].sender)),\
  11691. asstring(emails[i].subject)\
  11692. local whoFull=who\
  11693. if who:len()>15 then\
  11694. who=who:sub(1,15)\
  11695. elseif who:len()<15 then\
  11696. who=who..string.rep(\" \",15-who:len())\
  11697. end\
  11698. if subject:len()>15 then\
  11699. subject=subject:sub(1,15)\
  11700. elseif subject:len()<15 then\
  11701. subject=subject..string.rep(\" \",15-subject:len())\
  11702. end\
  11703. local day,part=math.modf(emails[i].time)\
  11704. local hour,minute=math.modf(part*24)\
  11705. minute=math.floor(minute*60)\
  11706. self.app_emails:addString(\
  11707. string.format(\"%s %s %5d,%02d:%02d\",who,subject,day,hour,minute),\
  11708. {path=emails[i].path,subject=string.trim(subject),who=whoFull})\
  11709. end\
  11710. local x,y=self.app_emails:getScrollSize()\
  11711. self.app_emails:setScrollSize(iif(self.app_emails:count()>0,43,0),y)\
  11712. end\
  11713. function appFrame:reloadEmails(folder)\
  11714. if folder and self.app_folder:getString()==folder then\
  11715. self:loadEmails(folder)\
  11716. end\
  11717. end\
  11718. function appFrame:onOpenEmail()\
  11719. if self.app_emails:getData()then\
  11720. local path=self.app_appFolder..\"emread\"\
  11721. self:getDesktop():runApp(path,self.app_emails:getData().path)\
  11722. end\
  11723. end\
  11724. function appFrame:onDeleteEmail()\
  11725. if self.app_emails:getData()then\
  11726. if cmndlg.confirm(self,\"Delete\",\"Delete \"..self.app_emails:getData().subject..\"?\",false,colors.orange)then\
  11727. fs.delete(self.app_emails:getData().path)\
  11728. self:reloadEmails(self.app_folder:getString())\
  11729. end\
  11730. end\
  11731. end\
  11732. function appFrame:onNewEmail()\
  11733. if self.app_emails:getData()then\
  11734. self:getDesktop():runApp(self.app_appFolder..\"emwrite\",self.app_emails:getData().who)\
  11735. else\
  11736. self:getDesktop():runApp(self.app_appFolder..\"emwrite\")\
  11737. end\
  11738. end\
  11739. function appFrame:onAccount()\
  11740. local iniPath=self.app_appFolder..\"email.ini\"\
  11741. local dlg=accountDlg:new(self)\
  11742. local address=\"\"\
  11743. local password=\"\"\
  11744. local network=\"wide_area_network\"\
  11745. local port=80\
  11746. local timeout=5\
  11747. local wireless=true\
  11748. local ini=fs.loadIniFile(iniPath)\
  11749. if ini then\
  11750. address=asstring((ini:find(\"address\")))\
  11751. password=asstring((ini:find(\"password\")))\
  11752. network=asstring(ini:find(\"network\"),\"wide_area_network\")\
  11753. port=asnumber(ini:find(\"port\"),80)\
  11754. timeout=asnumber(ini:find(\"timeout\"),5)\
  11755. wireless=asstring(ini:find(\"wireless\"),\"true\")~=\"false\"\
  11756. end\
  11757. if dlg:doModal(address,password,network,port,wireless,timeout)==ID_OK then\
  11758. address=dlg.acc_address:getText()\
  11759. password=dlg.acc_password:getText()\
  11760. network=dlg.acc_network:getText()\
  11761. if network:len()<1 then\
  11762. network=\"wide_area_network\"\
  11763. end\
  11764. port=asnumber(dlg.acc_port:getText(),80)\
  11765. timeout=asnumber(dlg.acc_timeout:getText(),5)\
  11766. wireless=iif(dlg.acc_wireless:getChecked(),\"true\",\"false\")\
  11767. local file=fs.open(iniPath,\"w\")\
  11768. if file then\
  11769. file.write(string.format(\
  11770. \"address=%s\\npassword=%s\\nnetwork=%s\\nport=%d\\ntimeout=%d\\nwireless=%s\",\
  11771. address,password,network,port,timeout,wireless))\
  11772. file.close()\
  11773. else\
  11774. self:msgBox(\"Error\",\"Error saving account settings!\",colors.red)\
  11775. end\
  11776. end\
  11777. end\
  11778. function appFrame:onGetEmails()\
  11779. local ini=fs.loadIniFile(self.app_appFolder..\"email.ini\")\
  11780. if ini then\
  11781. self.app_address=asstring(ini:find(\"address\"))\
  11782. self.app_password=asstring(ini:find(\"password\"))\
  11783. self.app_network=asstring(ini:find(\"network\"),\"wide_area_network\")\
  11784. local port=asnumber(ini:find(\"port\"),80)\
  11785. local timeout=asnumber(ini:find(\"timeout\"),5)\
  11786. local wireless=asstring(ini:find(\"wireless\"),\"true\")~=\"false\"\
  11787. if self.app_address:len()>2 and self.app_address:find(\"@\",1,true)then\
  11788. if self.app_password:len()<1 then\
  11789. local dlg=passwordDlg:new(self)\
  11790. if dlg:doModal()~=ID_OK then\
  11791. return\
  11792. end\
  11793. self.app_password=dlg.pw_password:getText()\
  11794. end\
  11795. if not self.app_connName then\
  11796. local con=self:commOpen(nil,wireless,port,timeout,false)\
  11797. if not con then\
  11798. self:msgBox(\"Connection\",\"Could not connect to modem!\",colors.red)\
  11799. return\
  11800. end\
  11801. self.app_connName=con:getName()\
  11802. self:wantMessages(\"email_client\",self.app_connName)\
  11803. self:wantMessages(self.app_network,self.app_connName)\
  11804. end\
  11805. local domain=self.app_address:sub(self.app_address:find(\"@\",1,true)+1)\
  11806. local account=self.app_address:sub(1,self.app_address:find(\"@\",1,true)-1)\
  11807. self.app_connTimer=self:startTimer(30)\
  11808. self:sendMessage(domain,self.app_network,\"email_request\",\
  11809. {\
  11810. application=\"email_client\",\
  11811. account=account,\
  11812. password=self.app_password\
  11813. },self.app_connName)\
  11814. else\
  11815. self.app_address=nil\
  11816. self.app_password=nil\
  11817. self.app_network=nil\
  11818. self:msgBox(\"Account\",\"Invalid account settings!\",colors.red)\
  11819. end\
  11820. else\
  11821. self:msgBox(\"Account\",\"No account set up!\",colors.red)\
  11822. end\
  11823. end\
  11824. function appFrame:onChangePassword()\
  11825. local ini=fs.loadIniFile(self.app_appFolder..\"email.ini\")\
  11826. if ini then\
  11827. self.app_address=asstring(ini:find(\"address\"))\
  11828. self.app_password=asstring(ini:find(\"password\"))\
  11829. self.app_network=asstring(ini:find(\"network\"),\"wide_area_network\")\
  11830. local port=asnumber(ini:find(\"port\"),80)\
  11831. local timeout=asnumber(ini:find(\"timeout\"),5)\
  11832. local wireless=asstring(ini:find(\"wireless\"),\"true\")~=\"false\"\
  11833. if self.app_address:len()>2 and self.app_address:find(\"@\",1,true)then\
  11834. local dlg=newPasswordDlg:new(self)\
  11835. if dlg:doModal(self.app_password)~=ID_OK then\
  11836. return\
  11837. end\
  11838. self.app_password=dlg.pw_password:getText()\
  11839. if not self.app_connName then\
  11840. local con=self:commOpen(nil,wireless,port,timeout,false)\
  11841. if not con then\
  11842. self:msgBox(\"Connection\",\"Could not connect to modem!\",colors.red)\
  11843. return\
  11844. end\
  11845. self.app_connName=con:getName()\
  11846. self:wantMessages(\"email_client\",self.app_connName)\
  11847. self:wantMessages(self.app_network,self.app_connName)\
  11848. end\
  11849. local domain=self.app_address:sub(self.app_address:find(\"@\",1,true)+1)\
  11850. local account=self.app_address:sub(1,self.app_address:find(\"@\",1,true)-1)\
  11851. self.app_connTimer=self:startTimer(30)\
  11852. self:sendMessage(domain,self.app_network,\"account_password\",\
  11853. {\
  11854. account=account,\
  11855. password=self.app_password,\
  11856. newPassword=dlg.pw_newPassword:getText()\
  11857. },self.app_connName)\
  11858. else\
  11859. self.app_address=nil\
  11860. self.app_password=nil\
  11861. self.app_network=nil\
  11862. self:msgBox(\"Account\",\"Invalid account settings!\",colors.red)\
  11863. end\
  11864. else\
  11865. self:msgBox(\"Account\",\"No account set up!\",colors.red)\
  11866. end\
  11867. end\
  11868. appFrame:runApp()",
  11869. ";address=account@domain\
  11870. ;password=password\
  11871. network=wide_area_network\
  11872. port=80\
  11873. timeout=5\
  11874. wireless=true\
  11875. ",
  11876. "local appArgs={...}\
  11877. local appFrame=win.createAppFrame()\
  11878. local APP_TITLE=\"email\"\
  11879. local ID_MENUBTN=101\
  11880. local IDM_OPEN=1001\
  11881. local IDM_PRINT=1002\
  11882. local IDM_COPY=1003\
  11883. local IDM_QUITAPP=1004\
  11884. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  11885. if event==\"btn_click\" then\
  11886. if p1:getId()==ID_MENUBTN then\
  11887. self:onMenu()\
  11888. return true\
  11889. end\
  11890. elseif event==\"menu_cmd\" then\
  11891. return self:onCommand(p1)\
  11892. end\
  11893. return false\
  11894. end\
  11895. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  11896. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  11897. return true\
  11898. end\
  11899. if ctrl and not alt and not shift then\
  11900. if key==keys.o then\
  11901. return self:onCommand(IDM_OPEN)\
  11902. end\
  11903. if key==keys.p then\
  11904. return self:onCommand(IDM_PRINT)\
  11905. end\
  11906. if key==keys.c then\
  11907. return self:onCommand(IDM_COPY)\
  11908. end\
  11909. end\
  11910. return false\
  11911. end\
  11912. function appFrame:onPrintPage(gdi,page,data)\
  11913. local width,height=gdi:getPageSize()\
  11914. if not data.data.lines then\
  11915. data.data.lines=string.wrap(data.data.raw,width)\
  11916. end\
  11917. local topLine=((page-1)*height)+1\
  11918. local lastLine=iif((topLine+height)>#data.data.lines,\
  11919. #data.data.lines,topLine+height)\
  11920. for line=topLine,lastLine,1 do\
  11921. gdi:write(data.data.lines[line],0,line-topLine)\
  11922. end\
  11923. return(lastLine<#data.data.lines)\
  11924. end\
  11925. function appFrame:onPrintData()\
  11926. local str=self.app_to:getText()..\"\\n\"..\
  11927. self.app_from:getText()..\"\\n\"..\
  11928. self.app_sent:getText()..\"\\n\"..\
  11929. self.app_subject:getText()..\"\\n\\n\"..\
  11930. self.app_message:getText()\
  11931. local width,height=string.wrapSize(string.wrap(str,25))\
  11932. local data={raw=str}\
  11933. local pages=math.ceil(height/21)\
  11934. return win.applicationFrame.onPrintData(self,self:getText(),data,pages)\
  11935. end\
  11936. function appFrame:onMenu()\
  11937. local menu=win.menuWindow:new(self)\
  11938. menu:addString(\"Open  Ctrl+O\",IDM_OPEN)\
  11939. menu:addString(\"Print Ctrl+P\",IDM_PRINT)\
  11940. menu:addString(\"Copy  Ctrl+C\",IDM_COPY)\
  11941. menu:addString(\"------------\")\
  11942. menu:addString(\"Quit App\",IDM_QUITAPP)\
  11943. menu:track(0,1)\
  11944. end\
  11945. function appFrame:onCommand(cmdId)\
  11946. if cmdId==IDM_OPEN then\
  11947. self:onOpenFile()\
  11948. return true\
  11949. end\
  11950. if cmdId==IDM_PRINT then\
  11951. self:printDoc()\
  11952. return true\
  11953. end\
  11954. if cmdId==IDM_COPY then\
  11955. self:onCopy()\
  11956. return true\
  11957. end\
  11958. if cmdId==IDM_QUITAPP then\
  11959. self:quitApp()\
  11960. return true\
  11961. end\
  11962. return false\
  11963. end\
  11964. function appFrame:onMove()\
  11965. self.app_to:move(0,1,self.width)\
  11966. self.app_from:move(0,2,self.width)\
  11967. self.app_sent:move(0,3,self.width)\
  11968. self.app_subject:move(0,4,self.width)\
  11969. self.app_message:move(0,5,self.width,self.height-5)\
  11970. return false\
  11971. end\
  11972. function appFrame:onCreate()\
  11973. self:dress(APP_TITLE)\
  11974. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  11975. menuBtn:setColors(menuBtn:getColors().frameText,\
  11976. menuBtn:getColors().titleBack,\
  11977. menuBtn:getColors().frameBack)\
  11978. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  11979. self.app_to=win.labelWindow:new(self,0,0,1,\"\")\
  11980. self.app_from=win.labelWindow:new(self,0,0,2,\"\")\
  11981. self.app_sent=win.labelWindow:new(self,0,0,3,\"\")\
  11982. self.app_subject=win.labelWindow:new(self,0,0,4,\"\")\
  11983. self.app_message=win.textWindow:new(self,0,0,5,self.width,self.height-5,\"\")\
  11984. self.app_message:setColor(self:getColors().wndText)\
  11985. self.app_message:setBgColor(self:getColors().wndBack)\
  11986. self.app_curPath=nil\
  11987. if #appArgs>0 then\
  11988. self:openFile(appArgs[1])\
  11989. end\
  11990. self:setActiveTopFrame()\
  11991. return true\
  11992. end\
  11993. local function emailDateTime(dateTime)\
  11994. local str=\"\"\
  11995. if dateTime then\
  11996. local day,part=math.modf(dateTime)\
  11997. local hour,minute=math.modf(part*24)\
  11998. minute=math.floor(minute*60)\
  11999. str=string.format(\"%d, %02d:%02d\",day,hour,minute)\
  12000. end\
  12001. return str\
  12002. end\
  12003. function appFrame:openFile(path)\
  12004. local result=false\
  12005. local file=fs.open(path,\"r\")\
  12006. if file then\
  12007. local email=textutils.unserialize(file.readAll())\
  12008. if email then\
  12009. self.app_to:setText(\"To     : \"..asstring(email.recipient))\
  12010. self.app_from:setText(\"From   : \"..asstring(email.sender))\
  12011. self.app_sent:setText(\"Sent   : \"..emailDateTime(email.time))\
  12012. self.app_subject:setText(\"Subject: \"..asstring(email.subject))\
  12013. self.app_message:setText(asstring(email.message))\
  12014. if email.subject then\
  12015. self:setTitle(asstring(email.subject)..\":\"..APP_TITLE)\
  12016. else\
  12017. self:setTitle(\"no subject:\"..APP_TITLE)\
  12018. end\
  12019. result=true\
  12020. end\
  12021. file.close()\
  12022. end\
  12023. if not result then\
  12024. self:msgBox(\"Error\",\"Could not open email\",colors.red)\
  12025. end\
  12026. end\
  12027. function appFrame:onOpenFile()\
  12028. local path=cmndlg.openFile(self,self.app_curPath,true)\
  12029. if path then\
  12030. self:openFile(path)\
  12031. end\
  12032. end\
  12033. function appFrame:onCopy()\
  12034. self:setClipboard(string.format(\
  12035. \"%s\\r%s\\r%s\\r%s\\r------------------------\\r%s\",\
  12036. self.app_to:getText(),\
  12037. self.app_from:getText(),\
  12038. self.app_sent:getText(),\
  12039. self.app_subject:getText(),\
  12040. self.app_message:getText()),\
  12041. CB_TEXT)\
  12042. end\
  12043. appFrame:runApp()\
  12044. ",
  12045. "local appArgs={...}\
  12046. local appFrame=win.createAppFrame()\
  12047. local APP_TITLE=\"email\"\
  12048. local ID_MENUBTN=101\
  12049. local ID_TO=102\
  12050. local ID_SUBJECT=103\
  12051. local ID_MESSAGE=104\
  12052. local IDM_SEND=1001\
  12053. local IDM_QUITAPP=1002\
  12054. local ID_EMAIL_FRAME=32154\
  12055. function appFrame:onSent(msg,success)\
  12056. if msg.context==\"email_send\" then\
  12057. self:commClose(self.app_connName)\
  12058. self.app_connName=nil\
  12059. if success then\
  12060. local path;\
  12061. repeat\
  12062. path=self.app_dataPath..\"/sent/s\"..\
  12063. tostring(math.random(1,65535))..\".email\"\
  12064. until not fs.exists(path)\
  12065. local file=fs.open(path,\"w\")\
  12066. if file then\
  12067. file.write(textutils.serialize(msg.data.email))\
  12068. file.close()\
  12069. else\
  12070. self:msgBox(\"Sent\",\"Email was sent but could not save a copy.\",colors.red)\
  12071. end\
  12072. local instance=self:getDesktop():getWndById(ID_EMAIL_FRAME)\
  12073. if instance then\
  12074. instance:sendEvent(\"reload_list\",\"sent\")\
  12075. end\
  12076. self.app_msgSent=true\
  12077. self:quitApp()\
  12078. else\
  12079. self:msgBox(\"Error\",\"Could not send email!\",colors.red)\
  12080. end\
  12081. end\
  12082. return true\
  12083. end\
  12084. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  12085. if event==\"btn_click\" then\
  12086. if p1:getId()==ID_MENUBTN then\
  12087. self:onMenu()\
  12088. return true\
  12089. end\
  12090. elseif event==\"menu_cmd\" then\
  12091. return self:onCommand(p1)\
  12092. elseif event==\"input_change\" then\
  12093. if p1:getId()==ID_SUBJECT then\
  12094. self:setTitle(iif(p1:getText():len()>0,p1:getText()..\":\",\"\")..APP_TITLE)\
  12095. return true\
  12096. end\
  12097. end\
  12098. return false\
  12099. end\
  12100. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  12101. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  12102. return true\
  12103. end\
  12104. if ctrl and not alt and not shift then\
  12105. if key==keys.s then\
  12106. return self:onCommand(IDM_SEND)\
  12107. end\
  12108. end\
  12109. return false\
  12110. end\
  12111. function appFrame:onQuit()\
  12112. if self.app_connName then\
  12113. self:msgBox(\"Sending\",\"Send in progress.\",colors.orange)\
  12114. return true\
  12115. end\
  12116. if not self.app_msgSent then\
  12117. if not cmndlg.confirm(self,\"Unsent\",\"Message not sent. Quit anyway?\")then\
  12118. return true\
  12119. end\
  12120. end\
  12121. return false\
  12122. end\
  12123. function appFrame:onMenu()\
  12124. local menu=win.menuWindow:new(self)\
  12125. menu:addString(\"Send Ctrl+S\",IDM_SEND)\
  12126. menu:addString(\"-----------\")\
  12127. menu:addString(\"Quit App\",IDM_QUITAPP)\
  12128. menu:track(0,1)\
  12129. end\
  12130. function appFrame:onCommand(cmdId)\
  12131. if cmdId==IDM_SEND then\
  12132. self:onSend()\
  12133. return true\
  12134. end\
  12135. if cmdId==IDM_QUITAPP then\
  12136. self:quitApp()\
  12137. return true\
  12138. end\
  12139. return false\
  12140. end\
  12141. function appFrame:onMove()\
  12142. self.app_to:move(1,1,self.width-2)\
  12143. self.app_subject:move(1,3,self.width-2)\
  12144. self.app_message:move(1,5,self.width-2,self.height-6)\
  12145. return false\
  12146. end\
  12147. function appFrame:onCreate()\
  12148. self:dress(APP_TITLE)\
  12149. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  12150. menuBtn:setColors(menuBtn:getColors().frameText,\
  12151. menuBtn:getColors().titleBack,\
  12152. menuBtn:getColors().frameBack)\
  12153. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  12154. self.app_to=win.inputWindow:new(self,ID_TO,1,1,self.width-2,\
  12155. nil,\"Recipient\")\
  12156. self.app_subject=win.inputWindow:new(self,ID_SUBJECT,1,3,\
  12157. self.width-2,nil,\"Subject\")\
  12158. self.app_message=win.editWindow:new(self,ID_MESSAGE,1,5,\
  12159. self.width-2,self.height-6,nil,\"Message\")\
  12160. self.app_appFolder=self:getAppPath():sub(1,-(fs.getName(self:getAppPath()):len()+1))\
  12161. self.app_dataPath=self.app_appFolder..\"data/email\"\
  12162. self.app_connName=nil\
  12163. self.app_msgSent=false\
  12164. if #appArgs>0 then\
  12165. self.app_to:setText(appArgs[1])\
  12166. self.app_subject:setFocus()\
  12167. else\
  12168. self.app_to:setFocus()\
  12169. end\
  12170. self:setActiveTopFrame()\
  12171. return true\
  12172. end\
  12173. function appFrame:onSend()\
  12174. local recipient=self.app_to:getText()\
  12175. if recipient:len()>2 and recipient:find(\"@\",1,true)then\
  12176. local ini=fs.loadIniFile(self.app_appFolder..\"email.ini\")\
  12177. if ini then\
  12178. local address=asstring((ini:find(\"address\")))\
  12179. local network=asstring(ini:find(\"network\"),\"wide_area_network\")\
  12180. local port=asnumber(ini:find(\"port\"),80)\
  12181. local timeout=asnumber(ini:find(\"timeout\"),5)\
  12182. local wireless=asstring(ini:find(\"wireless\"),\"true\")~=\"false\"\
  12183. if address:len()>2 and address:find(\"@\",1,true)then\
  12184. local con=self:commOpen(nil,wireless,port,timeout,false)\
  12185. if not con then\
  12186. self:msgBox(\"Connection\",\"Could not connect to modem!\",colors.red)\
  12187. return\
  12188. end\
  12189. self.app_connName=con:getName()\
  12190. self:wantMessages(network,self.app_connName)\
  12191. local domain=recipient:sub(recipient:find(\"@\",1,true)+1)\
  12192. local account=recipient:sub(1,recipient:find(\"@\",1,true)-1)\
  12193. self:sendMessage(domain,network,\"email_send\",\
  12194. {\
  12195. account=account,\
  12196. email=\
  12197. {\
  12198. recipient=recipient,\
  12199. sender=address,\
  12200. time=((os.time()/24)+os.day()),\
  12201. subject=self.app_subject:getText(),\
  12202. message=self.app_message:getText()\
  12203. }\
  12204. },self.app_connName)\
  12205. else\
  12206. self:msgBox(\"Account\",\"Invalid account settings!\",colors.red)\
  12207. end\
  12208. else\
  12209. self:msgBox(\"Account\",\"No account set up!\",colors.red)\
  12210. end\
  12211. else\
  12212. self.app_to:setError(true)\
  12213. self.app_to:setFocus()\
  12214. end\
  12215. end\
  12216. appFrame:runApp()\
  12217. ",
  12218. "local appArgs={...}\
  12219. local appFrame=win.createAppFrame()\
  12220. local APP_TITLE=\"admin\"\
  12221. local ID_OK=1\
  12222. local ID_MENUBTN=101\
  12223. local ID_DOMAIN=102\
  12224. local ID_NETWORK=103\
  12225. local ID_PORT=104\
  12226. local ID_TIMEOUT=105\
  12227. local ID_WIRELESS=106\
  12228. local ID_PASSWORD=107\
  12229. local ID_PROGRESS=108\
  12230. local ID_ACCOUNT=109\
  12231. local ID_SRCPATH=110\
  12232. local ID_SRCBROWSE=111\
  12233. local ID_DESTPATH=112\
  12234. local ID_LISTING=113\
  12235. local IDM_CONNECTION=1001\
  12236. local IDM_UP=1002\
  12237. local IDM_OPEN=1003\
  12238. local IDM_NEWDIR=1004\
  12239. local IDM_UPLOAD=1005\
  12240. local IDM_DOWNLOAD=1006\
  12241. local IDM_DELETE=1007\
  12242. local IDM_NEWACC=1008\
  12243. local IDM_RESETACC=1009\
  12244. local IDM_DELACC=1010\
  12245. local IDM_QUITAPP=1011\
  12246. local TYPE_UP=0\
  12247. local TYPE_DIR=1\
  12248. local TYPE_FILE=2\
  12249. local function pathFolder(path)\
  12250. path=asstring(path)\
  12251. if path:len()>1 then\
  12252. if path:sub(-1,-1)==\"/\" then\
  12253. path=path:sub(1,-2)\
  12254. end\
  12255. local lastName=fs.getName(path)\
  12256. path=path:sub(1,-(lastName:len()+1))\
  12257. else\
  12258. path=\"/\"\
  12259. end\
  12260. return path\
  12261. end\
  12262. local connectDlg=win.popupFrame:base()\
  12263. function connectDlg:onCreate(domain,password,network,port,timeout,wireless)\
  12264. self:dress(\"Connection\")\
  12265. self.con_domain=\
  12266. win.inputWindow:new(self,ID_DOMAIN,1,2,17,\
  12267. asstring(domain),\"Domain\")\
  12268. self.con_password=\
  12269. win.inputWindow:new(self,ID_PASSWORD,1,4,17,\
  12270. asstring(password),\"Password\")\
  12271. self.con_password:setMaskChar(\"*\")\
  12272. self.con_network=\
  12273. win.inputWindow:new(self,ID_NETWORK,1,6,17,\
  12274. asstring(network,\"wide_area_network\"),\"Network\")\
  12275. self.con_port=\
  12276. win.inputWindow:new(self,ID_PORT,1,8,7,\
  12277. asstring(port,\"80\"),\"Port\")\
  12278. self.con_timeout=\
  12279. win.inputWindow:new(self,ID_TIMEOUT,11,8,7,\
  12280. asstring(timeout,\"5\"),\"Timeout\")\
  12281. self.con_wireless=\
  12282. win.checkWindow:new(self,ID_WIRELESS,1,10,\"Wireless\",\
  12283. wireless~=false)\
  12284. self.con_wireless:setColors(self:getColors().popupText,\
  12285. self:getColors().popupBack,\
  12286. self:getColors().popupBack,\
  12287. self:getColors().checkText,\
  12288. self:getColors().checkBack,\
  12289. self:getColors().checkFocus)\
  12290. win.buttonWindow:new(self,ID_OK,14,10,\" Ok \")\
  12291. self.con_domain:setFocus()\
  12292. self:move(nil,nil,19,12)\
  12293. return true\
  12294. end\
  12295. function connectDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  12296. if event==\"btn_click\" then\
  12297. if p1:getId()==ID_OK then\
  12298. if self.con_domain:getText():len()<1 then\
  12299. self.con_domain:setFocus()\
  12300. self.con_domain:setError(true)\
  12301. elseif self.con_password:getText():len()<1 then\
  12302. self.con_password:setFocus()\
  12303. self.con_password:setError(true)\
  12304. else\
  12305. self:close(ID_OK)\
  12306. end\
  12307. return true\
  12308. end\
  12309. end\
  12310. return false\
  12311. end\
  12312. local accountDlg=win.popupFrame:base()\
  12313. function accountDlg:onCreate(title)\
  12314. self:dress(title)\
  12315. self.acc_account=win.inputWindow:new(self,ID_ACCOUNT,1,2,17,\
  12316. nil,\"Account\")\
  12317. self.acc_password=win.inputWindow:new(self,ID_PASSWORD,1,4,17,\
  12318. nil,\"Password\")\
  12319. win.buttonWindow:new(self,ID_OK,14,6,\" Ok \")\
  12320. self.acc_password:setMaskChar(\"*\")\
  12321. self.acc_account:setFocus()\
  12322. self:move(nil,nil,19,8)\
  12323. return true\
  12324. end\
  12325. function accountDlg:onEvent(event,p1,p2,p3,p4,p5,...)\
  12326. if event==\"btn_click\" then\
  12327. if p1:getId()==ID_OK then\
  12328. if self.acc_account:getText():len()<1 then\
  12329. self.acc_account:setFocus()\
  12330. elseif self.acc_password:getText():len()<1 then\
  12331. self.acc_password:setFocus()\
  12332. else\
  12333. self:close(ID_OK)\
  12334. end\
  12335. return true\
  12336. end\
  12337. end\
  12338. return false\
  12339. end\
  12340. function appFrame:onReceive(msg)\
  12341. if(msg.recipientId or msg.recipientName)and type(msg.data)==\"table\" then\
  12342. if msg.context==\"listing_response\" and type(msg.data.files)==\"table\" and\
  12343. type(msg.data.folders)==\"table\" and msg.data.path then\
  12344. self.app_list:setCurSel(0)\
  12345. self.app_list:resetContent()\
  12346. self.app_curPath=msg.data.path\
  12347. if msg.data.path~=\"/\" then\
  12348. self.app_list:addString(\"..\",{name=\"\",type=TYPE_UP})\
  12349. end\
  12350. table.sort(msg.data.folders)\
  12351. table.sort(msg.data.files)\
  12352. for i=1,#msg.data.folders,1 do\
  12353. self.app_list:addString(\"/\"..msg.data.folders[i],\
  12354. {name=msg.data.folders[i],type=TYPE_DIR})\
  12355. end\
  12356. for i=1,#msg.data.files,1 do\
  12357. self.app_list:addString(msg.data.files[i],\
  12358. {name=msg.data.files[i],type=TYPE_FILE})\
  12359. end\
  12360. self:updateTitle()\
  12361. self:startTimer(0.1)\
  12362. return true\
  12363. elseif msg.context==\"ftp_response\" and\
  12364. msg.data.path and msg.data.content then\
  12365. local path=cmndlg.saveFile(self,fs.getName(msg.data.path))\
  12366. if path then\
  12367. self.app_lastFile=path\
  12368. local hFile=fs.open(path,\"w\")\
  12369. if hFile then\
  12370. hFile.write(msg.data.content)\
  12371. hFile.close()\
  12372. else\
  12373. self:msgBox(\"File Error\",\"Could not write file \"..path,colors.red)\
  12374. end\
  12375. end\
  12376. self:startTimer(0.1)\
  12377. return true\
  12378. end\
  12379. end\
  12380. return false\
  12381. end\
  12382. function appFrame:onSent(msg,success)\
  12383. if success then\
  12384. if msg.context==\"file_delete\" or msg.context==\"file_upload\" or\
  12385. msg.context==\"directory_create\" then\
  12386. self:closeConnection()\
  12387. self:onFileList()\
  12388. elseif msg.context==\"create_account\" then\
  12389. self:closeConnection()\
  12390. self:msgBox(\"Success\",\"Account created.\")\
  12391. elseif msg.context==\"delete_account\" then\
  12392. self:closeConnection()\
  12393. self:msgBox(\"Success\",\"Account deleted.\")\
  12394. elseif msg.context==\"reset_password\" then\
  12395. self:closeConnection()\
  12396. self:msgBox(\"Success\",\"Account reset.\")\
  12397. end\
  12398. else\
  12399. self:closeConnection()\
  12400. self:msgBox(\"Fail\",\"Action failed!\",colors.red)\
  12401. end\
  12402. return true\
  12403. end\
  12404. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  12405. if event==\"btn_click\" then\
  12406. if p1:getId()==ID_MENUBTN then\
  12407. self:onMenu()\
  12408. return true\
  12409. end\
  12410. elseif event==\"menu_cmd\" then\
  12411. return self:onCommand(p1)\
  12412. elseif event==\"list_double_click\" then\
  12413. if p1:getId()==ID_LISTING then\
  12414. self:doDefaultAction()\
  12415. return true\
  12416. end\
  12417. end\
  12418. return false\
  12419. end\
  12420. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  12421. if win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)then\
  12422. return true\
  12423. end\
  12424. if ctrl and not alt and not shift then\
  12425. if key==keys.c then\
  12426. return self:onCommand(IDM_CONNECTION)\
  12427. end\
  12428. if key==keys.up then\
  12429. return self:onCommand(IDM_UP)\
  12430. end\
  12431. if key==keys.o then\
  12432. return self:onCommand(IDM_OPEN)\
  12433. end\
  12434. if key==keys.n then\
  12435. return self:onCommand(IDM_NEWDIR)\
  12436. end\
  12437. if key==keys.u then\
  12438. return self:onCommand(IDM_UPLOAD)\
  12439. end\
  12440. if key==keys.d then\
  12441. return self:onCommand(IDM_DOWNLOAD)\
  12442. end\
  12443. if key==keys.a then\
  12444. return self:onCommand(IDM_NEWACC)\
  12445. end\
  12446. if key==keys.r then\
  12447. return self:onCommand(IDM_RESETACC)\
  12448. end\
  12449. if key==keys.k then\
  12450. return self:onCommand(IDM_DELACC)\
  12451. end\
  12452. elseif not ctrl and not alt and not shift then\
  12453. if key==keys.delete then\
  12454. return self:onCommand(IDM_DELETE)\
  12455. end\
  12456. end\
  12457. return false\
  12458. end\
  12459. function appFrame:onFrameActivate(active)\
  12460. end\
  12461. function appFrame:onTimer(id)\
  12462. self:closeConnection()\
  12463. return false\
  12464. end\
  12465. function appFrame:onQuit()\
  12466. self:closeConnection()\
  12467. return false\
  12468. end\
  12469. function appFrame:onMenu(x,y)\
  12470. local menu=win.menuWindow:new(self)\
  12471. x=x or 0\
  12472. y=y or 1\
  12473. menu:addString(\"Connection  Ctrl+C\",IDM_CONNECTION)\
  12474. if self:canConnect()then\
  12475. menu:addString(\"------------------\")\
  12476. if self:canUp()then\
  12477. menu:addString(\"Up          Ctrl+^\",IDM_UP)\
  12478. end\
  12479. if self:canOpen()then\
  12480. menu:addString(\"Open        Ctrl+O\",IDM_OPEN)\
  12481. end\
  12482. menu:addString(\"New Folder  Ctrl+N\",IDM_NEWDIR)\
  12483. menu:addString(\"Upload      Ctrl+U\",IDM_UPLOAD)\
  12484. if self:canDownloadFile()then\
  12485. menu:addString(\"Download    Ctrl+D\",IDM_DOWNLOAD)\
  12486. end\
  12487. if self:canDeleteItem()then\
  12488. menu:addString(\"Delete         Del\",IDM_DELETE)\
  12489. end\
  12490. menu:addString(\"------------------\")\
  12491. menu:addString(\"New Account Ctrl+A\",IDM_NEWACC)\
  12492. menu:addString(\"Reset Acc   Ctrl+R\",IDM_RESETACC)\
  12493. menu:addString(\"Delete Acc  Ctrl+K\",IDM_DELACC)\
  12494. end\
  12495. menu:addString(\"------------------\")\
  12496. menu:addString(\"Quit App\",IDM_QUITAPP)\
  12497. menu:track(x,y)\
  12498. end\
  12499. function appFrame:onCommand(cmdId)\
  12500. if cmdId==IDM_CONNECTION then\
  12501. self:onConnection()\
  12502. return true\
  12503. end\
  12504. if cmdId==IDM_UP then\
  12505. self:onUp()\
  12506. return true\
  12507. end\
  12508. if cmdId==IDM_OPEN then\
  12509. self:onOpen()\
  12510. return true\
  12511. end\
  12512. if cmdId==IDM_NEWDIR then\
  12513. self:onNewFolder()\
  12514. return true\
  12515. end\
  12516. if cmdId==IDM_UPLOAD then\
  12517. self:onUploadFile()\
  12518. return true\
  12519. end\
  12520. if cmdId==IDM_DOWNLOAD then\
  12521. self:onDownloadFile()\
  12522. return true\
  12523. end\
  12524. if cmdId==IDM_DELETE then\
  12525. self:onDeleteItem()\
  12526. return true\
  12527. end\
  12528. if cmdId==IDM_NEWACC then\
  12529. self:onCreateAccount()\
  12530. return true\
  12531. end\
  12532. if cmdId==IDM_RESETACC then\
  12533. self:onResetAccount()\
  12534. return true\
  12535. end\
  12536. if cmdId==IDM_DELACC then\
  12537. self:onDeleteAccount()\
  12538. return true\
  12539. end\
  12540. if cmdId==IDM_QUITAPP then\
  12541. self:quitApp()\
  12542. return true\
  12543. end\
  12544. return false\
  12545. end\
  12546. function appFrame:onMove()\
  12547. self.app_list:move(1,1,self.width-2,self.height-2)\
  12548. self.app_progress:move(1,self.height-1)\
  12549. return false\
  12550. end\
  12551. function appFrame:onChildRightClick(child,x,y)\
  12552. if child==self.app_list then\
  12553. self.app_list:setFocus()\
  12554. self:onMenu(self:screenToWnd(x,y))\
  12555. return true\
  12556. end\
  12557. return false\
  12558. end\
  12559. function appFrame:onCreate()\
  12560. self:dress(APP_TITLE)\
  12561. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  12562. menuBtn:setColors(menuBtn:getColors().frameText,\
  12563. menuBtn:getColors().titleBack,\
  12564. menuBtn:getColors().frameBack)\
  12565. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  12566. self.app_domain=\"\"\
  12567. self.app_password=\"\"\
  12568. self.app_network=\"wide_area_network\"\
  12569. self.app_port=80\
  12570. self.app_timeout=5\
  12571. self.app_wireless=true\
  12572. self.app_curPath=\"/\"\
  12573. self.app_lastFile=nil\
  12574. self.app_appId=\"sadmin\"..asstring(math.random(1,65535))\
  12575. self.app_list=win.listWindow:new(self,ID_LISTING,1,1,\
  12576. self.width-2,self.height-2)\
  12577. self.app_list:setColors(self:getColors().wndText,\
  12578. self:getColors().wndBack,\
  12579. self:getColors().wndBack,\
  12580. self:getColors().selectedText,\
  12581. self:getColors().selectedBack)\
  12582. self.app_list:setFocus()\
  12583. self.app_progress=\
  12584. win.labelWindow:new(self,ID_PROGRESS,1,self.height-1,\"processing ...\")\
  12585. self.app_progress:show(false)\
  12586. if #appArgs>0 then\
  12587. local ini=fs.loadIniFile(appArgs[1])\
  12588. if ini then\
  12589. self.app_network=asstring(ini:find(\"network\"),\"wide_area_network\")\
  12590. self.app_port=asnumber(ini:find(\"port\"),80)\
  12591. self.app_timeout=asnumber(ini:find(\"timeout\"),5)\
  12592. self.app_domain=asstring(ini:find(\"domain\"),\"\")\
  12593. self.app_password=asstring(ini:find(\"password\"),\"\")\
  12594. self.app_wireless=asstring(ini:find(\"wireless\"),\"true\")~=\"false\"\
  12595. end\
  12596. end\
  12597. self.app_connName=nil\
  12598. self:setActiveTopFrame()\
  12599. if self:canConnect()then\
  12600. self:onFileList()\
  12601. end\
  12602. return true\
  12603. end\
  12604. function appFrame:updateTitle()\
  12605. if self:canConnect()then\
  12606. self:setTitle(string.trimRight(self.app_domain..self.app_curPath,\"/\")..\":\"..APP_TITLE)\
  12607. else\
  12608. self:setTitle(APP_TITLE)\
  12609. end\
  12610. end\
  12611. function appFrame:getSelectedPath()\
  12612. if self.app_list:getData()then\
  12613. if self.app_list:getData().type~=TYPE_UP then\
  12614. return(self.app_curPath..self.app_list:getData().name)\
  12615. end\
  12616. end\
  12617. return nil\
  12618. end\
  12619. function appFrame:getNetwork()\
  12620. return iif(self.app_network:len()<1,\"wide_area_network\",self.app_network)\
  12621. end\
  12622. function appFrame:canConnect()\
  12623. return self.app_domain:len()>0 and self.app_password:len()>0\
  12624. end\
  12625. function appFrame:openConnection()\
  12626. if self.app_connName then\
  12627. self:msgBox(\"Connection\",\"Action in progress!\",colors.red)\
  12628. return false\
  12629. end\
  12630. local con=self:commOpen(nil,self.app_wireless,self.app_port,\
  12631. self.app_timeout,false)\
  12632. if not con then\
  12633. self:msgBox(\"Connection\",\"Could not connect to modem!\",colors.red)\
  12634. return false\
  12635. end\
  12636. self.app_connName=con:getName()\
  12637. self:wantMessages(self:getNetwork(),self.app_connName)\
  12638. self:wantMessages(self.app_appId,self.app_connName)\
  12639. self.app_progress:show(true)\
  12640. return true\
  12641. end\
  12642. function appFrame:closeConnection()\
  12643. if self.app_connName then\
  12644. self:commClose(self.app_connName)\
  12645. self.app_connName=nil\
  12646. self.app_progress:show(false)\
  12647. end\
  12648. end\
  12649. function appFrame:onConnection()\
  12650. local dlg=connectDlg:new(self)\
  12651. if dlg:doModal(self.app_domain,self.app_password,self:getNetwork(),\
  12652. self.app_port,self.app_timeout,self.app_wireless)==ID_OK then\
  12653. self.app_domain=dlg.con_domain:getText()\
  12654. self.app_password=dlg.con_password:getText()\
  12655. self.app_network=dlg.con_network:getText()\
  12656. self.app_port=asnumber(dlg.con_port:getText(),80)\
  12657. self.app_timeout=asnumber(dlg.con_timeout:getText(),5)\
  12658. self.app_wireless=dlg.con_wireless:getChecked()\
  12659. self.app_curPath=\"/\"\
  12660. self:onFileList()\
  12661. end\
  12662. end\
  12663. function appFrame:onFileList()\
  12664. if self:openConnection()then\
  12665. self:sendMessage(self.app_domain,self:getNetwork(),\
  12666. \"listing_request\",\
  12667. {\
  12668. password=self.app_password,\
  12669. path=self.app_curPath,\
  12670. application=self.app_appId\
  12671. },self.app_connName)\
  12672. end\
  12673. end\
  12674. function appFrame:canDownloadFile()\
  12675. return self.app_list:getData()and\
  12676. self.app_list:getData().type==TYPE_FILE\
  12677. end\
  12678. function appFrame:onDownloadFile()\
  12679. if self:canDownloadFile()then\
  12680. if self:openConnection()then\
  12681. self:sendMessage(self.app_domain,self:getNetwork(),\
  12682. \"ftp_request\",\
  12683. {\
  12684. path=self:getSelectedPath(),\
  12685. application=self.app_appId\
  12686. },self.app_connName)\
  12687. end\
  12688. end\
  12689. end\
  12690. function appFrame:onUploadFile()\
  12691. if self:canConnect()then\
  12692. local path=cmndlg.openFile(self,self.app_lastFile)\
  12693. if path then\
  12694. local name=fs.getName(path)\
  12695. self.app_lastFile=path\
  12696. for i=1,self.app_list:count(),1 do\
  12697. if self.app_list:getData(i)then\
  12698. if self.app_list:getData(i).name==name then\
  12699. if cmndlg.confirm(self,\"Overwrite\",\
  12700. \"Overwrite \"..name..\"?\",\
  12701. false,colors.orange)then\
  12702. break\
  12703. else\
  12704. return\
  12705. end\
  12706. end\
  12707. end\
  12708. end\
  12709. local file=fs.open(path,\"r\")\
  12710. if not file then\
  12711. self:msgBox(\"Error\",\"Could not read source \"..path,colors.red)\
  12712. return\
  12713. end\
  12714. local content=file.readAll()\
  12715. file.close()\
  12716. if self:openConnection()then\
  12717. self:sendMessage(self.app_domain,self:getNetwork(),\
  12718. \"file_upload\",\
  12719. {\
  12720. password=self.app_password,\
  12721. path=self.app_curPath..name,\
  12722. content=content\
  12723. },self.app_connName)\
  12724. end\
  12725. end\
  12726. end\
  12727. end\
  12728. function appFrame:canDeleteItem()\
  12729. return self.app_list:getData()and\
  12730. (self.app_list:getData().type==TYPE_FILE or\
  12731. self.app_list:getData().type==TYPE_DIR)\
  12732. end\
  12733. function appFrame:onDeleteItem()\
  12734. if self:canDeleteItem()then\
  12735. local title,message;\
  12736. if self.app_list:getData().type==TYPE_FILE then\
  12737. title=\"Delete File\"\
  12738. message=\"Delete file \"..self:getSelectedPath()\
  12739. elseif self.app_list:getData().type==TYPE_DIR then\
  12740. title=\"Delete Folder\"\
  12741. message=\"Delete folder \"..self:getSelectedPath()..\
  12742. \" and all its contents\"\
  12743. end\
  12744. if cmndlg.confirm(self,title,message,false,colors.orange)then\
  12745. if self:openConnection()then\
  12746. self:sendMessage(self.app_domain,self:getNetwork(),\
  12747. \"file_delete\",\
  12748. {\
  12749. password=self.app_password,\
  12750. path=self:getSelectedPath()\
  12751. },self.app_connName)\
  12752. end\
  12753. end\
  12754. end\
  12755. end\
  12756. local function validateNewFolder(name)\
  12757. return(not name:find(\"/\",1,true))and\
  12758. (not name:find(\" \",1,true))\
  12759. end\
  12760. function appFrame:onNewFolder()\
  12761. if self:canConnect()then\
  12762. local folder=cmndlg.input(self,\"New Folder\",\"Enter new folder name.\",\
  12763. \"new\",\"Name\",nil,validateNewFolder)\
  12764. if folder then\
  12765. if self:openConnection()then\
  12766. self:sendMessage(self.app_domain,self:getNetwork(),\
  12767. \"directory_create\",\
  12768. {\
  12769. password=self.app_password,\
  12770. path=self.app_curPath..folder,\
  12771. },self.app_connName)\
  12772. end\
  12773. end\
  12774. end\
  12775. end\
  12776. function appFrame:canUp()\
  12777. return self:canConnect()and\
  12778. self.app_curPath:len()>1\
  12779. end\
  12780. function appFrame:shouldUp()\
  12781. return self:canUp()and\
  12782. self.app_list:getData()and\
  12783. self.app_list:getData().type==TYPE_UP\
  12784. end\
  12785. function appFrame:onUp()\
  12786. if self:canUp()then\
  12787. self.app_curPath=pathFolder(self.app_curPath)\
  12788. self:onFileList()\
  12789. end\
  12790. end\
  12791. function appFrame:canOpen()\
  12792. return self.app_list:getData()and\
  12793. self.app_list:getData().type==TYPE_DIR\
  12794. end\
  12795. function appFrame:onOpen()\
  12796. if self:canOpen()then\
  12797. self.app_curPath=self:getSelectedPath()..\"/\"\
  12798. self:onFileList()\
  12799. end\
  12800. end\
  12801. function appFrame:doDefaultAction()\
  12802. if self:shouldUp()then\
  12803. self:onUp()\
  12804. elseif self:canOpen()then\
  12805. self:onOpen()\
  12806. elseif self:canDownloadFile()then\
  12807. self:onDownloadFile()\
  12808. end\
  12809. end\
  12810. function appFrame:onCreateAccount()\
  12811. if self:canConnect()then\
  12812. local dlg=accountDlg:new(self)\
  12813. if dlg:doModal(\"New Account\")==ID_OK then\
  12814. if self:openConnection()then\
  12815. self:sendMessage(self.app_domain,self:getNetwork(),\
  12816. \"create_account\",\
  12817. {\
  12818. password=self.app_password,\
  12819. account=dlg.acc_account:getText(),\
  12820. clientPassword=dlg.acc_password:getText()\
  12821. },self.app_connName)\
  12822. end\
  12823. end\
  12824. end\
  12825. end\
  12826. function appFrame:onDeleteAccount()\
  12827. if self:canConnect()then\
  12828. local account=cmndlg.input(self,\"Delete Account\",\
  12829. \"Account to delete.\",nil,\"Account\")\
  12830. if account then\
  12831. if self:openConnection()then\
  12832. self:sendMessage(self.app_domain,self:getNetwork(),\
  12833. \"delete_account\",\
  12834. {\
  12835. password=self.app_password,\
  12836. account=account\
  12837. },self.app_connName)\
  12838. end\
  12839. end\
  12840. end\
  12841. end\
  12842. function appFrame:onResetAccount()\
  12843. if self:canConnect()then\
  12844. local dlg=accountDlg:new(self)\
  12845. if dlg:doModal(\"Reset Account\")==ID_OK then\
  12846. if self:openConnection()then\
  12847. self:sendMessage(self.app_domain,self:getNetwork(),\
  12848. \"reset_password\",\
  12849. {\
  12850. password=self.app_password,\
  12851. account=dlg.acc_account:getText(),\
  12852. clientPassword=dlg.acc_password:getText()\
  12853. },self.app_connName)\
  12854. end\
  12855. end\
  12856. end\
  12857. end\
  12858. appFrame:runApp()",
  12859. ";domain=domain\
  12860. ;password=admin\
  12861. network=wide_area_network\
  12862. port=80\
  12863. timeout=5\
  12864. wireless=true\
  12865. ",
  12866. "local appArgs={...}\
  12867. local appFrame=win.createAppFrame()\
  12868. local APP_TITLE=\"command\"\
  12869. local ID_MENUBTN=101\
  12870. local IDM_QUITAPP=1001\
  12871. local cmdWnd=win.window:base()\
  12872. local hexColors=\
  12873. {\
  12874. [\"0\"]=colors.white,\
  12875. [\"1\"]=colors.orange,\
  12876. [\"2\"]=colors.magenta,\
  12877. [\"3\"]=colors.lightBlue,\
  12878. [\"4\"]=colors.yellow,\
  12879. [\"5\"]=colors.lime,\
  12880. [\"6\"]=colors.pink,\
  12881. [\"7\"]=colors.gray,\
  12882. [\"8\"]=colors.lightGray,\
  12883. [\"9\"]=colors.cyan,\
  12884. [\"a\"]=colors.purple,\
  12885. [\"A\"]=colors.purple,\
  12886. [\"b\"]=colors.blue,\
  12887. [\"B\"]=colors.blue,\
  12888. [\"c\"]=colors.brown,\
  12889. [\"C\"]=colors.brown,\
  12890. [\"d\"]=colors.green,\
  12891. [\"D\"]=colors.green,\
  12892. [\"e\"]=colors.red,\
  12893. [\"E\"]=colors.red,\
  12894. [\"f\"]=colors.black,\
  12895. [\"F\"]=colors.black\
  12896. }\
  12897. local function createEnvironment(wnd)\
  12898. local global=getfenv(0)\
  12899. local data=\
  12900. {\
  12901. x=1,\
  12902. y=1,\
  12903. color=colors.white,\
  12904. bgColor=colors.black,\
  12905. lines={},\
  12906. dir=\"\",\
  12907. path=\".:/rom/programs\",\
  12908. aliases=\
  12909. {\
  12910. [\"ls\"]=\"list\",\
  12911. [\"mv\"]=\"move\",\
  12912. [\"rm\"]=\"delete\",\
  12913. [\"dir\"]=\"list\",\
  12914. [\"sh\"]=\"shell\",\
  12915. [\"cp\"]=\"copy\",\
  12916. [\"rs\"]=\"redstone\",\
  12917. [\"clr\"]=\"clear\"\
  12918. },\
  12919. stack={},\
  12920. term=term.current(),\
  12921. device=iif(wnd.gdi:isTerm(),term.current(),wnd.gdi.gdi__device)\
  12922. }\
  12923. data.buffer=\
  12924. {\
  12925. setTextColor=function(clr)\
  12926. data.color=clr\
  12927. end,\
  12928. setBackgroundColor=function(clr)\
  12929. data.bgColor=clr\
  12930. end,\
  12931. setTextColour=function(clr)\
  12932. data.color=clr\
  12933. end,\
  12934. setBackgroundColour=function(clr)\
  12935. data.bgColor=clr\
  12936. end,\
  12937. getTextColor=function()\
  12938. return data.color\
  12939. end,\
  12940. getBackgroundColor=function()\
  12941. return data.bgColor\
  12942. end,\
  12943. getTextColour=function()\
  12944. return data.color\
  12945. end,\
  12946. getBackgroundColour=function()\
  12947. return data.bgColor\
  12948. end,\
  12949. isColor=function()\
  12950. return data.device.isColor()\
  12951. end,\
  12952. isColour=function()\
  12953. return data.device.isColor()\
  12954. end,\
  12955. getSize=function()\
  12956. return wnd.width,wnd.height\
  12957. end,\
  12958. getCursorPos=function()\
  12959. return data.x,data.y\
  12960. end,\
  12961. write=function(text)\
  12962. text=tostring(text)\
  12963. if text:len()>0 then\
  12964. local first,last=data.x,data.x+text:len()-1\
  12965. if not data.lines[data.y]then\
  12966. data.lines[data.y]={}\
  12967. else\
  12968. for i=#data.lines[data.y],1,-1 do\
  12969. local part=data.lines[data.y][i]\
  12970. if first<=part.first then\
  12971. if last>=part.last then\
  12972. table.remove(data.lines[data.y],i)\
  12973. elseif last>=part.first then\
  12974. part.text=part.text:sub(last-part.first+2)\
  12975. part.first=last+1\
  12976. end\
  12977. elseif last>=part.last then\
  12978. if first<=part.last then\
  12979. part.text=part.text:sub(1,-(part.last-first+2))\
  12980. part.last=first-1\
  12981. end\
  12982. elseif first>part.first and last<part.last then\
  12983. data.lines[data.y][#data.lines[data.y]+1]=\
  12984. {\
  12985. first=last+1,\
  12986. last=part.last,\
  12987. color=part.color,\
  12988. bgColor=part.bgColor,\
  12989. text=part.text:sub(last-part.first+2)\
  12990. }\
  12991. part.text=part.text:sub(1,first-part.first)\
  12992. part.last=first-1\
  12993. end\
  12994. end\
  12995. end\
  12996. data.lines[data.y][#data.lines[data.y]+1]=\
  12997. {\
  12998. first=first,\
  12999. last=last,\
  13000. color=data.color,\
  13001. bgColor=data.bgColor,\
  13002. text=text\
  13003. }\
  13004. data.x=last+1\
  13005. term.setCursorPos(data.x,data.y)\
  13006. wnd:invalidate()\
  13007. end\
  13008. end,\
  13009. setCursorPos=function(cx,cy)\
  13010. data.x=cx\
  13011. data.y=cy\
  13012. wnd.wnd__cursorX=data.x-1\
  13013. wnd.wnd__cursorY=data.y-1\
  13014. if wnd:getFocus()==wnd then\
  13015. local rt=wnd:getScreenRect()\
  13016. cx=cx+rt.x\
  13017. cy=cy+rt.y\
  13018. if rt:contains(cx-1,cy-1)then\
  13019. data.device.setCursorPos(cx,cy)\
  13020. else\
  13021. data.device.setCursorPos(-1,-1)\
  13022. end\
  13023. end\
  13024. end,\
  13025. scroll=function(n)\
  13026. n=math.floor(n)\
  13027. if n>0 then\
  13028. local newLines={}\
  13029. for k,v in pairs(data.lines)do\
  13030. if(k-n)>0 then\
  13031. newLines[k-n]=v\
  13032. end\
  13033. end\
  13034. data.lines=newLines\
  13035. end\
  13036. end,\
  13037. setCursorBlink=function(bool)\
  13038. data.device.setCursorBlink(bool)\
  13039. end,\
  13040. clear=function()\
  13041. data.lines={}\
  13042. wnd:invalidate()\
  13043. term.setCursorPos(1,1)\
  13044. end,\
  13045. clearLine=function()\
  13046. data.lines[data.y]=nil\
  13047. wnd:invalidate()\
  13048. term.setCursorPos(1,data.y)\
  13049. end,\
  13050. blit=function(text,fore,back)\
  13051. local t=tostring(text)\
  13052. local f=tostring(fore)\
  13053. local b=tostring(back)\
  13054. local l=t:len()\
  13055. if f:len()<l then\
  13056. l=f:len()\
  13057. end\
  13058. if b:len()<l then\
  13059. l=b:len()\
  13060. end\
  13061. for c=1,l,1 do\
  13062. setTextColor(hexColors[f:sub(c,c)]or colors.white)\
  13063. setBackgroundColor(hexColors[b:sub(c,c)]or colors.black)\
  13064. write(t:sub(c,c))\
  13065. end\
  13066. end,\
  13067. redirect=data.term.redirect,\
  13068. restore=data.term.restore,\
  13069. current=data.term.current\
  13070. }\
  13071. data.blit=function(gdi)\
  13072. for line=1,wnd.height,1 do\
  13073. if data.lines[line]then\
  13074. for i=1,#data.lines[line],1 do\
  13075. local b=data.lines[line][i]\
  13076. gdi:setTextColor(b.color)\
  13077. gdi:setBackgroundColor(b.bgColor)\
  13078. gdi:write(b.text,b.first-1,line-1)\
  13079. end\
  13080. end\
  13081. end\
  13082. end\
  13083. data.resize=function()\
  13084. local last=0\
  13085. for line,v in pairs(data.lines)do\
  13086. if line>last then\
  13087. last=line\
  13088. end\
  13089. end\
  13090. if last>wnd.height then\
  13091. data.buffer.scroll(last-wnd.height)\
  13092. data.buffer.setCursorPos(data.x,data.y-(last-wnd.height))\
  13093. end\
  13094. end\
  13095. data.redirectTerm=function()\
  13096. term.redirect(data.buffer)\
  13097. end\
  13098. data.restoreTerm=function()\
  13099. term.redirect(data.term)\
  13100. end\
  13101. data.env={}\
  13102. for k,v in pairs(global)do\
  13103. if type(v)==\"table\" then\
  13104. data.env[k]={}\
  13105. for k1,v1 in pairs(v)do\
  13106. data.env[k][k1]=v1\
  13107. end\
  13108. else\
  13109. data.env[k]=v\
  13110. end\
  13111. end\
  13112. if not data.env.shell then\
  13113. data.env.shell={}\
  13114. end\
  13115. data.env.shell.exit=function()\
  13116. wnd.cw__continue=false\
  13117. end\
  13118. data.env.shell.dir=function()\
  13119. return data.dir\
  13120. end\
  13121. data.env.shell.setDir=function(path)\
  13122. data.dir=asstring(path)\
  13123. end\
  13124. data.env.shell.path=function()\
  13125. return data.path\
  13126. end\
  13127. data.env.shell.setPath=function(path)\
  13128. data.path=asstring(path)\
  13129. end\
  13130. data.env.shell.resolve=function(path)\
  13131. path=asstring(path)\
  13132. if path:sub(1,1)==\"/\" or path:sub(1,1)==\"\\\\\" then\
  13133. return fs.combine(\"\",path)\
  13134. else\
  13135. return fs.combine(data.dir,path)\
  13136. end\
  13137. end\
  13138. data.env.shell.resolveProgram=function(cmd)\
  13139. cmd=asstring(cmd)\
  13140. if data.aliases[cmd]then\
  13141. cmd=data.aliases[cmd]\
  13142. end\
  13143. if cmd:sub(1,1)==\"/\" or cmd:sub(1,1)==\"\\\\\" then\
  13144. local path=fs.combine(\"\",cmd)\
  13145. if fs.exists(path)and not fs.isDir(path)then\
  13146. return path\
  13147. end\
  13148. return nil\
  13149. end\
  13150. for path in data.path:gmatch(\"[^:]+\")do\
  13151. path=fs.combine(data.env.shell.resolve(path),cmd)\
  13152. if fs.exists(path)and not fs.isDir(path)then\
  13153. return path\
  13154. end\
  13155. end\
  13156. return nil\
  13157. end\
  13158. data.env.shell.aliases=function()\
  13159. local copy={}\
  13160. for name,cmd in pairs(data.aliases)do\
  13161. copy[name]=cmd\
  13162. end\
  13163. return copy\
  13164. end\
  13165. data.env.shell.setAlias=function(name,cmd)\
  13166. data.aliases[name]=cmd\
  13167. end\
  13168. data.env.shell.clearAlias=function(name)\
  13169. data.aliases[name]=nil\
  13170. end\
  13171. data.env.shell.programs=function(bHidden)\
  13172. local progs={}\
  13173. for path in data.path:gmatch(\"[^:]+\")do\
  13174. path=data.env.shell.resolve(path)\
  13175. if fs.isDir(path)then\
  13176. local success,files=pcall(fs.list,path)\
  13177. if success then\
  13178. for i=1,#files,1 do\
  13179. if not fs.isDir(fs.combine(path,files[i]))and\
  13180. (bHidden or files[i]:sub(1,1)~=\".\")then\
  13181. progs[#progs+1]=files[i]\
  13182. end\
  13183. end\
  13184. end\
  13185. end\
  13186. end\
  13187. table.sort(progs)\
  13188. return progs\
  13189. end\
  13190. data.env.shell.run=function(...)\
  13191. local result=false\
  13192. local args=win.parseCmdLine(...)\
  13193. local path=data.env.shell.resolveProgram(args[1])\
  13194. if path then\
  13195. data.stack[#data.stack+1]=path\
  13196. result=os.run(data.env,path,unpack(args,2))\
  13197. data.stack[#data.stack]=nil\
  13198. elseif asstring(args[1]):len()>0 then\
  13199. error(\"No such program \"..asstring(args[1]),0)\
  13200. end\
  13201. return result\
  13202. end\
  13203. data.env.shell.getRunningProgram=function()\
  13204. if #data.stack>0 then\
  13205. return data.stack[#data.stack]\
  13206. end\
  13207. return nil\
  13208. end\
  13209. return data\
  13210. end\
  13211. function cmdWnd:constructor(parent,id,x,y,width,height)\
  13212. if not win.window.constructor(self,parent,id,x,y,width,height)then\
  13213. return nil\
  13214. end\
  13215. self:setColor(colors.white)\
  13216. self:setBgColor(colors.black)\
  13217. self:setWantKeyInput(win.KEYINPUT_LINE)\
  13218. self.cw__promptColor=colors.yellow\
  13219. self.cw__errorColor=colors.red\
  13220. self:wantEvent(\"*\")\
  13221. self.cw__routine=nil\
  13222. self.cw__state=\"none\"\
  13223. self.cw__ready=false\
  13224. self.cw__sleep=nil\
  13225. self.cw__awake=os.clock()\
  13226. self.cw__continue=true\
  13227. self.cw__env=nil\
  13228. self:startShell()\
  13229. return self\
  13230. end\
  13231. function cmdWnd:setColors(text,prompt,errorColor,back)\
  13232. self:setColor(text)\
  13233. self:setBgColor(back)\
  13234. self.cw__promptColor=prompt\
  13235. self.cw__errorColor=errorColor\
  13236. end\
  13237. function cmdWnd:resume(...)\
  13238. if self.cw__env then\
  13239. local success,state,param;\
  13240. self.cw__env.redirectTerm()\
  13241. if self.cw__state==\"new\" then\
  13242. success,state,param=coroutine.resume(self.cw__routine,self,...)\
  13243. elseif self.cw__state==\"event\" then\
  13244. success,state,param=coroutine.resume(self.cw__routine,...)\
  13245. elseif self.cw__state==\"sleep\" then\
  13246. local p={...}\
  13247. if(p[1]==\"timer\" and p[2]==self.cw__sleep)or\
  13248. (os.clock()>self.cw__awake)or p[1]==\"terminate\" then\
  13249. self.cw__sleep=nil\
  13250. success,state,param=coroutine.resume(self.cw__routine,p[1])\
  13251. end\
  13252. end\
  13253. self.cw__env.restoreTerm()\
  13254. if success~=nil then\
  13255. if success then\
  13256. if self.cw__routine then\
  13257. self.cw__state=state\
  13258. self.cw__ready=true\
  13259. if state==\"sleep\" then\
  13260. self.cw__sleep=self:startTimer(param)\
  13261. self.cw__awake=os.clock()+asnumber(param)\
  13262. end\
  13263. else\
  13264. self.cw__state=\"none\"\
  13265. self.cw__ready=false\
  13266. self.cw__sleep=nil\
  13267. self.cw__env=nil\
  13268. if self:getParent()then\
  13269. self:getParent():sendEvent(\"cmd_exit\",self)\
  13270. end\
  13271. end\
  13272. else\
  13273. if self:getParent()then\
  13274. self:getParent():sendEvent(\"cmd_error\",self,state)\
  13275. end\
  13276. end\
  13277. end\
  13278. end\
  13279. end\
  13280. function cmdWnd:routeWndEvent(event,p1,p2,p3,p4,p5,...)\
  13281. win.window.routeWndEvent(self,event,p1,p2,p3,p4,p5,...)\
  13282. if self.cw__ready then\
  13283. if event==\"terminate\" and self:getFocus()~=self then\
  13284. return false\
  13285. end\
  13286. if event==\"mouse_click\" or event==\"mouse_drag\" or\
  13287. event==\"monitor_touch\" or event==\"mouse_scroll\" then\
  13288. p2,p3=self:screenToWnd(p2,p3)\
  13289. end\
  13290. self:resume(event,p1,p2,p3,p4,p5,...)\
  13291. end\
  13292. return true\
  13293. end\
  13294. local function getShellLoop()\
  13295. return function(wnd,...)\
  13296. local args={...}\
  13297. wnd.cw__env.redirectTerm()\
  13298. if #args>0 then\
  13299. local success,msg=pcall(shell.run,...)\
  13300. if not success then\
  13301. term.setTextColor(wnd.cw__errorColor)\
  13302. print(msg)\
  13303. term.setTextColor(wnd:getColor())\
  13304. term.write(\"Press key ...\")\
  13305. repeat until(os.pullEvent())==\"key\"\
  13306. end\
  13307. else\
  13308. local history={}\
  13309. term.setBackgroundColor(wnd:getBgColor())\
  13310. term.setTextColor(wnd.cw__promptColor)\
  13311. print(os.version())\
  13312. while wnd.cw__continue do\
  13313. local success,msg,line;\
  13314. term.setBackgroundColor(wnd:getBgColor())\
  13315. term.setTextColor(wnd.cw__promptColor)\
  13316. write(shell.dir()..\"> \")\
  13317. term.setTextColor(wnd:getColor())\
  13318. success,line=pcall(read,nil,history)\
  13319. if success then\
  13320. for i=#history,1,-1 do\
  13321. if history[i]==line then\
  13322. table.remove(history,i)\
  13323. end\
  13324. end\
  13325. history[#history+1]=line\
  13326. success,msg=pcall(shell.run,line)\
  13327. if not success then\
  13328. term.setTextColor(wnd.cw__errorColor)\
  13329. print(msg)\
  13330. end\
  13331. else\
  13332. term.setTextColor(wnd.cw__errorColor)\
  13333. print(line)\
  13334. end\
  13335. end\
  13336. end\
  13337. wnd.cw__env.restoreTerm()\
  13338. wnd.cw__routine=nil\
  13339. end\
  13340. end\
  13341. function cmdWnd:startShell()\
  13342. local f=getShellLoop()\
  13343. self.cw__env=createEnvironment(self)\
  13344. self.cw__env.path=self:getWorkSpace():getShell().path()\
  13345. setfenv(f,self.cw__env.env)\
  13346. self.cw__routine=coroutine.create(f)\
  13347. if self.cw__routine then\
  13348. self.cw__continue=true\
  13349. self.cw__state=\"new\"\
  13350. return true\
  13351. end\
  13352. return false\
  13353. end\
  13354. function cmdWnd:ready()\
  13355. return self.cw__state~=\"none\"\
  13356. end\
  13357. function cmdWnd:draw(gdi,bounds)\
  13358. if self.cw__env then\
  13359. self.cw__env.blit(gdi)\
  13360. end\
  13361. end\
  13362. function cmdWnd:onMove()\
  13363. if self.cw__env then\
  13364. self.cw__env.resize()\
  13365. end\
  13366. if self.cw__ready then\
  13367. self:resume(\"term_resize\",self:getSide())\
  13368. end\
  13369. return false\
  13370. end\
  13371. function cmdWnd:onFocus(blurred)\
  13372. self:showCursor()\
  13373. return false\
  13374. end\
  13375. function appFrame:onEvent(event,p1,p2,p3,p4,p5,...)\
  13376. if event==\"btn_click\" then\
  13377. if p1:getId()==ID_MENUBTN then\
  13378. self:onMenu()\
  13379. return true\
  13380. end\
  13381. elseif event==\"menu_cmd\" then\
  13382. return self:onCommand(p1)\
  13383. elseif event==\"cmd_exit\" then\
  13384. self:startTimer(0.1)\
  13385. return true\
  13386. elseif event==\"cmd_error\" then\
  13387. self:msgBox(\"Error\",p2,colors.red)\
  13388. return true\
  13389. end\
  13390. return false\
  13391. end\
  13392. function appFrame:onTimer(id)\
  13393. self:quitApp()\
  13394. return false\
  13395. end\
  13396. function appFrame:onMenu()\
  13397. local menu=win.menuWindow:new(self)\
  13398. menu:addString(\"Quit App   \",IDM_QUITAPP)\
  13399. menu:track(0,1)\
  13400. end\
  13401. function appFrame:onCommand(cmdId)\
  13402. if cmdId==IDM_QUITAPP then\
  13403. self:quitApp()\
  13404. return true\
  13405. end\
  13406. return false\
  13407. end\
  13408. function appFrame:onMove()\
  13409. self.app_cmdWnd:move(0,1,self.width,self.height-1)\
  13410. return false\
  13411. end\
  13412. function appFrame:onChildKey(wnd,key,ctrl,alt,shift)\
  13413. if key==keys.tab then\
  13414. if not ctrl and not alt and not shift and wnd==self.app_cmdWnd then\
  13415. return false\
  13416. end\
  13417. end\
  13418. return win.applicationFrame.onChildKey(self,wnd,key,ctrl,alt,shift)\
  13419. end\
  13420. function appFrame:onCreate()\
  13421. self:dress(APP_TITLE)\
  13422. local menuBtn=win.buttonWindow:new(self,ID_MENUBTN,0,0,\"Menu\")\
  13423. menuBtn:setColors(menuBtn:getColors().frameText,\
  13424. menuBtn:getColors().titleBack,\
  13425. menuBtn:getColors().frameBack)\
  13426. menuBtn:move(nil,nil,nil,nil,win.WND_TOP)\
  13427. self.app_cmdWnd=cmdWnd:new(self,0,0,1,self.width,self.height-1)\
  13428. self.app_cmdWnd:setFocus()\
  13429. self:setActiveTopFrame()\
  13430. self.app_cmdWnd:resume(unpack(appArgs))\
  13431. return self.app_cmdWnd:ready()\
  13432. end\
  13433. appFrame:runApp()\
  13434. ",
  13435. "Explore\
  13436. /win/apps/fexplore\
  13437. \
  13438. \
  13439. \
  13440. NotePad\
  13441. /win/apps/notepad\
  13442. \
  13443. \
  13444. \
  13445. Browse\
  13446. /win/apps/browse\
  13447. \
  13448. \
  13449. \
  13450. Email\
  13451. /win/apps/email\
  13452. \
  13453. \
  13454. \
  13455. Command\
  13456. /win/apps/cmd\
  13457. \
  13458. \
  13459. \
  13460. Chat\
  13461. /win/apps/chat\
  13462. \
  13463. \
  13464. \
  13465. Admin\
  13466. /win/apps/sadmin\
  13467. /win/apps/sadmin.ini\
  13468. \
  13469. \
  13470. Manager\
  13471. /win/apps/manager\
  13472. \
  13473. \
  13474. \
  13475. Shutdown\
  13476. /win/apps/shutdown\
  13477. \
  13478. \
  13479. \
  13480. ",
  13481. "; auto-run at startup\
  13482. ;run=fullPath [arguments]\
  13483. \
  13484. ; name of desktop\
  13485. ;home=Home\
  13486. \
  13487. ; buffer display drawing\
  13488. buffer=true\
  13489. \
  13490. ; start in full screen\
  13491. ;fullscreen=false\
  13492. ",
  13493. "\
  13494. -- collect any program arguments\
  13495. local appArgs = {...}\
  13496. \
  13497. -- create the application's main frame\
  13498. local appFrame = win.createAppFrame()\
  13499. \
  13500. -- run the application's loop\
  13501. appFrame:runApp()\
  13502. ",
  13503. "\
  13504. -- collect any program arguments\
  13505. local appArgs = {...}\
  13506. \
  13507. -- create the application's main frame\
  13508. local appFrame = win.createAppFrame()\
  13509. \
  13510. \
  13511. local APP_TITLE      = \"Starter\"\
  13512. \
  13513. \
  13514. -- handle control, wanted and custom events\
  13515. function appFrame:onEvent(event, p1, p2, p3, p4, p5, ...)\
  13516.   -- handle events and return true\
  13517. \
  13518.   return false\
  13519. end\
  13520. \
  13521. \
  13522. -- if needed, low priority, called about every 1/3 second\
  13523. -- when nothing happening - but keep it brief\
  13524. function appFrame:onIdle(idleCount)\
  13525.   return false\
  13526. end\
  13527. \
  13528. \
  13529. -- if needed\
  13530. function appFrame:onAlarm(alarmId)\
  13531.   return false\
  13532. end\
  13533. \
  13534. \
  13535. -- if needed\
  13536. function appFrame:onTimer(timerId)\
  13537.   return false\
  13538. end\
  13539. \
  13540. \
  13541. -- to reposition control windows, app frames should only\
  13542. -- move if monitor device changes size/resolution or\
  13543. -- fullscreen mode changes\
  13544. function appFrame:onMove()\
  13545.   return false\
  13546. end\
  13547. \
  13548. \
  13549. -- for clean up, if needed\
  13550. function appFrame:onDestroyWnd()\
  13551. end\
  13552. \
  13553. \
  13554. -- to implement accelerator keys. best to use with combo keys\
  13555. -- to try and avoid char event following to child\
  13556. function appFrame:onChildKey(wnd, key, ctrl, alt, shift)\
  13557.   -- base implements tab key navigation\
  13558.   if win.applicationFrame.onChildKey(self, wnd, key, ctrl, alt, shift) then\
  13559.      return true\
  13560.   end\
  13561. \
  13562.   -- return true if handled so child does not receive key event\
  13563. \
  13564.   return false\
  13565. end\
  13566. \
  13567. \
  13568. -- called when app becomes and stops being the active app\
  13569. function appFrame:onFrameActivate(active)\
  13570. end\
  13571. \
  13572. \
  13573. -- called when app is quitting\
  13574. function appFrame:onQuit()\
  13575.   -- return true to stop app from quitting\
  13576. \
  13577.   return false\
  13578. end\
  13579. \
  13580. \
  13581. function appFrame:onCreate()\
  13582.   -- add title bar and close btn, close btn will have focus\
  13583.   -- frame wnd text displays in running app list\
  13584.   self:dress(APP_TITLE)\
  13585. \
  13586. \
  13587.   -- create controls, usually setting focus to first\
  13588. \
  13589. \
  13590.   -- app is constructed, bring it to top\
  13591.   self:setActiveTopFrame()\
  13592. \
  13593.   return true\
  13594. end\
  13595. \
  13596. \
  13597. -- run application loop after methods are defined\
  13598. appFrame:runApp()\
  13599. ",
  13600. "\
  13601. -- collect any program arguments\
  13602. local appArgs = {...}\
  13603. \
  13604. -- create the application's main frame\
  13605. local appFrame = win.createAppFrame()\
  13606. \
  13607. \
  13608. local APP_TITLE         = \"Single\"\
  13609. \
  13610. -- ids should be between 1 - 65535\
  13611. \
  13612. -- control ids\
  13613. local ID_MENUBTN        = 101\
  13614. \
  13615. -- command ids\
  13616. local IDM_ONE           = 1001\
  13617. local IDM_TWO           = 1002\
  13618. local IDM_THREE         = 1003\
  13619. local IDM_QUITAPP       = 1004\
  13620. \
  13621. -- unique id for app frame\
  13622. local ID_MYAPP_FRAME    = 12673\
  13623. \
  13624. \
  13625. -- handle control, wanted and custom events\
  13626. function appFrame:onEvent(event, p1, p2, p3, p4, p5, ...)\
  13627.   -- handle events and return true\
  13628.   if event == \"btn_click\" then\
  13629.      if p1:getId() == ID_MENUBTN then\
  13630.         self:onMenu()\
  13631.         return true\
  13632.      end\
  13633. \
  13634.   elseif event == \"menu_cmd\" then\
  13635.      return self:onCommand(p1)\
  13636.   end\
  13637. \
  13638.   return false\
  13639. end\
  13640. \
  13641. \
  13642. -- if needed, low priority, called about every 1/3 second\
  13643. -- when nothing happening - but keep it brief\
  13644. function appFrame:onIdle(idleCount)\
  13645.   return false\
  13646. end\
  13647. \
  13648. \
  13649. -- if needed\
  13650. function appFrame:onAlarm(alarmId)\
  13651.   return false\
  13652. end\
  13653. \
  13654. \
  13655. -- if needed\
  13656. function appFrame:onTimer(timerId)\
  13657.   return false\
  13658. end\
  13659. \
  13660. \
  13661. -- to reposition control windows, app frames should only\
  13662. -- move if monitor device changes size/resolution or\
  13663. -- fullscreen mode changes\
  13664. function appFrame:onMove()\
  13665.   return false\
  13666. end\
  13667. \
  13668. \
  13669. -- for clean up, if needed\
  13670. function appFrame:onDestroyWnd()\
  13671. end\
  13672. \
  13673. \
  13674. -- to implement accelerator keys. best to use with combo keys\
  13675. -- to try and avoid char event following to child\
  13676. function appFrame:onChildKey(wnd, key, ctrl, alt, shift)\
  13677.   -- base implements tab key navigation\
  13678.   if win.applicationFrame.onChildKey(self, wnd, key, ctrl, alt, shift) then\
  13679.      return true\
  13680.   end\
  13681. \
  13682.   -- return true if handled so child does not receive key event\
  13683. \
  13684.   -- accelerators to menu commands\
  13685.   if ctrl and not alt and not shift then\
  13686.      if key == keys.one then\
  13687.         return self:onCommand(IDM_ONE)\
  13688.      end\
  13689. \
  13690.      if key == keys.two then\
  13691.         return self:onCommand(IDM_TWO)\
  13692.      end\
  13693. \
  13694.      if key == keys.three then\
  13695.         return self:onCommand(IDM_THREE)\
  13696.      end\
  13697.   end\
  13698. \
  13699.   return false\
  13700. end\
  13701. \
  13702. \
  13703. -- called when app becomes and stops being the active app\
  13704. function appFrame:onFrameActivate(active)\
  13705. end\
  13706. \
  13707. \
  13708. -- called when app is quitting\
  13709. function appFrame:onQuit()\
  13710.   -- return true to stop app from quitting\
  13711. \
  13712.   return false\
  13713. end\
  13714. \
  13715. \
  13716. -- method to create and display menu\
  13717. function appFrame:onMenu()\
  13718.   local menu = win.menuWindow:new(self)\
  13719. \
  13720.   menu:addString(\"One   Ctrl+1\",   IDM_ONE)\
  13721.   menu:addString(\"Two   Ctrl+2\",   IDM_TWO)\
  13722.   menu:addString(\"Three Ctrl+3\",   IDM_THREE)\
  13723.   menu:addString(\"------------\")\
  13724.   menu:addString(\"Quit App\",       IDM_QUITAPP)\
  13725. \
  13726.   menu:track(0, 1)\
  13727. end\
  13728. \
  13729. \
  13730. -- command handler\
  13731. function appFrame:onCommand(cmdId)\
  13732.   if cmdId == IDM_ONE then\
  13733.      self:msgBox(\"Menu Command\", \"Application message box.\")\
  13734.      return true\
  13735.   end\
  13736. \
  13737.   if cmdId == IDM_TWO then\
  13738.      self:msgBox(\"Menu Command\",\
  13739.                  \"Application message box with custom colour.\",\
  13740.                  colours.lightBlue)\
  13741.      return true\
  13742.   end\
  13743. \
  13744.   if cmdId == IDM_THREE then\
  13745.      self:getDesktop():msgBox(\"Menu Command\",\
  13746.                               \"System message box with custom colour.\",\
  13747.                               colors.red)\
  13748.      return true\
  13749.   end\
  13750. \
  13751.   if cmdId == IDM_QUITAPP then\
  13752.      self:quitApp()\
  13753.      return true\
  13754.   end\
  13755. \
  13756.   return false\
  13757. end\
  13758. \
  13759. \
  13760. \
  13761. function appFrame:onCreate()\
  13762.   -- single instance, look for existing frame\
  13763.   local instance = self:getDesktop():getWndById(ID_MYAPP_FRAME, false)\
  13764. \
  13765.   -- if found\
  13766.   if instance then\
  13767.      -- bring running instance to top\
  13768.      instance:setActiveTopFrame()\
  13769. \
  13770.      -- and drop out\
  13771.      return false\
  13772.   end\
  13773. \
  13774.   -- not found, change frame id to ID_MYAPP_FRAME\
  13775.   self:setId(ID_MYAPP_FRAME)\
  13776. \
  13777.   -- add title bar and close btn, close btn will have focus\
  13778.   -- frame wnd text displays in running app list\
  13779.   self:dress(APP_TITLE)\
  13780. \
  13781.   -- create menu button on title bar\
  13782.   local menuBtn = win.buttonWindow:new(self, ID_MENUBTN, 0, 0, \"Menu\")\
  13783.   -- customise to blend into title bar\
  13784.   menuBtn:setColors(menuBtn:getColors().frameText,\
  13785.                     menuBtn:getColors().titleBack,\
  13786.                     menuBtn:getColors().frameBack)\
  13787.   -- move on top of title bar text so wont get obscured\
  13788.   menuBtn:move(nil, nil, nil, nil, win.WND_TOP)\
  13789. \
  13790. \
  13791.   -- create controls, usually setting focus to first\
  13792. \
  13793. \
  13794.   -- app is constructed, bring it to top\
  13795.   self:setActiveTopFrame()\
  13796. \
  13797.   return true\
  13798. end\
  13799. \
  13800. \
  13801. -- run application loop after methods are defined\
  13802. appFrame:runApp()\
  13803. ",
  13804. "\
  13805. -- collect any program arguments\
  13806. local appArgs = {...}\
  13807. \
  13808. -- create the application's main frame\
  13809. local appFrame = win.createAppFrame()\
  13810. \
  13811. \
  13812. local APP_TITLE      = \"Menu\"\
  13813. \
  13814. -- ids should be between 1 - 65535\
  13815. \
  13816. -- control ids\
  13817. local ID_MENUBTN     = 101\
  13818. \
  13819. -- command ids\
  13820. local IDM_ONE        = 1001\
  13821. local IDM_TWO        = 1002\
  13822. local IDM_THREE      = 1003\
  13823. local IDM_QUITAPP    = 1004\
  13824. \
  13825. \
  13826. -- handle control, wanted and custom events\
  13827. function appFrame:onEvent(event, p1, p2, p3, p4, p5, ...)\
  13828.   -- handle events and return true\
  13829.   if event == \"btn_click\" then\
  13830.      if p1:getId() == ID_MENUBTN then\
  13831.         self:onMenu()\
  13832.         return true\
  13833.      end\
  13834. \
  13835.   elseif event == \"menu_cmd\" then\
  13836.      return self:onCommand(p1)\
  13837.   end\
  13838. \
  13839.   return false\
  13840. end\
  13841. \
  13842. \
  13843. -- if needed, low priority, called about every 1/3 second\
  13844. -- when nothing happening - but keep it brief\
  13845. function appFrame:onIdle(idleCount)\
  13846.   return false\
  13847. end\
  13848. \
  13849. \
  13850. -- if needed\
  13851. function appFrame:onAlarm(alarmId)\
  13852.   return false\
  13853. end\
  13854. \
  13855. \
  13856. -- if needed\
  13857. function appFrame:onTimer(timerId)\
  13858.   return false\
  13859. end\
  13860. \
  13861. \
  13862. -- to reposition control windows, app frames should only\
  13863. -- move if monitor device changes size/resolution or\
  13864. -- fullscreen mode changes\
  13865. function appFrame:onMove()\
  13866.   return false\
  13867. end\
  13868. \
  13869. \
  13870. -- for clean up, if needed\
  13871. function appFrame:onDestroyWnd()\
  13872. end\
  13873. \
  13874. \
  13875. -- to implement accelerator keys. best to use with combo keys\
  13876. -- to try and avoid char event following to child\
  13877. function appFrame:onChildKey(wnd, key, ctrl, alt, shift)\
  13878.   -- base implements tab key navigation\
  13879.   if win.applicationFrame.onChildKey(self, wnd, key, ctrl, alt, shift) then\
  13880.      return true\
  13881.   end\
  13882. \
  13883.   -- return true if handled so child does not receive key event\
  13884. \
  13885.   -- accelerators to menu commands\
  13886.   if ctrl and not alt and not shift then\
  13887.      if key == keys.one then\
  13888.         return self:onCommand(IDM_ONE)\
  13889.      end\
  13890. \
  13891.      if key == keys.two then\
  13892.         return self:onCommand(IDM_TWO)\
  13893.      end\
  13894. \
  13895.      if key == keys.three then\
  13896.         return self:onCommand(IDM_THREE)\
  13897.      end\
  13898.   end\
  13899. \
  13900.   return false\
  13901. end\
  13902. \
  13903. \
  13904. -- called when app becomes and stops being the active app\
  13905. function appFrame:onFrameActivate(active)\
  13906. end\
  13907. \
  13908. \
  13909. -- called when app is quitting\
  13910. function appFrame:onQuit()\
  13911.   -- return true to stop app from quitting\
  13912. \
  13913.   return false\
  13914. end\
  13915. \
  13916. \
  13917. -- method to create and display menu\
  13918. function appFrame:onMenu()\
  13919.   local menu = win.menuWindow:new(self)\
  13920. \
  13921.   menu:addString(\"One   Ctrl+1\",   IDM_ONE)\
  13922.   menu:addString(\"Two   Ctrl+2\",   IDM_TWO)\
  13923.   menu:addString(\"Three Ctrl+3\",   IDM_THREE)\
  13924.   menu:addString(\"------------\")\
  13925.   menu:addString(\"Quit App\",       IDM_QUITAPP)\
  13926. \
  13927.   menu:track(0, 1)\
  13928. end\
  13929. \
  13930. \
  13931. -- command handler\
  13932. function appFrame:onCommand(cmdId)\
  13933.   if cmdId == IDM_ONE then\
  13934.      self:msgBox(\"Menu Command\", \"Application message box.\")\
  13935.      return true\
  13936.   end\
  13937. \
  13938.   if cmdId == IDM_TWO then\
  13939.      self:msgBox(\"Menu Command\",\
  13940.                  \"Application message box with custom colour.\",\
  13941.                  colours.lightBlue)\
  13942.      return true\
  13943.   end\
  13944. \
  13945.   if cmdId == IDM_THREE then\
  13946.      self:getDesktop():msgBox(\"Menu Command\",\
  13947.                               \"System message box with custom colour.\",\
  13948.                               colors.red)\
  13949.      return true\
  13950.   end\
  13951. \
  13952.   if cmdId == IDM_QUITAPP then\
  13953.      self:quitApp()\
  13954.      return true\
  13955.   end\
  13956. \
  13957.   return false\
  13958. end\
  13959. \
  13960. \
  13961. \
  13962. function appFrame:onCreate()\
  13963.   -- add title bar and close btn, close btn will have focus\
  13964.   -- frame wnd text displays in running app list\
  13965.   self:dress(APP_TITLE)\
  13966. \
  13967.   -- create menu button on title bar\
  13968.   local menuBtn = win.buttonWindow:new(self, ID_MENUBTN, 0, 0, \"Menu\")\
  13969.   -- customise to blend into title bar\
  13970.   menuBtn:setColors(menuBtn:getColors().frameText,\
  13971.                     menuBtn:getColors().titleBack,\
  13972.                     menuBtn:getColors().frameBack)\
  13973.   -- move on top of title bar text so wont get obscured\
  13974.   menuBtn:move(nil, nil, nil, nil, win.WND_TOP)\
  13975. \
  13976. \
  13977.   -- create controls, usually setting focus to first\
  13978. \
  13979. \
  13980.   -- app is constructed, bring it to top\
  13981.   self:setActiveTopFrame()\
  13982. \
  13983.   return true\
  13984. end\
  13985. \
  13986. \
  13987. -- run application loop after methods are defined\
  13988. appFrame:runApp()\
  13989. \
  13990. \
  13991. \
  13992. \
  13993. ",
  13994. "\
  13995. -- collect any program arguments\
  13996. local appArgs = {...}\
  13997. \
  13998. -- create the application's main frame\
  13999. local appFrame = win.createAppFrame()\
  14000. \
  14001. \
  14002. local APP_TITLE         = \"Popup\"\
  14003. \
  14004. -- ids should be between 1 - 65535\
  14005. \
  14006. -- control ids\
  14007. local ID_MENUBTN        = 101\
  14008. local ID_SETTITLEBTN    = 102\
  14009. \
  14010. -- popup ids\
  14011. local ID_TITLETEXT      = 201\
  14012. local ID_OK             = 202\
  14013. \
  14014. -- command ids\
  14015. local IDM_ONE           = 1001\
  14016. local IDM_TWO           = 1002\
  14017. local IDM_THREE         = 1003\
  14018. local IDM_QUITAPP       = 1004\
  14019. \
  14020. -- unique id for app frame\
  14021. local ID_MYAPP_FRAME    = 32174\
  14022. \
  14023. \
  14024. \
  14025. -- myPopup class -------------------------------------------------------\
  14026. local myPopup = win.popupFrame:base()\
  14027. \
  14028. \
  14029. -- return false on failure\
  14030. function myPopup:onCreate()\
  14031.   self:dress(\"Set Title\")\
  14032. \
  14033.   local inputWnd = win.inputWindow:new(self, ID_TITLETEXT, 1, 2, 14,\
  14034.                                    self:getOwner():getText(), \"Title\")\
  14035.   inputWnd:setSel(0, -1)\
  14036.   inputWnd:setFocus()\
  14037. \
  14038.   win.buttonWindow:new(self, ID_OK, 11, 4, \" Ok \")\
  14039. \
  14040.   self:move(nil, nil, 16, 6)\
  14041. \
  14042.   return true\
  14043. end\
  14044. \
  14045. \
  14046. -- handles events for myPopup\
  14047. function myPopup:onEvent(event, p1, p2, p3, p4, p5, ...)\
  14048.   if event == \"btn_click\" then\
  14049.      if p1:getId() == ID_OK then\
  14050.         local titleText = APP_TITLE\
  14051.         local titleWnd = self:getWndById(ID_TITLETEXT)\
  14052. \
  14053.         if titleWnd then\
  14054.            if string.len(titleWnd:getText()) > 0 then\
  14055.               titleText = titleWnd:getText()\
  14056.            end\
  14057.         end\
  14058. \
  14059.         self:getOwner():setTitle(titleText)\
  14060. \
  14061.         self:close(ID_OK)\
  14062. \
  14063.         return true\
  14064.      end\
  14065.   end\
  14066. \
  14067.   return false\
  14068. end\
  14069. -- end myPopup class ---------------------------------------------------\
  14070. \
  14071. \
  14072. -- handle control, wanted and custom events\
  14073. function appFrame:onEvent(event, p1, p2, p3, p4, p5, ...)\
  14074.   -- handle events and return true\
  14075.   if event == \"btn_click\" then\
  14076.      if p1:getId() == ID_MENUBTN then\
  14077.         self:onMenu()\
  14078.         return true\
  14079.      end\
  14080. \
  14081.      if p1:getId() == ID_SETTITLEBTN then\
  14082.         myPopup:new(self):doModal()\
  14083.         return true\
  14084.      end\
  14085. \
  14086.   elseif event == \"menu_cmd\" then\
  14087.      return self:onCommand(p1)\
  14088.   end\
  14089. \
  14090.   return false\
  14091. end\
  14092. \
  14093. \
  14094. -- if needed, low priority, called about every 1/3 second\
  14095. -- when nothing happening - but keep it brief\
  14096. function appFrame:onIdle(idleCount)\
  14097.   return false\
  14098. end\
  14099. \
  14100. \
  14101. -- if needed\
  14102. function appFrame:onAlarm(alarmId)\
  14103.   return false\
  14104. end\
  14105. \
  14106. \
  14107. -- if needed\
  14108. function appFrame:onTimer(timerId)\
  14109.   return false\
  14110. end\
  14111. \
  14112. \
  14113. -- to reposition control windows, app frames should only\
  14114. -- move if monitor device changes size/resolution or\
  14115. -- fullscreen mode changes\
  14116. function appFrame:onMove()\
  14117.   return false\
  14118. end\
  14119. \
  14120. \
  14121. -- for clean up, if needed\
  14122. function appFrame:onDestroyWnd()\
  14123. end\
  14124. \
  14125. \
  14126. -- to implement accelerator keys. best to use with combo keys\
  14127. -- to try and avoid char event following to child\
  14128. function appFrame:onChildKey(wnd, key, ctrl, alt, shift)\
  14129.   -- base implements tab key navigation\
  14130.   if win.applicationFrame.onChildKey(self, wnd, key, ctrl, alt, shift) then\
  14131.      return true\
  14132.   end\
  14133. \
  14134.   -- return true if handled so child does not receive key event\
  14135. \
  14136.   -- accelerators to menu commands\
  14137.   if ctrl and not alt and not shift then\
  14138.      if key == keys.one then\
  14139.         return self:onCommand(IDM_ONE)\
  14140.      end\
  14141. \
  14142.      if key == keys.two then\
  14143.         return self:onCommand(IDM_TWO)\
  14144.      end\
  14145. \
  14146.      if key == keys.three then\
  14147.         return self:onCommand(IDM_THREE)\
  14148.      end\
  14149.   end\
  14150. \
  14151.   return false\
  14152. end\
  14153. \
  14154. \
  14155. -- called when app becomes and stops being the active app\
  14156. function appFrame:onFrameActivate(active)\
  14157. end\
  14158. \
  14159. \
  14160. -- called when app is quitting\
  14161. function appFrame:onQuit()\
  14162.   -- return true to stop app from quitting\
  14163. \
  14164.   return false\
  14165. end\
  14166. \
  14167. \
  14168. -- method to create and display menu\
  14169. function appFrame:onMenu()\
  14170.   local menu = win.menuWindow:new(self)\
  14171. \
  14172.   menu:addString(\"One   Ctrl+1\",   IDM_ONE)\
  14173.   menu:addString(\"Two   Ctrl+2\",   IDM_TWO)\
  14174.   menu:addString(\"Three Ctrl+3\",   IDM_THREE)\
  14175.   menu:addString(\"------------\")\
  14176.   menu:addString(\"Quit App\",       IDM_QUITAPP)\
  14177. \
  14178.   menu:track(0, 1)\
  14179. end\
  14180. \
  14181. \
  14182. -- command handler\
  14183. function appFrame:onCommand(cmdId)\
  14184.   if cmdId == IDM_ONE then\
  14185.      appFrame:msgBox(\"Menu Command\", \"Application message box.\")\
  14186.      return true\
  14187.   end\
  14188. \
  14189.   if cmdId == IDM_TWO then\
  14190.      self:msgBox(\"Menu Command\",\
  14191.                  \"Application message box with custom colour.\",\
  14192.                  colours.lightBlue)\
  14193.      return true\
  14194.   end\
  14195. \
  14196.   if cmdId == IDM_THREE then\
  14197.      self:getDesktop():msgBox(\"Menu Command\",\
  14198.                               \"System message box with custom colour.\",\
  14199.                               colors.red)\
  14200.      return true\
  14201.   end\
  14202. \
  14203.   if cmdId == IDM_QUITAPP then\
  14204.      self:quitApp()\
  14205.      return true\
  14206.   end\
  14207. \
  14208.   return false\
  14209. end\
  14210. \
  14211. \
  14212. \
  14213. function appFrame:onCreate()\
  14214.   -- single instance, look for existing frame\
  14215.   local instance = self:getDesktop():getWndById(ID_MYAPP_FRAME, false)\
  14216. \
  14217.   -- if found\
  14218.   if instance then\
  14219.      -- bring running instance to top\
  14220.      instance:setActiveTopFrame()\
  14221. \
  14222.      -- and drop out\
  14223.      return false\
  14224.   end\
  14225. \
  14226.   -- not found, change frame id to ID_MYAPP_FRAME\
  14227.   self:setId(ID_MYAPP_FRAME)\
  14228. \
  14229.   -- add title bar and close btn, close btn will have focus\
  14230.   -- frame wnd text displays in running app list\
  14231.   self:dress(APP_TITLE)\
  14232. \
  14233.   -- create menu button on title bar\
  14234.   local menuBtn = win.buttonWindow:new(self, ID_MENUBTN, 0, 0, \"Menu\")\
  14235.   -- customise to blend into title bar\
  14236.   menuBtn:setColors(menuBtn:getColors().frameText,\
  14237.                     menuBtn:getColors().titleBack,\
  14238.                     menuBtn:getColors().frameBack)\
  14239.   -- move on top of title bar text so wont get obscured\
  14240.   menuBtn:move(nil, nil, nil, nil, win.WND_TOP)\
  14241. \
  14242. \
  14243.   -- create controls, usually setting focus to first\
  14244.   win.buttonWindow:new(self, ID_SETTITLEBTN, 2, 3, \" Set Title \"):setFocus()\
  14245. \
  14246. \
  14247.   -- app is constructed, bring it to top\
  14248.   self:setActiveTopFrame()\
  14249. \
  14250.   return true\
  14251. end\
  14252. \
  14253. \
  14254. -- run application loop after methods are defined\
  14255. appFrame:runApp()\
  14256. "
  14257. }
  14258. local function backup(path)
  14259.    if fs.exists(path) then
  14260.       print("backing up "..path)
  14261.       if fs.exists("/backup"..path) then
  14262.          fs.delete("/backup"..path)
  14263.       end
  14264.       fs.copy(path, "/backup"..path)
  14265.    end
  14266. end
  14267. backup("/startup")
  14268. backup("/win/startup.ini")
  14269. backup("/win/apps/notepad.ini")
  14270. backup("/win/apps/fexplore.asc")
  14271. backup("/win/apps/browse.ini")
  14272. backup("/win/apps/email.ini")
  14273. backup("/win/apps/sadmin.ini")
  14274. backup("/win/term/desktop.ini")
  14275. backup("/win/term/startup.ini")
  14276. backup("/win/term/theme.ini")
  14277. for i = 1, #srcFiles, 1 do
  14278.    print("unpacking "..srcFiles[i])
  14279.    local hOut = fs.open(srcFiles[i], "w")
  14280.    if not hOut then
  14281.       print("Could not open "..srcFiles[i])
  14282.       return
  14283.    end
  14284.  
  14285.    hOut.write(srcData[i])
  14286.    hOut.close()
  14287. end
Add Comment
Please, Sign In to add comment