• R/O
  • SSH
  • HTTPS

cabos: Commit


Commit MetaInfo

Revision69 (tree)
Time2008-11-23 20:50:29
Authorheavy_baby

Log Message

build number change

Change Summary

Incremental Difference

--- branches/java14/source.txt (nonexistent)
+++ branches/java14/source.txt (revision 69)
@@ -0,0 +1,16499 @@
1+SOAPMethod.Parameter: +Sub Parameter(name as string, Assigns value as variant) + inputParams.value(name) = value +End Sub + +SOAPMethod.Constructor: +Sub Constructor() + initialize +End Sub + +SOAPMethod.ExecuteRPC: +Private Function ExecuteRPC() As SOAPResult + dim response as string + + // intialize connection + if connection = NIL then + connection = new httpSocket + end + + // set up the post data + connection.setRequestHeader "SOAPAction",action + connection.setPostContent formatEnvelope(),"text/xml" + response = connection.post(url,timeout) + + // handle error + if connection.errorCode() <> 0 then + return NIL + end + + // parse the response + return parseSOAPResult(response) +End Function + +SOAPMethod.ParseSOAPResult: +Private Function ParseSOAPResult(resultData as string) As SOAPResult + dim sr as soapResult + dim i,j as integer + dim xnode as xmlNode + + // parse soap result + sr = new soapResult + sr.document = new xmlDocument + sr.document.loadXML resultData + + // extract envelope + for i = 0 to sr.document.childCount-1 + xnode = sr.document.child(i) + if xnode.localName = "Envelope" then + sr.envelope = xnode + exit + end + next + + // provide access to the body tag without having to go through envelope + for i = 0 to sr.envelope.childCount-1 + xnode = sr.envelope.child(i) + if xnode.localName = "Body" then + sr.body = xmlElement(xnode) + exit + end + next + + // check for faults + for i = 0 to sr.body.childCount-1 + xnode = sr.body.child(i) + if xnode.localName = "Fault" then// fault was found + sr.error = true + for j = 0 to xnode.childCount-1// extract fault code and message + if xnode.child(j).localName = "FaultCode" then + sr.errorCode = val(xnode.child(j).firstChild.value) + end + if xnode.child(j).localName = "FaultString" then + sr.errorMessage = xnode.child(j).firstChild.value + end + next + exit + end + next + + + // return the result + return sr + + +exception err as XMLException + sr.error = true + sr.errorCode = -1 + sr.errorMessage = err.message + return sr +End Function + +SOAPMethod.Constructor: +Sub Constructor(WSDLurl as string) + initialize + loadWSDLFromURL WSDLurl +End Sub + +SOAPMethod.LoadWSDLFromURL: +Sub LoadWSDLFromURL(url as string) + dim pageGrab as _soapSocket + dim response as string + + // use the user defined socket if one exists + if connection = NIL then + pageGrab = new httpSocket + else + pageGrab = me.connection + end + + // get the wsdl + response = pageGrab.get(url,timeout) + if pageGrab.errorCode <> 0 then + raise getSOAPException("WSDL could not be loaded from URL") + end + + // parse the wsdl + wsdl = new xmlDocument + wsdl.loadXml response +End Sub + +SOAPMethod.InvokeMethod: +Private Function InvokeMethod(name as string, paramIsArray as boolean) As string + dim sr as soapResult + dim resultNode as xmlNode + + // parse wsdl if found + if wsdl <> NIL then + parseWSDL name,paramIsArray + else// call function with no wsdl + methodName = name + end + + // execute the function + sr = executeRPC() + if sr = NIL then + return "" + end + + // find the result node + resultNode = sr.body.firstChild.firstChild.firstChild + if resultNode = NIL then + resultNode = sr.body.firstChild.firstChild + return resultNode.value + end + + // return the result + if resultNode.type = 3 then + return resultNode.value + else + return resultNode.toString() + end if +End Function + +SOAPMethod.Operator_Lookup: +Function Operator_Lookup(funcName as string, ParamArray params as variant) As string + dim i as integer + + if ubound(params) = -1 then// there are no parameters + if wsdl <> NIL then// clear parameters if there is a wsdl defined + inputParams.clear + end + else// parameters exist + inputParams.clear// clear stale parameters + for i = 0 to ubound(params)// assign new parameters + inputParams.value(str(i)) = params(i) + next + end + + return invokeMethod(funcName,true) +End Function + +SOAPMethod.wsdlFindParamNodesParent: +Private Function wsdlFindParamNodesParent(funcName as string) As xmlNode + dim rlist as xmlNodeList + dim inputMessage as string + dim inputmessageNode, sequenceNode as xmlNode + + // first find the port input name + rlist = wsdlQuery("definitions/portType/operation[@name='" + funcName + "']/input") + inputMessage = xmlElement(rlist.Item(0)).GetAttribute("message") + inputMessage = nthField(inputMessage, ":", 2) + + rlist = wsdlQuery("definitions/message[@name='" + inputMessage + "']") + inputMessageNode = rlist.Item(0) + + if inputMessageNode.childCount = 0 then + return NIL + end + + // some wsdl services will go ahead and have our param details here + if inputMessageNode.childCount >= 1 AND xmlElement(inputMessageNode.firstChild).getAttribute("type") <> "" then + return inputMessageNode + end + + // if there is only one <part> tag and it has an "element" attribute, then we have to find our params + // in the <types> node + if inputMessageNode.childCount = 1 AND xmlElement(inputMessageNode.firstChild).getAttribute("element") <> "" then + rlist = wsdlQuery("definitions/types/schema/element[@name='" + funcName + "']/complexType/sequence") + sequenceNode = rlist.Item(0) + return sequenceNode + end + + return NIL +End Function + +SOAPMethod.wsdlFunctionExists: +Private Function wsdlFunctionExists(funcName as string) As string + dim rlist as xmlNodeList + dim i as integer + + rlist = wsdlQuery("definitions/binding/operation[@name]") + for i = 0 to rlist.length-1 + if xmlElement(rlist.item(i)).getAttribute("name") = funcName then + return xmlElement(rlist.item(i)).getAttribute("name") + end + next + + return "" +End Function + +SOAPMethod.wsdlGetAction: +Private Function wsdlGetAction(funcName as string) As string + dim rlist as xmlNodeList + dim action as string + + rlist = wsdlQuery("definitions/binding/operation[@name='" + funcName + "']/operation") + action = xmlElement(rlist.item(0)).getAttribute("soapAction") + + return action +End Function + +SOAPMethod.wsdlGetAddress: +Private Function wsdlGetAddress() As string + dim rlist as xmlNodeList + dim tmpNode as xmlNode + dim address as string + + // lets get the real url of the service + rlist = wsdlQuery("definitions/service/port/address") + address = xmlElement(rlist.Item(0)).getAttribute("location") + + return address +End Function + +SOAPMethod.wsdlGetMethodNS: +Private Function wsdlGetMethodNS(funcName as string) As string + dim rlist as xmlNodeList + dim ns as string + + rlist = wsdlQuery("definitions/binding/operation[@name='" + funcName + "']/input/body") + ns = xmlElement(rlist.item(0)).getAttribute("namespace") + + if ns = "" then + ns = wsdl.documentElement.getAttribute("targetNamespace") + end + + return ns +End Function + +SOAPMethod.Initialize: +Private Sub Initialize() + inputParams = new dictionary + + namespaces = new dictionary + namespaces.value("SOAP") = "http://schemas.xmlsoap.org/soap/envelope/" + namespaces.value("xsd") = "http://www.w3.org/2001/XMLSchema" + namespaces.value("xsi") = "http://www.w3.org/2001/XMLSchema-instance" + namespaces.value("ENC") = "http://schemas.xmlsoap.org/soap/encoding/" + namespaces.value("si") = "http://soapinterop.org/xsd" + + paramTypes = new dictionary + paramTypes.value("0") = ""// nil + paramTypes.value("2") = "int"// integer + paramTypes.value("5") = "double"// double + paramTypes.value("7") = "string"// date + paramTypes.value("8") = "string"// string + paramTypes.value("9") = ""// object + paramTypes.value("11") = "boolean"// boolean + paramTypes.value("16") = "string"// color +End Sub + +SOAPMethod.Invoke: +Function Invoke(name as string) As SOAPResult + // record the method name + methodName = name + + // if a wsdl exists then use its definition of the method + if wsdl <> NIL then + parseWSDL name,false + end + + // return result + return executeRPC() +End Function + +SOAPMethod.ParseWSDL: +Private Sub ParseWSDL(name as string, paramIsArray as boolean) + dim paramParent as xmlNode + dim i as integer + + // set method name + methodName = wsdlFunctionExists(name) + + // does the function exist + if methodName = "" then + raise getSOAPException("Method name does not exist in WSDL") + end + + // extract method properties from wsdl + url = wsdlGetAddress() + action = wsdlGetAction(methodName) + methodNamespace = wsdlGetMethodNS(methodName) + paramParent = wsdlFindParamNodesParent(methodName) + + // validate parameter count + if paramParent = NIL then// no parameters found + if inputParams.count > 0 then// parameters were passed in + raise getSOAPException("Incorrect parameters") + end + return// no parameters so we are done + end + if paramParent.childCount <> inputParams.count then// compare input params with needed params + raise getSOAPException("Incorrect parameters") + end + + // set up parameters + for i = 0 to paramParent.childCount-1 + if paramIsArray = true then// change array index to name + inputParams.value(xmlElement(paramParent.child(i)).getAttribute("name")) = inputParams.value(str(i)) + inputParams.remove str(i) + else// verify parameter names + if inputParams.hasKey(xmlElement(paramParent.child(i)).getAttribute("name")) = false then + raise getSOAPException("Incorrect parameters") + end + end + next +End Sub + +SOAPMethod.GetSOAPException: +Private Function GetSOAPException(message as string) As SOAPException + dim err as SOAPException + + err = new SOAPException + err.message = message + + return err +End Function + +SOAPMethod.FormatEnvelope: +Private Function FormatEnvelope() As string + dim env as xmlDocument + dim xbody,xdef as xmlNode + dim i as integer + + // create document + env = new xmlDocument + + // setup envelope and namespaces + env.appendChild env.createElement(namespaces.value("SOAP"),"SOAP:Envelope") + for i = 0 to namespaces.count-1 + env.documentElement.setAttribute "xmlns:"+namespaces.key(i),namespaces.value(namespaces.key(i)) + next + + // create body + xbody = env.createElement(namespaces.value("SOAP"),"SOAP:Body") + env.documentElement.appendChild xbody + + // create method + xdef = env.createElement(methodNameSpace,methodName) + xbody.appendChild xdef + + // set parameters + for i = 0 to inputParams.count-1 + xdef.appendChild getParameterNode(env,i) + next + + // return envelope string + return env.toString() +End Function + +SOAPMethod.GetParameterNode: +Private Function GetParameterNode(env as xmlDocument, idx as integer) As xmlNode + dim xnode as xmlElement + dim pname,ptype,pval as string + + // extract parameter name and type + pname = inputParams.key(idx) + ptype = "xsd:"+ paramTypes.value(str(inputParams.value(pname).type)) + + // format parameter types + select case inputParams.value(pname).type + case 11// boolean + if inputParams.value(pname).booleanValue = true then + pval = "1" + else + pval = "0" + end + + case 9// object + if inputParams.value(pname).objectValue isa XMLNode then + xnode = xmlElement(inputParams.value(pname).objectValue) + end + + else + pval = inputParams.value(pname).stringValue + end + + // create node from parameter data if parameter value wasn't already a node + if xnode = NIL then + xnode = env.createElement(pname) + xnode.setAttribute namespaces.value("xsi"),"xsi:type",ptype + xnode.appendChild env.createTextNode(pval) + end + + // return parameter node + return xnode +End Function + +SOAPMethod.UseSocket: +Sub UseSocket(SOAPsocket as _SOAPSocket) + me.connection = soapSocket +End Sub + +SOAPMethod.ClearParameters: +Sub ClearParameters() + inputParams.clear +End Sub + +SOAPMethod.wsdlQuery: +Private Function wsdlQuery(query as string) As xmlNodeList + dim i,x as integer + dim output,qstr,tmp,attr as string + + // Format the XQL query to support namespaces. We these queries after the fact + // in order to keep them more human readable in code for debugging. + for i = 1 to countFields(query,"/") + tmp = nthField(query,"/",i) + + x = instr(tmp,"[") + if x > 0 then + attr = mid(tmp,x) + tmp = nthField(tmp,"[",1) + end + + qstr = "*[local-name()='"+ tmp +"']" + if x > 0 then + qstr = qstr + attr + end + + output = output +"/"+ qstr + next + output = mid(output,2) + + // run the query + return wsdl.xql(output) +End Function + +CCoreController.commandAvailable: +Sub commandAvailable(args() as string) + + if ubound(args) = -1 then return + + dim index as integer = args(0).val + + try + select case index + + case 1 //* QueryResult *// + me.CQueryController1.handleQueryReply args() + + case 2 //* ConnectionInitialized *// + me.CNetworkController1.connectionInitialized args() + + case 3 //* ConnectionClosed *// + me.CNetworkController1.connectionClosed args() + + case 4 //* ConnectionsUpdated *// + me.CNetworkController1.statsUpdated + + case 5 //* AddDownload *// + me.CDownloadsController1.addDownload args() + + case 6 //* RemoveDownload *// + me.CDownloadsController1.removeDownload args() + + case 7 //* UpdateDownloadStats *// + me.CDownloadsController1.updateDownloadStats args() + + case 8 //* DownloadsUpdated *// + me.CDownloadsController1.statsUpdated + me.CQueryController1.statsUpdated + + case 9 //* AddUpload *// + me.CUploadsController1.addUpload args() + + case 10 //* RemoveUpload *// + me.CUploadsController1.removeUpload args() + + case 11 //* UpdateUploadStats *// + me.CUploadsController1.updateUploadStats args() + + case 12 //* UploadsUpdated *// + me.CUploadsController1.statsUpdated + me.CFilterController1.statsUpdated + + case 13 //* AddSharedFile *// + me.CFileurnsController1.addSharedFile args() + + case 14 //* BrowseHostFailed *// + me.CQueryController1.browseHostFailed args() + + case 98 //* CoreConnected *// + me.state = 1 + #if targetWin32 + setApplicationPriority("java.exe", &h40) //Idle + #endif + + case 99 //* CoreInitialized *// + me.state = 2 + me.setValue "All" + me.sendBuffer + coreStarted + + else //* Error Messages *// + System.debugLog args(0) + + end + + catch e as RuntimeException + System.debugLog e.message + + end + +End Sub + +CCoreController.Initialize: +Sub Initialize(network as CNetworkController, query as CQueryController, downloads as CDownloadsController, uploads as CUploadsController, fileurns as CFileurnsController, filter as CFilterController) + + dim javaBundlePath as string + + me.CNetworkController1 = network + me.CQueryController1 = query + me.CDownloadsController1 = downloads + me.CUploadsController1 = uploads + me.CFileurnsController1 = fileurns + me.CFilterController1 = filter + + //* launch LimeWire core *// + + #if debugBuild and targetMachO + try + if getFolderItem("Contents").child("Resources").child("Java").child("CabosCore.jar").exists then + javaBundlePath = getFolderItem("Contents").child("Resources").child("Java").posixPath + me.execute _ + "cd """ + javaBundlePath + """;" + _ + "nice -n 20 java " + _ + "-Xms19M " + _ + "-Xmx114M " + _ + "-Dfile.encoding=UTF-8 " + _ + "-Djava.endorsed.dirs= " + _ + "-Djava.library.path=. " + _ + "-Djava.net.preferIPv4Stack=true " + _ + "-Djava.nio.preferSelect=true " + _ + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog " + _ + "-Dorg.apache.commons.logging.simplelog.defaultlog=debug " + _ + "-cp CabosCore.jar" + _ + ":clink.jar" + _ + ":commons-logging.jar" + _ + ":commons-net.jar" + _ + ":dnsjava.jar" + _ + ":guice-1.0.jar" + _ + ":httpclient-4.0-alpha5-20080522.192134-5.jar" + _ + ":httpcore-4.0-beta2-20080510.140437-10.jar" + _ + ":httpcore-nio-4.0-beta2-20080510.140437-10.jar" + _ + ":icu4j.jar" + _ + ":jaudiotagger.jar" + _ + ":jcraft.jar" + _ + ":jmdns.jar" + _ + ":onion-common.jar" + _ + ":onion-fec.jar " + _ + "jp.sourceforge.cabos.AqMain" + return + + end + + catch + end + + #elseif targetMachO + try + if App.ExecutableFile.parent.parent.child("Resources").child("Java").child("CabosCore.jar").exists then + javaBundlePath = App.ExecutableFile.parent.parent.child("Resources").child("Java").posixPath + + if kOldJava then //* old core *// + me.execute _ + "cd """ + javaBundlePath + """;" + _ + "nice -n 20 java " + _ + "-Xms19M " + _ + "-Xmx114M " + _ + "-Dfile.encoding=UTF-8 " + _ + "-Djava.endorsed.dirs= " + _ + "-Djava.library.path=. " + _ + "-Djava.net.preferIPv4Stack=true " + _ + "-Djava.nio.preferSelect=true " + _ + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog " + _ + "-Dorg.apache.commons.logging.simplelog.defaultlog=fatal " + _ + "-cp CabosCore.jar" + _ + ":clink.jar" + _ + ":commons-httpclient.jar" + _ + ":commons-logging.jar" + _ + ":cryptix.jar" + _ + ":i18n.jar" + _ + ":icu4j.jar" + _ + ":id3v2.jar" + _ + ":jcraft.jar" + _ + ":jmdns.jar" + _ + ":logicrypto.jar" + _ + ":xerces.jar" + _ + ":xml-apis.jar " + _ + "jp.sourceforge.cabos.AqMain" + + else //* new core *// + me.execute _ + "cd """ + javaBundlePath + """;" + _ + "nice -n 20 java " + _ + "-Xms19M " + _ + "-Xmx114M " + _ + "-Dfile.encoding=UTF-8 " + _ + "-Djava.endorsed.dirs= " + _ + "-Djava.library.path=. " + _ + "-Djava.net.preferIPv4Stack=true " + _ + "-Djava.nio.preferSelect=true " + _ + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog " + _ + "-Dorg.apache.commons.logging.simplelog.defaultlog=fatal " + _ + "-cp CabosCore.jar" + _ + ":clink.jar" + _ + ":commons-logging.jar" + _ + ":commons-net.jar" + _ + ":dnsjava.jar" + _ + ":guice-1.0.jar" + _ + ":httpclient-4.0-alpha5-20080522.192134-5.jar" + _ + ":httpcore-4.0-beta2-20080510.140437-10.jar" + _ + ":httpcore-nio-4.0-beta2-20080510.140437-10.jar" + _ + ":icu4j.jar" + _ + ":jaudiotagger.jar" + _ + ":jcraft.jar" + _ + ":jmdns.jar" + _ + ":onion-common.jar" + _ + ":onion-fec.jar " + _ + "jp.sourceforge.cabos.AqMain" + + end + + return + end + + catch + end + + #elseif targetCarbon + try + if App.ExecutableFile.parent.child("Contents").child("Resources").child("Java").child("CabosCore.jar").exists then + me.port = 1024 + me.listen + App.ExecutableFile.parent.child("Contents").child("Resources").child("Java").child("CabosCore").launch + return + + end + + catch + end + + #elseif targetWin32 + dim bs as binaryStream + dim f as folderItem + + try + if App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child("Java").child("CabosCore.jar").exists then + + if targetNT then + javaBundlePath = App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child("Java").posixPath + me.execute _ + javaBundlePath.left(2) + "&" + _ + "cd """ + javaBundlePath + """&" + _ + "java " + _ + "-ss32k " + _ + "-oss32k " + _ + "-ms4m " + _ + "-Xminf0.10 " + _ + "-Xmaxf0.25 " + _ + "-Dfile.encoding=UTF-8 " + _ + "-Djava.library.path=. " + _ + "-Djava.net.preferIPv4Stack=true " + _ + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog " + _ + "-Dorg.apache.commons.logging.simplelog.defaultlog=fatal " + _ + "-cp CabosCore.jar" + _ + ";clink.jar" + _ + ";commons-logging.jar" + _ + ";commons-net.jar" + _ + ";dnsjava.jar" + _ + ";guice-1.0.jar" + _ + ";httpclient-4.0-alpha5-20080522.192134-5.jar" + _ + ";httpcore-4.0-beta2-20080510.140437-10.jar" + _ + ";httpcore-nio-4.0-beta2-20080510.140437-10.jar" + _ + ";icu4j.jar" + _ + ";jaudiotagger.jar" + _ + ";jcraft.jar" + _ + ";jmdns.jar" + _ + ";onion-common.jar" + _ + ";onion-fec.jar " + _ + "jp.sourceforge.cabos.AqMain" + return + + else + javaBundlePath = App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child("Java").posixPath + f = PreferencesFolder.fixRbBug.child("CabosCore.bat") + + try + bs = f.createBinaryFile("") + bs.write convertEncoding( _ + javaBundlePath.left(2) + EndOfLine + _ + "cd """ + javaBundlePath + """" + EndOfLine + _ + "java " + _ + "-ss32k " + _ + "-oss32k " + _ + "-ms4m " + _ + "-Xminf0.10 " + _ + "-Xmaxf0.25 " + _ + "-Dfile.encoding=UTF-8 " + _ + "-Djava.library.path=. " + _ + "-Djava.net.preferIPv4Stack=true " + _ + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog " + _ + "-Dorg.apache.commons.logging.simplelog.defaultlog=fatal " + _ + "-cp CabosCore.jar" + _ + ";clink.jar" + _ + ";commons-logging.jar" + _ + ";commons-net.jar" + _ + ";dnsjava.jar" + _ + ";guice-1.0.jar" + _ + ";httpclient-4.0-alpha5-20080522.192134-5.jar" + _ + ";httpcore-4.0-beta2-20080510.140437-10.jar" + _ + ";httpcore-nio-4.0-beta2-20080510.140437-10.jar" + _ + ";icu4j.jar" + _ + ";jaudiotagger.jar" + _ + ";jcraft.jar" + _ + ";jmdns.jar" + _ + ";onion-common.jar" + _ + ";onion-fec.jar " + _ + "jp.sourceforge.cabos.AqMain" + EndOfLine, _ + Encodings.systemDefault) + catch + + finally + if bs <> nil then bs.close + + end + + me.execute convertEncoding(f.posixPath, Encodings.systemDefault) + return + + end + + end + + catch + end + + #elseif targetLinux + try + if App.ExecutableFile.parent.child("Contents").fixRbBug.child("Resources").fixRbBug.child("Java").fixRbBug.child("CabosCore.jar").fixRbBug.exists then + javaBundlePath = App.ExecutableFile.parent.child("Contents").fixRbBug.child("Resources").fixRbBug.child("Java").fixRbBug.posixPath + + me.execute _ + "cd """ + javaBundlePath + """;" + _ + "java " + _ + "-Xms32m " + _ + "-Dfile.encoding=UTF-8 " + _ + "-Djava.library.path=. " + _ + "-Djava.net.preferIPv4Stack=true " + _ + "-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog " + _ + "-cp CabosCore.jar" + _ + ":clink.jar" + _ + ":commons-httpclient.jar" + _ + ":commons-logging.jar" + _ + ":cryptix.jar" + _ + ":i18n.jar" + _ + ":icu4j.jar" + _ + ":id3v2.jar" + _ + ":jcraft.jar" + _ + ":jmdns.jar" + _ + ":logicrypto.jar" + _ + ":xerces.jar" + _ + ":xml-apis.jar " + _ + "jp.sourceforge.cabos.AqMain" + return + + end + + catch + end + + #endif + + coreCorrupted + +End Sub + +CCoreController.coreDisconnected: +Sub coreDisconnected() + + #if not targetMachO and targetCarbon + me.close + + #endif + + select case me.state + + case 0 + coreLoadingError + + case 1 + coreBlockedByFirewall + + case 2 + if me.isShuttingdown then + coreStopped + else + coreCrashed + end + + end + +End Sub + +CCoreController.setValue: +Sub setValue(defaults as string, param as string) + + select case defaults + + //* general *// + + case "kAqAdultFilter" + me.sendCommand "setAdultFilter|" + kAqAdultFilter.getBoolAsString + me.sendCommand "applyFilterSettings" + + case "kAqKeywordFilterKeywords" + me.sendCommand "setBannedKeywords|" + kAqKeywordFilterKeywords.join("|") + me.sendCommand "applyFilterSettings" + + //* download *// + + case "kAqSaveDirectory" + me.sendCommand "setSaveDirectory|" + kAqSaveDirectory + me.sendCommand "applySaveDirectory" + + case "kAqIncompletePurgeTime" + me.sendCommand "setIncompletePurgeTime|" + str(kAqIncompletePurgeTime) + + case "kAqConcurrentDownloads" + me.sendCommand "setMaxSimDownload|" + str(kAqConcurrentDownloads) + + case "kAqDownstreamLimit" + me.sendCommand "setDownloadSpeed|" + str(kAqDownstreamLimit) + me.sendCommand "applyDownloadSpeed" + + //* sharing *// + + case "kAqSharedDirectories" + me.sendCommand "setDirectories|" + kAqSharedDirectories.join("|") + me.sendCommand "applyDirectories" + + case "kAqPartialFileSharing" + me.sendCommand "setAllowPartialSharing|" + kAqPartialFileSharing.getBoolAsString + + case "kAqCompleteFileSharing" + me.sendCommand "setAllowCompleteSharing|" + kAqCompleteFileSharing.getBoolAsString + + case "kAqMaxUploads" + me.sendCommand "setMaxUploads|" + str(kAqMaxUploads) + + case "kAqMaxUploadsPerPerson" + me.sendCommand "setUploadsPerPerson|" + str(kAqMaxUploadsPerPerson) + + case "kAqUpstreamLimit" + me.sendCommand "setUploadSpeed|" + str(kAqUpstreamLimit) + me.sendCommand "applyUploadSpeed" + + //* Network *// + + case "kAqConnectionSpeed" + me.sendCommand "setConnectionSpeed|" + str(kAqConnectionSpeed) + + case "kAqPort" + me.sendCommand "setPort|" + str(kAqPort) + + case "kAqUPnPType" + me.sendCommand "setUPnPType|" + str(kAqUPnPType) + + case "kAqEnableUltrapeer" + me.sendCommand "setEnableUltrapeer|" + kAqEnableUltrapeer.getBoolAsString + + case "kAqLocale" + me.sendCommand "setUsesLocalePreferencing|" + kAqLocale.getBoolAsString + + case "kAqPreferLocale" + me.sendCommand "setLanguage|" + kAqPreferLocale + + case "kAqAllowFreeloaders" + me.sendCommand "setAllowFreeloaders|" + kAqAllowFreeloaders.getBoolAsString + + //* Advanced *// + + case "kAqUseProxy" + if kAqUseProxy then + me.sendCommand "setProxyType|" + str(kAqProxyType) + + else + me.sendCommand "setProxyType|0" + + end + + case "kAqProxyServer" + me.sendCommand "setProxyServer|" + kAqProxyServer + + case "kAqProxyPort" + me.sendCommand "setProxyPort|" + str(kAqProxyPort) + + case "kAqProxyRequiresAuthentication" + me.sendCommand "setRequiresAuthentication|" + kAqProxyRequiresAuthentication.getBoolAsString + + case "kAqProxyUsername" + me.sendCommand "setProxyUsername|" + kAqProxyUsername + + case "kAqProxyPassword" + me.sendCommand "setProxyPassword|" + kAqProxyPassword + + case "kAqProxyPrivate" + me.sendCommand "setProxyPrivate|" + kAqProxyPrivate.getBoolAsString + + case "kAqIPFilterIPs" + me.sendCommand "setBannedIPs|" + kAqIPFilterIPs.join("|") + me.sendCommand "applyFilterSettings" + + case "All" + + //* general *// + + me.sendCommand "setAdultFilter|" + kAqAdultFilter.getBoolAsString + me.sendCommand "setBannedKeywords|" + kAqKeywordFilterKeywords.join("|") + + //* download *// + + me.sendCommand "setSaveDirectory|" + kAqSaveDirectory + me.sendCommand "setIncompletePurgeTime|" + str(kAqIncompletePurgeTime) + me.sendCommand "setMaxSimDownload|" + str(kAqConcurrentDownloads) + me.sendCommand "setDownloadSpeed|" + str(kAqDownstreamLimit) + + //* sharing *// + + me.sendCommand "setDirectories|" + kAqSharedDirectories.join("|") + me.sendCommand "setAllowPartialSharing|" + kAqPartialFileSharing.getBoolAsString + me.sendCommand "setAllowCompleteSharing|" + kAqCompleteFileSharing.getBoolAsString + me.sendCommand "setMaxUploads|" + str(kAqMaxUploads) + me.sendCommand "setUploadsPerPerson|" + str(kAqMaxUploadsPerPerson) + me.sendCommand "setUploadSpeed|" + str(kAqUpstreamLimit) + + //* network *// + + me.sendCommand "setConnectionSpeed|" + str(kAqConnectionSpeed) + me.sendCommand "setPort|" + str(kAqPort) + me.sendCommand "setUPnPType|" + str(kAqUPnPType) + me.sendCommand "setEnableUltrapeer|" + kAqEnableUltrapeer.getBoolAsString + me.sendCommand "setUsesLocalePreferencing|" + kAqLocale.getBoolAsString + me.sendCommand "setLanguage|" + kAqPreferLocale + me.sendCommand "setAllowFreeloaders|" + kAqAllowFreeloaders.getBoolAsString + + //* advanced *// + + if kAqUseProxy then + me.sendCommand "setProxyType|" + str(kAqProxyType) + + else + me.sendCommand "setProxyType|0" + + end + + me.sendCommand "setProxyServer|" + kAqProxyServer + me.sendCommand "setProxyPort|" + str(kAqProxyPort) + me.sendCommand "setRequiresAuthentication|" + kAqProxyRequiresAuthentication.getBoolAsString + me.sendCommand "setProxyUsername|" + kAqProxyUsername + me.sendCommand "setProxyPassword|" + kAqProxyPassword + me.sendCommand "setProxyPrivate|" + kAqProxyPrivate.getBoolAsString + me.sendCommand "setBannedIPs|" + kAqIPFilterIPs.join("|") + + me.sendCommand "start" + + end + +End Sub + +CCoreController.setValue: +Sub setValue(defaults as string) + + me.setValue defaults, "" + +End Sub + +CCoreController.sendCommand: +Sub sendCommand(arg as string) + + if me.state < 2 then + me.buffers.append arg + return + + end + + #if targetMachO or targetWin32 or targetLinux + if me.isRunning then + me.writeLine arg + + end + + #elseif targetCarbon + if me.isConnected then + me.write arg + me.write EndOfLine.UNIX + + end + + #endif + +End Sub + +CCoreController.sendBuffer: +Sub sendBuffer() + + dim buffer as string + + for each buffer in me.buffers + me.sendCommand buffer + next + + redim me.buffers(-1) + +End Sub + +CCoreController.shutdown: +Sub shutdown() + + me.isShuttingdown = true + me.sendCommand "shutdown" + +End Sub + +CCoreController.Completed: +Sub Completed() + + me.coreDisconnected + +End Sub + +CCoreController.DataAvailable: +Sub DataAvailable() + + #if targetMachO or targetWin32 or targetLinux + dim messages(-1) as string + dim line as string + + messages = me.readAll.defineEncoding(Encodings.UTF8).replaceAllB(EndOfLine, EndOfLine.UNIX).split(EndOfLine.UNIX) + + for each line in messages + me.commandAvailable line.split("<aq/>") + next + + #elseif targetCarbon + dim position as integer = me.lookahead(Encodings.UTF8).instrb(EndOfLine.UNIX) + + while position <> 0 + me.commandAvailable me.read(position - 1, Encodings.UTF8).split("<aq/>") + call me.read(1) + position = me.lookahead(Encodings.UTF8).instrb(EndOfLine.UNIX) + wend + + #endif + +End Sub + +CDefaultsController.Write: +Sub Write(key as string, value as variant) + + select case value.type + + case 11 //* boolean *// + me.prefs.root.setBoolean key, value.BooleanValue + + case 2 //* integer *// + me.prefs.root.setInteger key, value.IntegerValue + + case 8 //* string *// + me.prefs.root.setString key, value.StringValue + + end + +End Sub + +CDefaultsController.Read: +Function Read(key as string, value as variant) As variant + + if me.prefs.root.exists(key) = false then return value + + try + select case value.type + + case 11 //* boolean *// + value = me.prefs.root.getBoolean(key) + + case 2 //* integer *// + value = me.prefs.root.getInteger(key) + + case 8 //* string *// + value = me.prefs.root.getString(key) + + end + + catch + + end + + return value + +End Function + +CDefaultsController.WriteArrayString: +Sub WriteArrayString(key as string, values() as string) + + me.prefs.root.SetList key, values, 0, ubound(values) + +End Sub + +CDefaultsController.Constructor: +Sub Constructor() + + //* load preferences *// + + dim f as folderItem + + try + #if targetMacOS + f = PreferencesFolder.Child("Cabos.plist") + + #elseif targetWin32 + f = PreferencesFolder.fixRbBug.Child("Cabos.plist") + + #elseif targetLinux + f = PreferencesFolder.Child("Cabos.plist").fixRbBug + + #endif + + me.prefs = new plist(f) + + catch + + end + +End Sub + +CDefaultsController.Destructor: +Sub Destructor() + + //* save preferences *// + + try + me.prefs.Save + + catch + + end + +End Sub + +CDefaultsController.ReadArrayString: +Function ReadArrayString(key as string, values() as string) As String() + + if me.prefs.root.exists(key) = false then return values + + me.prefs.root.GetList(key, values, 0) + + return values + +End Function + +CDefaultsController.ReadArrayInteger: +Function ReadArrayInteger(key as string, values() as integer) As Integer() + + if me.prefs.root.exists(key) = false then return values + + me.prefs.root.GetList(key, values, 0) + + return values + +End Function + +CDefaultsController.ReadArrayBoolean: +Function ReadArrayBoolean(key as string, values() as boolean) As Boolean() + + if me.prefs.root.exists(key) = false then return values + + me.prefs.root.GetList(key, values, 0) + + return values + +End Function + +CDefaultsController.WriteArrayBoolean: +Sub WriteArrayBoolean(key as string, values() as boolean) + + me.prefs.root.SetList key, values, 0, ubound(values) + +End Sub + +CDefaultsController.WriteArrayInteger: +Sub WriteArrayInteger(key as string, values() as integer) + + me.prefs.root.SetList key, values, 0, ubound(values) + +End Sub + +CDownloadsController.addDownload: +Sub addDownload(args() as string) + + if ubound(args) <> 6 then return + + if me.representedInfos.hasKey(args(1).val) then return + + dim c as new CDownloadModel(args) + + me.representedObjects.append c + me.representedInfos.value(c.getRepresentation) = ubound(me.representedObjects) + me.flush + + me.markedTable.value(c.sha1) = true + +End Sub + +CDownloadsController.removeDownload: +Sub removeDownload(args() as string) + + if ubound(args) <> 1 then return + + dim hashCode as integer = args(1).val + + if me.representedInfos.hasKey(hashCode) = false then return + + dim infoArray as integer = me.representedInfos.value(hashCode) + dim c as CDownloadModel = CDownloadModel(me.representedObjects(infoArray)) + + c.isComplete = true + + dim f, m as folderItem + + if c.isCanceled = false then + try + select case c.getMediaType + + case 1 //* music *// + if kAqMoveMusic and kAqMoveMusicLocation <> "" then + f = getPath2FolderItem(c.path) + m = getPath2FolderItem(kAqMoveMusicLocation) + f.moveFileTo m + c.path = m.child(f.name).posixPath + + end + + case 2 //* picture *// + if kAqMovePictures and kAqMovePicturesLocation <> "" then + f = getPath2FolderItem(c.path) + m = getPath2FolderItem(kAqMovePicturesLocation) + f.moveFileTo m + c.path = m.child(f.name).posixPath + + end + + case 3 //* movie *// + if kAqMoveMovies and kAqMoveMoviesLocation <> "" then + f = getPath2FolderItem(c.path) + m = getPath2FolderItem(kAqMoveMoviesLocation) + f.moveFileTo m + c.path = m.child(f.name).posixPath + + end + + end + + catch + + end + + downloadCompleted c + + end + + if c.isCanceled or kAqAutoClearDownloads then + me.remove infoArray + + else + c.invalidateValues + me.representedObjects(infoArray) = c + + end + + me.flush + +End Sub + +CDownloadsController.updateDownloadStats: +Sub updateDownloadStats(args() as string) + + if ubound(args) <> 12 then return + + dim hashCode as integer = args(1).val + + if me.representedInfos.hasKey(hashCode) = false then return + + dim infoArray as integer = me.representedInfos.value(hashCode) + dim c as CDownloadModel = CDownloadModel(me.representedObjects(infoArray)) + + c.updateStats args + c.invalidateValues + + me.representedObjects(infoArray) = c + +End Sub + +CDownloadsController.statsUpdated: +Sub statsUpdated() + + dim o as CStatsModel + dim c as CTransferModel + dim downloading, negociating as integer + dim bandwidth as double + + for each o in me.representedObjects + c = CTransferModel(o) + + if c.isActive then + downloading = downloading + 1 + bandwidth = bandwidth + c.measuredBandwidth + + elseif c.isComplete = false then + negociating = negociating + 1 + + end + + next + + me.flush + updateCell downloading, negociating, bandwidth + +End Sub + +CDownloadsController.getDownloadHosts: +Function getDownloadHosts(index as integer) As string + + return CDownloadModel(me.representedObjects(index)).hosts + +End Function + +CDownloadsController.Constructor: +Sub Constructor() + + super.Constructor + + me.markedTable = new Dictionary + +End Sub + +CDownloadsController.hasMarkedDownloadItem: +Function hasMarkedDownloadItem(sha1 as string) As boolean + + return me.markedTable.hasKey(sha1) + +End Function + +CEditMenuController.openEditMenu: +Function openEditMenu(target as CEditField) As boolean + + me.actionPerformed = false + me.target = target + me.target.setFocus + + dim c as new clipboard + + if me.target.selLength <> 0 then + me.addrow getLocalizedString("Cut", "ContextualMenu") + me.addrow getLocalizedString("Copy", "ContextualMenu") + + end + + if c.TextAvailable then _ + me.addrow getLocalizedString("Paste", "ContextualMenu") + + me.addrow getLocalizedString("Clear", "ContextualMenu") + + if me.target.text.lenb <> 0 then + me.addSeparator + me.addrow getLocalizedString("Select All", "ContextualMenu") + + end + + c.close + me.open + me.deleteAllRows + + me.target = nil + + return me.actionPerformed + +End Function + +CEditMenuController.Action: +Sub Action(item As String) + + me.actionPerformed = true + + dim c as new clipboard + dim position as integer + + select case item + + case getLocalizedString("Cut", "ContextualMenu") + c.text = me.target.selText + position = me.target.selStart + me.target.text = me.target.text.left(me.target.selStart) + _ + me.target.text.mid(me.target.selStart + me.target.selLength + 1) + me.target.selStart = position + + case getLocalizedString("Copy", "ContextualMenu") + c.text = me.target.selText + + case getLocalizedString("Paste", "ContextualMenu") + me.target.selText = c.text + + case getLocalizedString("Clear", "ContextualMenu") + me.target.text = "" + + case getLocalizedString("Select All", "ContextualMenu") + me.target.selStart = 0 + me.target.selLength = me.target.text.len + + end + + c.close + +End Sub + +CFileurnsController.hasKey: +Function hasKey(sha1 as string) As boolean + + return kAqExistingFileMatching and me.fileURNs.hasKey(sha1) + +End Function + +CFileurnsController.addSharedFile: +Sub addSharedFile(args() as string) + + if kAqExistingFileMatching = false or ubound(args) <> 1 then return + + me.fileURNs.value(args(1)) = true + +End Sub + +CFileurnsController.load: +Protected Sub load(cache as string) + + dim r as new regEx + dim m as regexMatch + dim bs as binaryStream + dim s as string + + try + #if targetMachO + bs = PreferencesFolder.parent.child("Application Support").child("Cabos").child(cache).OpenAsBinaryFile(false) + + #elseif targetCarbon + bs = PreferencesFolder.child(".cabos").child(cache).OpenAsBinaryFile(false) + + #elseif targetWin32 + if PreferencesFolder.fixRbBug.child("Cabos").exists then + bs = PreferencesFolder.fixRbBug.child("Cabos").child(cache).OpenAsBinaryFile(false) + + elseif PreferencesFolder.fixRbBug.parent.child(".cabos").exists then + bs = PreferencesFolder.fixRbBug.parent.child(".cabos").child(cache).OpenAsBinaryFile(false) + + end + + #elseif targetLinux + bs = PreferencesFolder.child(".cabos").fixRbBug.child(cache).fixRbBug.OpenAsBinaryFile(false) + + #endif + + s = bs.read(bs.length, Encodings.ASCII) + r.searchPattern = "(urn\:sha1\:[A-Z0-9]+)q" + m = r.search(s) + + while m <> nil + + me.fileURNs.value(m.subExpressionString(1)) = true + m = r.search(s, m.subExpressionStartB(1) + m.subExpressionString(1).lenb) + + wend + + catch + + finally + if bs <> nil then bs.close + + end + +End Sub + +CFileurnsController.Constructor: +Sub Constructor() + + me.fileURNs = new dictionary + + if kAqExistingFileMatching then + load "fileurns.cache" + load "ttrees.cache" + load "ttroot.cache" + + end + +End Sub + +CFilterController.Initialize: +Sub Initialize(query as CQueryController) + + me.CQueryController1 = query + +End Sub + +CFilterController.filterResults: +Sub filterResults() + + if me.currentFilter = nil or me.CQueryController1 = nil then return + + dim index as integer = me.CQueryController1.getCurrentIndex + + if me.CQueryController1.hasQueryModel(index) = false then return + + dim query as CQueryModel = me.CQueryController1.getQueryModel(index) + dim o as CStatsModel + dim c as CResponseModel + dim d(-1) as CResponseModel + dim f as new dictionary + dim k as integer + + for each o in query.response.representedObjects + + c = CResponseModel(o) + + if me.isFilteredResponse(c) then + d.append c + f.value(c.sha1) = k + k = k + 1 + + end + + next + + me.CQueryController1.setFilteredQuery new CQueryModel(d, f) + +End Sub + +CFilterController.setSizeFilter: +Sub setSizeFilter(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.size = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setBitrateFilter: +Sub setBitrateFilter(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.bitrate = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setMediaFilter: +Sub setMediaFilter(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.media = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setKeywordFilter: +Sub setKeywordFilter(value as string) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.keyword = value.lowercase + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.isFilteredResponse: +Function isFilteredResponse(c as CResponseModel) As boolean + + return (c.spam = false or kAqSpamFilter = false) and _ + ((me.currentFilter.enabled = false) or _ + (me.currentFilter.media = 0 or me.currentFilter.media = c.mediaType) and _ + (me.currentFilter.bitrate <= c.bitrate) and _ + (me.currentFilter.size <= c.fileSize) and _ + (me.currentFilter.sources <= c.sources) and _ + (me.currentFilter.speed <= c.speed) and _ + (me.currentFilter.keyword.lenb = 0 or _ + c.fileName.lowercase.instrb(me.currentFilter.keyword) <> 0 or _ + c.artist.lowercase.instrb(me.currentFilter.keyword) <> 0 or _ + c.album.lowercase.instrb(me.currentFilter.keyword) <> 0 or _ + c.title.lowercase.instrb(me.currentFilter.keyword) <> 0)) + +End Function + +CFilterController.updateResults: +Sub updateResults() + + if me.currentFilter = nil or me.CQueryController1 = nil then return + + dim index as integer = me.CQueryController1.getCurrentIndex + + if me.CQueryController1.hasQueryModel(index) = false then return + + dim k as integer + dim query as CQueryModel = me.CQueryController1.getQueryModel(index) + dim o as CStatsModel + dim c as CResponseModel + dim d(-1) as CResponseModel + dim f as new dictionary + + query.response.sort me.currentFilter.sortColumn, me.currentFilter.sortDirection + + for each o in query.response.representedObjects + + c = CResponseModel(o) + + if me.isFilteredResponse(c) then + d.append c + f.value(c.sha1) = k + k = k + 1 + + end + + next + + me.CQueryController1.setQueryModel index, query + me.CQueryController1.setFilteredQuery new CQueryModel(d, f) + +End Sub + +CFilterController.setSortDirection: +Sub setSortDirection(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.sortDirection = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setSortColumn: +Sub setSortColumn(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.sortColumn = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setNeedsSort: +Sub setNeedsSort() + + me.needsSort = true + +End Sub + +CFilterController.Constructor: +Sub Constructor() + + me.currentFilter = new CFilterModel + +End Sub + +CFilterController.toggleFilterEnabled: +Sub toggleFilterEnabled() + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.enabled = not me.currentFilter.enabled + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setSpeedFilter: +Sub setSpeedFilter(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.speed = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setSourcesFilter: +Sub setSourcesFilter(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.sources = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.setFilterModel: +Sub setFilterModel() + + if me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter = me.CQueryController1.getFilterModel() + +End Sub + +CFilterController.statsUpdated: +Sub statsUpdated() + + //* query result stack *// + + if me.needsSort then + me.needsSort = false + me.updateResults + + end + +End Sub + +CFilterController.ignoreResults: +Sub ignoreResults(selectedItems as dictionary) + + if me.currentFilter = nil or me.CQueryController1 = nil then return + + dim index as integer = me.CQueryController1.getCurrentIndex + + if me.CQueryController1.hasQueryModel(index) = false then return + + dim i, k as integer + dim query as CQueryModel = me.CQueryController1.getQueryModel(index) + dim o as CStatsModel + dim c as CResponseModel + dim d(-1) as CResponseModel + dim f as new dictionary + + for i = ubound(query.response.representedObjects) downto 0 + + c = CResponseModel(query.response.representedObjects(i)) + + if selectedItems.hasKey(c.getRepresentation) then _ + query.response.representedObjects.remove i + + next + + query.response.rehash + + for each o in query.response.representedObjects + + c = CResponseModel(o) + + if me.isFilteredResponse(c) then + d.append c + f.value(c.sha1) = k + k = k + 1 + + end + + next + + me.CQueryController1.setQueryModel index, query + me.CQueryController1.setFilteredQuery new CQueryModel(d, f) + +End Sub + +CFilterController.setScrollPosition: +Sub setScrollPosition(value as integer) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.scrollPosition = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.updateFilter: +Sub updateFilter() + + if me.currentFilter = nil then return + + filterChanged me.currentFilter + +End Sub + +CFilterController.isFilteredResponse: +Function isFilteredResponse(c as CResponseModel, filter as CFilterModel) As boolean + + return (c.spam = false or kAqSpamFilter = false) and _ + ((filter.enabled = false) or _ + (filter.media = 0 or filter.media = c.mediaType) and _ + (filter.bitrate <= c.bitrate) and _ + (filter.size <= c.fileSize) and _ + (filter.sources <= c.sources) and _ + (filter.speed <= c.speed) and _ + (filter.keyword.lenb = 0 or _ + c.fileName.lowercase.instrb(filter.keyword) <> 0 or _ + c.artist.lowercase.instrb(filter.keyword) <> 0 or _ + c.album.lowercase.instrb(filter.keyword) <> 0 or _ + c.title.lowercase.instrb(filter.keyword) <> 0)) + +End Function + +CFilterController.setColumnWidths: +Sub setColumnWidths(value as string) + + if me.currentFilter = nil or me.CQueryController1 = nil or me.CQueryController1.getCurrentIndex = -1 then return + + me.currentFilter.columnWidths = value + me.CQueryController1.setFilterModel new CFilterModel(me.currentFilter) + +End Sub + +CFilterController.getFilterModel: +Function getFilterModel() As CFilterModel + return me.currentFilter +End Function + +CiTunesController.launchiTunes: +Function launchiTunes() As Boolean + + #if targetMacOS + if me.getPlayerState <> -1 then return true + + dim ae as AppleEvent + + ae = NewAppleEvent("aevt", "odoc", "MACS") + ae.ObjectSpecifierParam("----") = GetUniqueIDObjectDescriptor("appf", nil, "hook") + + return ae.Send + + #endif + +End Function + +CiTunesController.pause: +Function pause() As Boolean + + #if targetMacOS + dim ae as AppleEvent + + ae = NewAppleEvent("hook", "Paus", "hook") + + return ae.Send + + #elseif targetWin32 + try + new OLEObject("iTunes.Application").Pause + return true + + catch + + end + + #endif + +End Function + +CiTunesController.play: +Function play(track As variant) As Boolean + + #if targetMacOS + dim ae as AppleEvent + dim obj1, obj2 as AppleEventObjectSpecifier + + obj1 = GetStringComparisonObjectDescriptor("= ", "prop", "pDID", track) + obj2 = GetIndexedObjectDescriptor("cLiP", nil, 1) + obj2 = GetTestObjectDescriptor("cTrk", obj2, obj1) + + ae = NewAppleEvent("hook", "Play", "hook") + ae.ObjectSpecifierParam("----") = obj2 + + return ae.Send + + #elseif targetWin32 + try + OLEObject(track.objectValue).Play + return true + + catch + + end + + #endif + +End Function + +CiTunesController.getPlayerState: +Function getPlayerState() As Integer + + #if targetMacOS + dim ae as AppleEvent + + ae = NewAppleEvent("core", "getd", "hook") + ae.ObjectSpecifierParam("----") = GetPropertyObjectDescriptor(nil, "pPlS") + + if ae.Send then + + if StrComp(ae.ReplyString, "kPSp", 0) = 0 then // paused + return 2 + + Elseif StrComp(ae.ReplyString, "kPSP", 0) = 0 then // playing + return 1 + + Elseif StrComp(ae.ReplyString, "kPSS", 0) = 0 then // stopped + return 0 + + end + + end + + return -1 + + #elseif targetWin32 + try + return new OLEObject("iTunes.Application").PlayerState + + catch + + end + + + #endif + +End Function + +CiTunesController.makePlaylist: +Function makePlaylist(playlist As String) As variant + + #if targetMacOS + dim ae as AppleEvent + dim rec as AppleEventRecord + + rec = New AppleEventRecord + rec.StringParam("pnam") = playlist.convertEncoding(Encodings.systemDefault) + + ae = NewAppleEvent("core", "crel", "hook") + ae.RecordParam("prdt") = rec + ae.MacTypeParam("kocl") = "cPly" + + if ae.Send then return ae.ReplyInteger + + return -1 + + #elseif targetWin32 + try + new OLEObject("iTunes.Application").CreatePlaylist playlist + return true + + catch + + end + + #endif + +End Function + +CiTunesController.getPlaylistIndex: +Function getPlaylistIndex(Playlist As String) As Integer + + #if targetMacOS + dim ae as AppleEvent + dim obj as AppleEventObjectSpecifier + + obj = GetNamedObjectDescriptor("cPly", nil, Playlist.convertEncoding(Encodings.systemDefault)) + + ae = NewAppleEvent("core", "getd", "hook") + ae.ObjectSpecifierParam("----") = GetPropertyObjectDescriptor(obj, "pidx") + + if ae.Send then return ae.ReplyInteger + + return -1 + + #elseif targetWin32 + dim o as OLEObject + dim i, j as integer + + try + o = new OLEObject("iTunes.Application").LibrarySource.Playlists + j = o.count + + for i = 1 to j + + if o.Item(i).Name = Playlist then return i + + next + + catch + + end + + #endif + +End Function + +CiTunesController.addTrackToPlaylist: +Function addTrackToPlaylist(track as variant, Playlist As Variant) As variant + + #if targetMacOS + dim ae as AppleEvent + dim obj1 as AppleEventObjectSpecifier + dim obj2 as AppleEventObjectSpecifier + + obj1 = GetStringComparisonObjectDescriptor("= ", "prop", "pDID", track) + obj2 = GetIndexedObjectDescriptor("cLiP", nil, 1) + + ae = NewAppleEvent("core", "clon", "hook") + ae.ObjectSpecifierParam("----") = GetTestObjectDescriptor("cTrk", obj2, obj1) + ae.ObjectSpecifierParam("insh") = GetIndexedObjectDescriptor("cPly", nil, playlist) + + if ae.Send and ae.ReplyObjectSpecifier <> nil then + obj1 = ae.ReplyObjectSpecifier + + ae = NewAppleEvent("core", "getd", "hook") + ae.ObjectSpecifierParam("----") = GetPropertyObjectDescriptor(obj1, "pDID") + + if ae.Send then return ae.ReplyInteger + + end + + return -1 + + #elseif targetWin32 + dim o as OLEObject + dim v(1) as variant + + try + v(1) = track.objectValue + o = new OLEObject("iTunes.Application").LibrarySource.Playlists.ItemByName(Playlist.stringValue) + o = o.invoke("AddTrack", v) + return o + + catch + + end + + return nil + + #endif + +End Function + +CiTunesController.getCurrentTrackArtist: +Function getCurrentTrackArtist() As string + + #if targetMacOS + Dim ae As AppleEvent + Dim obj As AppleEventObjectSpecifier + + obj = GetPropertyObjectDescriptor( Nil, "pTrk" ) + + ae = NewAppleEvent( "core", "getd", "hook" ) + ae.ObjectSpecifierParam("----") = GetPropertyObjectDescriptor( obj, "pArt" ) + + if ae.Send then return ae.ReplyString.convertEncoding(Encodings.UTF8) + + #elseif TargetWin32 + try + return new OLEObject("iTunes.Application").CurrentTrack.Artist + + catch + + end + + #endif + +End Function + +CiTunesController.getCurrentTrackName: +Function getCurrentTrackName() As string + + #if targetMacOS + Dim ae As AppleEvent + Dim obj As AppleEventObjectSpecifier + + obj = GetPropertyObjectDescriptor( Nil, "pTrk" ) + + ae = NewAppleEvent( "core", "getd", "hook" ) + ae.ObjectSpecifierParam("----") = GetPropertyObjectDescriptor( obj, "pnam" ) + + if ae.Send then return ae.ReplyString.convertEncoding(Encodings.UTF8) + + #elseif TargetWin32 + try + return new OLEObject("iTunes.Application").CurrentTrack.Name + + catch + + end + + #endif + +End Function + +CiTunesController.addFileToLibrary: +Function addFileToLibrary(item As FolderItem) As variant + + #if targetMacOS + dim ae as AppleEvent + dim obj as AppleEventObjectSpecifier + + obj = GetIndexedObjectDescriptor("cLiP", nil, 1) + + ae = NewAppleEvent("hook", "Add ","hook") + ae.FolderItemParam("----") = item + ae.ObjectSpecifierParam("insh") = obj + + if ae.Send and ae.ReplyObjectSpecifier <> nil then + obj = ae.ReplyObjectSpecifier + + ae = NewAppleEvent("core", "getd", "hook") + ae.ObjectSpecifierParam("----") = GetPropertyObjectDescriptor(obj, "pDID") + + if ae.Send then return ae.ReplyInteger + + end + + return -1 + + #elseif targetWin32 + dim o as OLEObject + dim v(1) as variant + + try + v(1) = item.posixPath + o = new OLEObject("iTunes.Application").LibraryPlaylist.invoke("AddFile", v) + return o.Tracks.Item(o.Tracks.count) + + catch + + end + + return nil + + #endif + +End Function + +CiTunesController.play: +Function play(TrackID As variant, PlaylistIndex As integer) As Boolean + + #if targetMacOS + Dim ae As AppleEvent + Dim obj1, obj2 As AppleEventObjectSpecifier + + obj1 = GetStringComparisonObjectDescriptor("= ", "prop", "pDID", trackID) + obj2 = GetIndexedObjectDescriptor("cPly", nil, PlaylistIndex) + obj2 = GetTestObjectDescriptor("cTrk", obj2, obj1) + + ae = NewAppleEvent( "hook", "Play", "hook" ) + ae.ObjectSpecifierParam("----") = obj2 + + Return ae.Send + + #endif + +End Function + +CiTunesController.getPlaylistName: +Function getPlaylistName(index as integer) As string + + #if targetWin32 + try + return new OLEObject("iTunes.Application").LibrarySource.Playlists.Item(Index).Name + + catch + + end + + #endif + +End Function + +CLocalizationController.getLocalizedStringFromTable: +Function getLocalizedStringFromTable(key as string, tableName as string) As string + + if key.lenb = 0 then return "" + + #if debugBuild and targetMachO + if me.table.haskey(tableName) = false then me.table.value(tableName) = new dictionary + + if Dictionary(me.table.value(tableName)).hasKey(key) = false then Dictionary(me.table.value(tableName)).value(key) = key + + #endif + + if me.table.haskey(tableName) and Dictionary(me.table.value(tableName)).hasKey(key) then return Dictionary(me.table.value(tableName)).value(key) + + return key + +End Function + +CLocalizationController.Destructor: +Sub Destructor() + ' + '#if debugBuild and targetMachO + 'dim bs as binaryStream + 'dim d as dictionary + 'dim i, j, k as integer + 'dim fi as folderItem = getFolderItem("Contents").child("Resources").Child("English.lproj") + ' + 'for i = me.table.count - 1 downto 0 + ' + 'try + 'bs = fi.child(me.table.key(i) + ".strings").createBinaryFile("") + 'bs.write encodings.UTF16.chr(&hFEFF) + 'd = me.table.value(me.table.key(i)) + 'k = d.count - 1 + ' + 'for j = 0 to k + ' + 'bs.write convertEncoding("""" + d.key(j).replaceAllB("""", "\""").replaceAllB(EndOfLine, "\n") + """ = """ + d.value(d.key(j)).replaceAllB("""", "\""").replaceAllB(EndOfLine, "\n") + """;" + EndOfLine.UNIX, encodings.UTF16) + ' + 'next + ' + 'catch + ' + 'finally + 'if bs <> nil then bs.close + ' + 'end + ' + 'next + ' + '#endif + ' +End Sub + +CLocalizationController.loadLocalizedStrings: +Protected Sub loadLocalizedStrings(fi as folderItem) + + dim bom, tableName, raw, key, value as string + dim bs as binaryStream + dim r as new regex + dim m as regexmatch + dim i as integer + dim utf16bigbom as string = chrb(&hFE) + chrb(&hFF) + dim utf16littlebom as string = chrb(&hFF) + chrb(&hFE) + dim utf8bom as string = chrb(&hEF) + chrb(&hBB) + chrb(&hBF) + + r.searchpattern = """(.+)""\s*=\s*""(.*)"";" + + for i = fi.count downto 1 + + if strcomp(fi.item(i).name.rightb(8), ".strings", 0) = 0 then + tableName = fi.item(i).name.replaceb(".strings", "") + + try + bs = fi.item(i).openAsBinaryFile(false) + bom = bs.read(3) + + if strcomp(bom.leftB(2), utf16bigbom, 0) = 0 then + bs.position = 2 + #if targetWin32 or targetLinux or targetX86 'Intel + raw = bs.read(bs.length - 2).reverseEndian.convertEncoding(encodings.UTF8) + + #elseif targetMacOS 'PowerPC + raw = bs.read(bs.length - 2, encodings.UTF16).convertEncoding(encodings.UTF8) + + #endif + + elseif strcomp(bom.leftB(2), utf16littlebom, 0) = 0 then + bs.position = 2 + #if targetWin32 or targetLinux or targetX86 'Intel + raw = bs.read(bs.length - 2, encodings.UTF16).convertEncoding(encodings.UTF8) + + #elseif targetMacOS 'PowerPC + raw = bs.read(bs.length - 2).reverseEndian.convertEncoding(encodings.UTF8) + + #endif + + elseif strcomp(bom, utf8bom, 0) = 0 then + bs.position = 3 + raw = bs.read(bs.length - 3, encodings.UTF8) + + else + bs.position = 0 + raw = bs.read(bs.length, encodings.UTF8) + + end + + me.table.value(tableName) = new dictionary + m = r.search(raw) + + while m <> nil + + key = m.SubExpressionString(1).replaceAllB("\""", """").replaceAllB("\n", EndOfLine) + value = m.SubExpressionString(2).replaceAllb("\""", """").replaceAllb("\n", EndOfLine) + + if strcomp(key, value, 0) <> 0 then _ + Dictionary(me.table.value(tableName)).value(key) = value + m = r.search(raw, m.subExpressionStartB(2) + m.subExpressionString(2).lenb) + + wend + + catch + + finally + if bs <> nil then bs.close + + end + + end + + next + +End Sub + +CLocalizationController.Constructor: +Sub Constructor() + + me.table = new dictionary + + dim fi as folderItem + + //* find .lproj folder for current language *// + + #if debugBuild and targetMachO + 'dim MainBundle as new CFBundle(new CFURL(getFolderItem(""))) + 'dim locArray as CFArray = MainBundle.Localizations + 'dim preferLoc as CFArray = MainBundle.PreferredLocalizations(locArray) + 'dim currentLanguage as string = new CFString(preferLoc.value(0)) + ' + 'try + 'fi = getFolderItem("Contents").child("Resources").child(currentLanguage + ".lproj") + ' + 'catch + ' + 'end + + #elseif targetMachO + dim MainBundle as new CFBundle + dim locArray as CFArray = MainBundle.Localizations + dim preferLoc as CFArray = MainBundle.PreferredLocalizations(locArray) + dim currentLanguage as string = new CFString(preferLoc.value(0)) + + try + fi = App.ExecutableFile.parent.parent.child("Resources").child(currentLanguage + ".lproj") + + catch + + end + + #elseif targetCarbon + Declare Function GetScriptVariable lib kCarbon (script as short, selector as short) as short + Declare Function GetScriptManagerVariable lib kCarbon (selector as short) as short + Declare Function LocaleRefFromLangOrRegionCode lib kCarbon (LangCode as short, RegionCode as short, LocaleRef as Integer) as short + Declare Function LocaleRefGetPartString lib kCarbon (locale as Integer, partMask as Integer, maxStringLen as short, partString as Ptr) as short + + dim languageCode, regionCode, error as integer + dim str255 as new MemoryBlock(255) + dim localeRef as Integer + + const kSystemScript = -1 + const kCurrentLanguage = 28 + const smRegionCode = 40 + const kLocaleAllPartsMask = &h0000003F + + languageCode = GetScriptVariable(kSystemScript, kCurrentLanguage) + regionCode = GetScriptManagerVariable(smRegionCode) + error = LocaleRefFromLangOrRegionCode(languageCode, regionCode, localeRef) + error = LocaleRefGetPartString(localeRef, kLocaleAllPartsMask, str255.Size, str255) + + dim d as new Dictionary + + //* A *// + + d.value(0) = "English" + d.value(1) = "French" + d.value(2) = "German" + d.value(3) = "Italian" + d.value(4) = "Dutch" + d.value(5) = "Swedish" + d.value(6) = "Spanish" + d.value(7) = "Danish" + d.value(8) = "Portuguese" + d.value(9) = "Norwegian" + d.value(10) = "Hebrew" + d.value(11) = "Japanese" + d.value(12) = "Arabic" + d.value(13) = "Finnish" + d.value(14) = "Greek" + d.value(15) = "Icelandic" + d.value(16) = "Maltese" + d.value(17) = "Turkish" + d.value(18) = "Croatian" + d.value(19) = "Traditional Chinese" + d.value(20) = "Urdu" + d.value(21) = "Hindi" + d.value(22) = "Thai" + d.value(23) = "Korean" + + //* B *// + + d.value(24) = "Lithuanian" + d.value(25) = "Polish" + d.value(26) = "Hungarian" + d.value(27) = "Estonian" + d.value(28) = "Lettish" + d.value(29) = "Sami" + d.value(30) = "Faroese" + d.value(31) = "Farsi" + d.value(31) = "Persian" + d.value(32) = "Russian" + d.value(33) = "Simplified Chinese" + d.value(34) = "Flemish" + d.value(35) = "Irish Gaelic" + d.value(36) = "Albanian" + d.value(37) = "Romanian" + d.value(38) = "Czech" + d.value(39) = "Slovak" + d.value(40) = "Slovenian" + d.value(41) = "Yiddish" + d.value(42) = "Serbian" + d.value(43) = "Macedonian" + d.value(44) = "Bulgarian" + d.value(45) = "Ukrainian" + d.value(46) = "Byelorussian" + + try + fi = App.executableFile.parent.child("Contents").child("Resources").child(str255.CString(0) + ".lproj") + + if fi.exists = false then _ + fi = App.executableFile.parent.child("Contents").child("Resources").child(str255.CString(0).leftb(2) + ".lproj") + + if fi.exists = false then _ + fi = App.executableFile.parent.child("Contents").child("Resources").child(d.value(languageCode) + ".lproj") + + catch + + end + + #elseif targetWin32 + Declare Function GetLocaleInfoA Lib "kernel32" (Locale As integer, LCType As integer, lpLCData As ptr, cchData As integer) As Integer + + dim mb as memoryBlock + dim iso639, locale, english as string + + Const LOCALE_USER_DEFAULT = &H400 + Const LOCALE_SISO639LANGNAME = &H59 + Const LOCALE_SISO3166CTRYNAME = &H5A + Const LOCALE_SENGLANGUAGE = &H1001 + + mb = new MemoryBlock( 256 ) + call GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, mb, mb.Size ) + iso639 = mb.CString( 0 ).defineEncoding(Encodings.UTF8) + + mb = new MemoryBlock( 256 ) + call GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, mb, mb.Size ) + locale = iso639 + "_" + mb.CString( 0 ).defineEncoding(Encodings.UTF8) + + mb = new MemoryBlock( 256 ) + call GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SENGLANGUAGE, mb, mb.Size ) + english = mb.CString( 0 ).defineEncoding(Encodings.UTF8) + + try + fi = App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child(iso639 + ".lproj") + + if fi.exists = false then _ + fi = App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child(locale + ".lproj") + + if fi.exists = false then _ + fi = App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child(english + ".lproj") + + catch + + end + + #elseif targetLinux + 'todo + + #endif + + if fi <> nil and fi.exists then + me.loadLocalizedStrings fi + end + +End Sub + +CActionsController.actionHeading: +Protected Sub actionHeading(item as string) + + dim i as integer + + if item = getLocalizedString("Reset to Default", "ContextualMenu") then + me.receiver.setColumnWidths me.receiver.getInitialColumnWidths + me.receiver.headingIndex = -1 + + if me.receiver isa CResponseListBox then + me.CFilterController1.setColumnWidths me.receiver.columnWidths + me.CFilterController1.setSortColumn -1 + me.CFilterController1.setSortDirection ListBox.sortAscending + + end + + return + + else + item = item.replaceb(kChecked, "").replaceb(kUnchecked, "") + + for i = me.receiver.columnCount - 1 downto 0 + + if me.receiver.heading(i) = item then + if me.receiver.column(i).widthExpression = "0%" then + me.receiver.column(i).userResizable = true + me.receiver.column(i).widthExpression = _ + me.receiver.getInitialColumnWidths.nthField(",", i + 1).trim + + else + me.receiver.column(i).userResizable = false + me.receiver.column(i).widthExpression = "0%" + + end + + me.receiver.columnWidths = me.receiver.columnWidths + if me.receiver isa CResponseListBox then + me.CFilterController1.setColumnWidths me.receiver.columnWidths + end + return + + end + + next + + end + +End Sub + +CActionsController.openHeadingMenu: +Sub openHeadingMenu(sender as CStatsListBox) + + dim i, j as integer + + try + me.actionType = 1 //* heading *// + me.receiver = sender + me.receiver.setFocus + j = me.receiver.columnCount - 1 + + for i = 0 to j + + if me.receiver.column(i).MaxWidthExpression <> me.receiver.column(i).MinWidthExpression then + if me.receiver.column(i).WidthExpression = "0%" then + me.addRow kUnchecked + me.receiver.heading(i) + + else + me.addRow kChecked + me.receiver.heading(i) + + end + + end + + next + + me.addSeparator + me.addRow getLocalizedString("Reset to Default", "ContextualMenu") + me.open + + catch + + finally + me.deleteAllRows + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.openNetworkMenu: +Sub openNetworkMenu(sender as CStatsListBox) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 2 //* network *// + me.receiver = sender + me.receiver.setFocus + + select case me.receiver.selCount + + case 0 + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + case 1 + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + addBrowseHostFromNetwork me.receiver.listIndex, items() + + if ubound(items) = 0 then + me.addSeparator + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(0)) + + end + + else + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromNetwork i, items() + + next + + j = ubound(items) + + if j <> -1 then + me.addSeparator + + end + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + end + + me.open + + catch + + finally + me.deleteAllRows + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.actionNetwork: +Protected Sub actionNetwork(item as string) + + dim i, j as integer + dim items(-1) as string + + select case item + + case getLocalizedString("Remove", "ContextualMenu") + actionNetworkRemove me.receiver + + case getLocalizedString("Remove All", "ContextualMenu") + me.receiver.selectAll + actionNetworkRemove me.receiver + + case getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromNetwork i, items() + + next + + j = ubound(items) + + for i = 0 to j + + me.CQueryController1.handleQueryBrowse items(i) + + next + + else + me.CQueryController1.handleQueryBrowse _ + item.replaceb(getLocalizedStringWithStringData("Browse %@", "ContextualMenu", ""), "") + + end + +End Sub + +CActionsController.openSidebarMenu: +Sub openSidebarMenu(sender as CStatsListBox) + + try + me.actionType = 3 //* sidebar *// + me.receiver = sender + me.receiver.setFocus + + if me.receiver.listIndex <> -1 then + if me.receiver.selcount <> 1 then + + elseif CStatsModel(me.receiver.dataSource(me.receiver.listIndex)).getRepresentation < 0 then + me.addRow getLocalizedString("Start Query", "ContextualMenu") + + if me.CQueryController1.getKeepInSidebar(CStatsModel(me.receiver.dataSource(me.receiver.listIndex)).getRepresentation) = false then _ + me.addRow getLocalizedString("Keep in Sidebar", "ContextualMenu") + + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addSeparator + + else + me.addRow getLocalizedString("Stop Query", "ContextualMenu") + + if me.CQueryController1.getKeepInSidebar(CStatsModel(me.receiver.dataSource(me.receiver.listIndex)).getRepresentation) = false then _ + me.addRow getLocalizedString("Keep in Sidebar", "ContextualMenu") + + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addSeparator + + end + + if me.receiver.selcount <> 1 then + me.addRow getLocalizedString("Clear All Results and Restart Query", "ContextualMenu") + me.addRow getLocalizedString("Clear All Results", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addSeparator + + elseif me.CQueryController1.getResponseCount <> 0 then + me.addRow getLocalizedString("Clear All Results and Restart Query", "ContextualMenu") + me.addRow getLocalizedString("Clear All Results", "ContextualMenu") + me.addSeparator + + end + + end + + me.addRow getLocalizedString("Remove All Queries", "ContextualMenu") + me.open + + catch + + finally + me.deleteAllRows + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.actionSidebar: +Protected Sub actionSidebar(item as string) + + dim i as integer + + select case item + + case getLocalizedString("Start Query", "ContextualMenu") + me.CQueryController1.startQuery false + + case getLocalizedString("Stop Query", "ContextualMenu") + me.CQueryController1.stopQuery' CStatsModel(me.receiver.dataSource(me.receiver.listIndex)).getRepresentation + + case getLocalizedString("Keep in Sidebar", "ContextualMenu") + me.CQueryController1.setKeepInSidebar CStatsModel(me.receiver.dataSource(me.receiver.listIndex)).getRepresentation, true + + case getLocalizedString("Remove", "ContextualMenu") + actionSidebarRemove me.receiver + + case getLocalizedString("Clear All Results and Restart Query", "ContextualMenu") + for i = me.receiver.listCount - 1 downto 0 + + if me.receiver.selected(i) then + me.CQueryController1.clearAllResults CStatsModel(me.receiver.dataSource(i)).getRepresentation + me.CQueryController1.startQuery CStatsModel(me.receiver.dataSource(i)).getRepresentation, false + + end + + next + + case getLocalizedString("Clear All Results", "ContextualMenu") + for i = me.receiver.listCount - 1 downto 0 + + if me.receiver.selected(i) then + me.CQueryController1.clearAllResults CStatsModel(me.receiver.dataSource(i)).getRepresentation + + end + + next + + case getLocalizedString("Remove All Queries", "ContextualMenu") + me.CQueryController1.removeAllQueries + + end + +End Sub + +CActionsController.openResponseMenu: +Sub openResponseMenu(sender as CStatsListBox) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 4 //* query results *// + me.receiver = sender + me.receiver.setFocus + + select case me.receiver.selCount + + case 0 + me.addRow getLocalizedString("Clear All Results", "ContextualMenu") + + case 1 + me.addRow getLocalizedString("Download", "ContextualMenu") + + if me.CQueryController1.hasQueryString(me.receiver.helpTag) = false then + me.addSeparator + me.addRow getLocalizedString("Find More Sources", "ContextualMenu") + end + + me.addSeparator + #if targetMachO or targetWin32 or targetLinux + me.addRow getLocalizedString("Mark As Spam", "ContextualMenu") + if kAqSpamFilter = false then _ + me.addRow getLocalizedString("Mark As Not Spam", "ContextualMenu") + me.addSeparator + #endif + + me.addRow getLocalizedString("Clear All Results", "ContextualMenu") + + addBrowseHostFromResponse(me.receiver.listIndex, items()) + j = ubound(items) + + if j <> -1 then me.addSeparator + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + else + me.addRow getLocalizedString("Download", "ContextualMenu") + + me.addSeparator + #if targetMachO or targetWin32 or targetLinux + me.addRow getLocalizedString("Mark As Spam", "ContextualMenu") + if kAqSpamFilter = false then _ + me.addRow getLocalizedString("Mark As Not Spam", "ContextualMenu") + me.addSeparator + + #endif + + me.addRow getLocalizedString("Clear All Results", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then addBrowseHostFromResponse(i, items()) + + next + + j = ubound(items) + + if j <> -1 then me.addSeparator + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + end + + me.open + + catch + + finally + me.deleteAllRows + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.addBrowseHostFromResponse: +Protected Sub addBrowseHostFromResponse(index as integer, byref items() as string) + + dim c as CResponseModel = me.CQueryController1.getResponseModel(index) + + if c = nil then return + + dim i, j as integer + + j = ubound(c.address) + + for i = 0 to j + + if c.isBrowseHostEnabled(i) and _ + items.indexOf(c.address(i)) = -1 and _ + me.CQueryController1.hasQueryString(c.address(i)) = false then _ + items.append c.address(i) + + next + + items.sort + +End Sub + +CActionsController.actionResponse: +Protected Sub actionResponse(item as string) + + dim i, j as integer + dim arg, items(-1) as string + + select case item + + case getLocalizedString("Download", "ContextualMenu") + actionResponseDownload me.receiver + + case getLocalizedString("Mark As Spam", "ContextualMenu") + actionResponseSpam me.receiver + + case getLocalizedString("Mark As Not Spam", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then + me.CCoreController1.sendCommand "removeSpamFiles|" + me.CQueryController1.getLocalIndexes(i) + me.CQueryController1.setQuerySpam(i, false) + + end + + next + + me.CCoreController1.sendCommand "applyFilterSettings" + me.CFilterController1.filterResults + + case getLocalizedString("Clear All Results", "ContextualMenu") + me.CQueryController1.clearAllResults + + case getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + if me.receiver.selected(i) then addBrowseHostFromResponse i, items() + + next + + j = ubound(items) + + for i = 0 to j + + CQueryController1.handleQueryBrowse items(i) + + next + + case getLocalizedString("Find More Sources", "ContextualMenu") + me.CQueryController1.handleQueryFindMoreSources me.receiver.helpTag.split(EndOfLine).top + + else + me.CQueryController1.handleQueryBrowse _ + item.replaceb(getLocalizedStringWithStringData("Browse %@", "ContextualMenu", ""), "") + + end + +End Sub + +CActionsController.actionResponseDownload: +Sub actionResponseDownload(targetListBox as CListBox) + + dim i, j as integer + + j = targetListBox.listCount - 1 + + for i = 0 to j + + if targetListBox.selected(i) then + me.CCoreController1.sendCommand "download|" + me.CQueryController1.getLocalIndexes(i) + me.CQueryController1.setQueryMarked(i, true) + + end + + next + + me.CQueryController1.flush + +End Sub + +CActionsController.openDownloadsMenu: +Sub openDownloadsMenu(sender as CStatsListBox) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 5 //* downloads *// + me.receiver = sender + me.receiver.setFocus + + select case me.receiver.selCount + + case 0 + me.addRow getLocalizedString("Clear All Completed", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + case 1 + me.addRow getLocalizedString("Open", "ContextualMenu") + me.addRow getLocalizedString("Open With...", "ContextualMenu") + me.addRow getLocalizedString("Reveal in Finder", "ContextualMenu") + + //* if not completed *// + + if me.CDownloadsController1.isCompletedTransferItem(me.receiver.listIndex) = false then + me.addSeparator + me.addRow getLocalizedString("Resume", "ContextualMenu") + if me.CQueryController1.hasQueryString(me.receiver.helpTag) = false then _ + me.addRow getLocalizedString("Find More Sources", "ContextualMenu") + + end + + me.addSeparator + me.addRow getLocalizedString("Clear All Completed", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + addBrowseHostFromDownloads me.receiver.listIndex, items() + j = ubound(items) + + if j <> -1 then me.addSeparator + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + else //* if not completed *// + me.addRow getLocalizedString("Resume", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Clear All Completed", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromDownloads i, items() + + next + + j = ubound(items) + + if j <> -1 then me.addSeparator + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + end + + me.open + + catch + + finally + me.deleteAllRows + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.openUploadsMenu: +Sub openUploadsMenu(sender as CStatsListBox) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 6 //* uploads *// + me.receiver = sender + me.receiver.setFocus + + select case me.receiver.selCount + + case 0 + me.addRow getLocalizedString("Clear All Completed", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + case 1 + me.addRow getLocalizedString("Open", "ContextualMenu") + me.addRow getLocalizedString("Open With...", "ContextualMenu") + me.addRow getLocalizedString("Reveal in Finder", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Clear All Completed", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addRow getLocalizedString("Remove All", "ContextualMenu") + addBrowseHostFromUploads me.receiver.listIndex, items() + j = ubound(items) + + if j <> -1 then me.addSeparator + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + else //* if not completed *// + me.addRow getLocalizedString("Clear All Completed", "ContextualMenu") + me.addSeparator + me.addRow getLocalizedString("Remove", "ContextualMenu") + me.addRow getLocalizedString("Remove All", "ContextualMenu") + + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromUploads i, items() + + next + + j = ubound(items) + + if j <> -1 then me.addSeparator + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + end + + me.open + + catch + + finally + me.deleteAllRows + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.actionDownloads: +Protected Sub actionDownloads(item as string) + + dim fi(1) as folderItem + dim path, items(-1) as string + dim i, j as integer + dim hasActiveTransfers as boolean + + select case item + + case getLocalizedString("Open", "ContextualMenu") + actionDownloadsOpen me.receiver + + case getLocalizedString("Open With...", "ContextualMenu") + if kAqWarnOpening = false or me.CDownloadsController1.isCompletedTransferItem(me.receiver.listIndex) or askOpening then + path = me.CDownloadsController1.getTransferPath(me.receiver.listIndex) + + if path.lenB <> 0 then fi(0) = getPath2FolderItem(path) + + fi(1) = getOpenFolderItem("application/executable") + + if fi(0) <> nil and fi(0).exists and fi(1) <> nil and fi(1).exists then _ + fi(0).openWith(fi(1)) + + end + + case getLocalizedString("Reveal in Finder", "ContextualMenu") + actionDownloadsRevealInFinder me.receiver + + case getLocalizedString("Pause", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) and _ + me.CDownloadsController1.isCompletedTransferItem(i) = false then _ + me.CCoreController1.sendCommand "pauseDownload|" + me.CDownloadsController1.getTransferHashCode(i) + + next + + case getLocalizedString("Resume", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + if me.receiver.selected(i) and _ + me.CDownloadsController1.isCompletedTransferItem(i) = false then _ + me.CCoreController1.sendCommand "retryDownload|" + me.CDownloadsController1.getTransferHashCode(i) + next + + case getLocalizedString("Find More Sources", "ContextualMenu") + if me.CDownloadsController1.isCompletedTransferItem(me.receiver.listIndex) = false then _ + me.CQueryController1.handleQueryFindMoreSources me.CDownloadsController1.getTransferFileName(me.receiver.listIndex) + + case getLocalizedString("Clear All Completed", "ContextualMenu") + for i = me.receiver.listCount - 1 downto 0 + if me.CDownloadsController1.isCompletedTransferItem(i) then _ + me.CDownloadsController1.remove(i) + next + + me.CDownloadsController1.statsUpdated + + case getLocalizedString("Remove", "ContextualMenu") + actionDownloadsRemove me.receiver + + case getLocalizedString("Remove All", "ContextualMenu") + me.receiver.selectAll + actionDownloadsRemove me.receiver + + case getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + if me.receiver.selected(i) then addBrowseHostFromDownloads i, items() + next + + j = ubound(items) + + for i = 0 to j + me.CQueryController1.handleQueryBrowse items(i) + next + + else //* browse one selected host *// + me.CQueryController1.handleQueryBrowse _ + item.replaceb(getLocalizedStringWithStringData("Browse %@", "ContextualMenu", ""), "") + + end + +End Sub + +CActionsController.addBrowseHostFromDownloads: +Protected Sub addBrowseHostFromDownloads(index as integer, byref items() as string) + + dim i, j as integer + dim elements(-1) as string = _ + me.CDownloadsController1.getDownloadHosts(index).split(",") + + j = ubound(elements) - 1 + + for i = 0 to j + + if items.indexOf(elements(i)) = -1 and _ + me.CQueryController1.hasQueryString(elements(i)) = false then _ + items.append elements(i) + + next + + items.sort + +End Sub + +CActionsController.addBrowseHostFromUploads: +Protected Sub addBrowseHostFromUploads(index as integer, byref items() as string) + + dim element as string = me.CUploadsController1.getUploadIPAndPort(index) + + if element.lenB <> 0 and _ + items.indexOf(element) = -1 and _ + me.CQueryController1.hasQueryString(element) = false then _ + items.append element + + items.sort + +End Sub + +CActionsController.actionUploads: +Protected Sub actionUploads(item as string) + + dim fi(1) as folderItem + dim path, items(-1) as string + dim i, j as integer + + select case item + + case getLocalizedString("Open", "ContextualMenu") + actionUploadsOpen me.receiver + + case getLocalizedString("Open With...", "ContextualMenu") + path = me.CUploadsController1.getTransferPath(me.receiver.listIndex) + + if path.lenB <> 0 then _ + fi(0) = getPath2FolderItem(path) + + fi(1) = getOpenFolderItem("application/executable") + + if fi(0) <> nil and fi(0).exists and fi(1) <> nil and fi(1).exists then _ + fi(0).openWith(fi(1)) + + case getLocalizedString("Reveal in Finder", "ContextualMenu") + actionUploadsRevealInFinder me.receiver + + case getLocalizedString("Clear All Completed", "ContextualMenu") + for i = me.receiver.listCount - 1 downto 0 + + if me.CUploadsController1.isCompletedTransferItem(i) then _ + me.CUploadsController1.remove(i) + + next + + me.CUploadsController1.statsUpdated + + case getLocalizedString("Remove", "ContextualMenu") + actionUploadsRemove me.receiver + + case getLocalizedString("Remove All", "ContextualMenu") + me.receiver.selectAll + actionUploadsRemove me.receiver + + case getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromUploads i, items() + + next + + j = ubound(items) + + for i = 0 to j + + me.CQueryController1.handleQueryBrowse items(i) + + next + + else //* browse one selected host *// + me.CQueryController1.handleQueryBrowse _ + item.replaceb(getLocalizedStringWithStringData("Browse %@", "ContextualMenu", ""), "") + + end + +End Sub + +CActionsController.actionDownloadsRevealInFinder: +Sub actionDownloadsRevealInFinder(targetListBox as CListBox) + + me.CDownloadsController1.getTransferPath(targetListBox.listIndex).revealInFinder + +End Sub + +CActionsController.actionDownloadsOpen: +Sub actionDownloadsOpen(targetListBox as CListBox) + + if kAqWarnOpening = false or me.CDownloadsController1.isCompletedTransferItem(targetListBox.listIndex) or askOpening then _ + me.CDownloadsController1.getTransferPath(targetListBox.listIndex).open + +End Sub + +CActionsController.actionDownloadsRemove: +Sub actionDownloadsRemove(targetListBox as CListBox) + + dim i as integer + dim hasActiveTransfers as boolean + + for i = targetListBox.listCount - 1 downto 0 + + if targetListBox.selected(i) and _ + me.CDownloadsController1.isCompletedTransferItem(i) = false then + hasActiveTransfers = true + exit + + end + + next + + if kAqWarnDownloads and hasActiveTransfers and askRemoving = false then return + + for i = targetListBox.listCount - 1 downto 0 + + if targetListBox.selected(i) then + if me.CDownloadsController1.isCompletedTransferItem(i) then + me.CDownloadsController1.remove(i) + + elseif me.CDownloadsController1.setCanceled(i) then + me.CCoreController1.sendCommand "cancelDownload|" + me.CDownloadsController1.getTransferHashCode(i) + + end + + end + + next + + me.CDownloadsController1.statsUpdated + +End Sub + +CActionsController.actionNetworkRemove: +Sub actionNetworkRemove(targetListBox as CListBox) + + dim i as integer + + for i = targetListBox.listCount - 1 downto 0 + + if targetListBox.selected(i) then _ + me.CCoreController1.sendCommand "closeConnection|" + me.CNetworkController1.getHostAndPort(i).replace(":", "|") + + next + +End Sub + +CActionsController.openDownloadsMenu: +Sub openDownloadsMenu(sender as CStatsListBox, item as string) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 5 //* downloads *// + me.receiver = sender + me.receiver.setFocus + + select case item + + case getLocalizedString("Browse", "Toolbar") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromDownloads i, items() + + next + + j = ubound(items) + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + if j <> -1 then + me.open + me.deleteAllRows + + end + + case getLocalizedString("Remove", "Toolbar") + if me.receiver.selCount <> 0 then _ + actionDownloads getLocalizedString("Remove", "ContextualMenu") + + case getLocalizedString("Clear", "Toolbar") + actionDownloads getLocalizedString("Clear All Completed", "ContextualMenu") + + case getLocalizedString("Reveal", "Toolbar") + if me.receiver.selCount = 1 then _ + actionDownloads getLocalizedString("Reveal in Finder", "ContextualMenu") + + case getLocalizedString("Resume", "Toolbar") + if me.receiver.selCount > 0 then _ + actionDownloads getLocalizedString("Resume", "ContextualMenu") + + case getLocalizedString("Pause", "Toolbar") + if me.receiver.selCount > 0 then _ + actionDownloads getLocalizedString("Pause", "ContextualMenu") + + end + + catch + + finally + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.openNetworkMenu: +Sub openNetworkMenu(sender as CStatsListBox, item as string) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 2 //* network *// + me.receiver = sender + me.receiver.setFocus + + select case item + + case getLocalizedString("Browse", "Toolbar") + if me.receiver.selcount > 0 then + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromNetwork i, items() + + next + + j = ubound(items) + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + if j <> -1 then + me.open + me.deleteAllRows + + end + + end + + case getLocalizedString("Remove", "Toolbar") + if me.receiver.selcount > 0 then _ + actionNetwork getLocalizedString("Remove", "ContextualMenu") + + end + + catch + + finally + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.openResponseMenu: +Sub openResponseMenu(sender as CStatsListBox, item as string) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 4 //* query results *// + me.receiver = sender + me.receiver.setFocus + + select case item + + case getLocalizedString("Browse", "Toolbar") + if me.receiver.selCount > 0 then + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then addBrowseHostFromResponse(i, items()) + + next + + j = ubound(items) + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + if j <> -1 then + me.open + me.deleteAllRows + + end + + end + + case getLocalizedString("Download", "Toolbar") + if me.receiver.selCount > 0 then _ + actionResponse getLocalizedString("Download", "ContextualMenu") + + case getLocalizedString("Filter", "Toolbar") + me.actionResponseFilterResults + + end + + catch + + finally + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.openUploadsMenu: +Sub openUploadsMenu(sender as CStatsListBox, item as string) + + dim i, j as integer + dim items(-1) as string + + try + me.actionType = 6 //* uploads *// + me.receiver = sender + me.receiver.setFocus + + select case item + + case getLocalizedString("Browse", "Toolbar") + j = me.receiver.listCount - 1 + + for i = 0 to j + + if me.receiver.selected(i) then _ + addBrowseHostFromUploads i, items() + + next + + j = ubound(items) + + for i = 0 to j + + me.addRow getLocalizedStringWithStringData("Browse %@", "ContextualMenu", items(i)) + + next + + if j > 0 then + me.addSeparator + me.addRow getLocalizedString("Browse All Selected Hosts", "ContextualMenu") + + end + + if j <> -1 then + me.open + me.deleteAllRows + + end + + case getLocalizedString("Remove", "Toolbar") + if me.receiver.selCount > 0 then _ + actionUploads getLocalizedString("Remove", "ContextualMenu") + + case getLocalizedString("Clear", "Toolbar") + actionUploads getLocalizedString("Clear All Completed", "ContextualMenu") + + case getLocalizedString("Reveal", "Toolbar") + if me.receiver.selCount = 1 then _ + actionUploads getLocalizedString("Reveal in Finder", "ContextualMenu") + + end + + catch + + finally + me.actionType = 0 //* initialize *// + me.receiver = nil + + end + +End Sub + +CActionsController.actionSidebarRemove: +Sub actionSidebarRemove(targetListBox as CStatsListBox) + + dim i as integer + + for i = targetListBox.listCount - 1 downto 0 + + if targetListBox.selected(i) then _ + me.CQueryController1.removeQuery CStatsModel(targetListBox.dataSource(i)).getRepresentation + + next + + targetListBox.listIndex = -1 + +End Sub + +CActionsController.Initialize: +Sub Initialize(core as CCoreController, query as CQueryController, filter as CFilterController, network as CNetworkController, downloads as CDownloadsController, uploads as CUploadsController) + + me.CCoreController1 = core + me.CQueryController1 = query + me.CFilterController1 = filter + me.CNetworkController1 = network + me.CDownloadsController1 = downloads + me.CUploadsController1 = uploads + +End Sub + +CActionsController.addBrowseHostFromNetwork: +Protected Sub addBrowseHostFromNetwork(index as integer, byref items() as string) + + dim browseHost as string = me.CNetworkController1.getHostAndPort(index) + + if items.indexOf(browseHost) = -1 and _ + me.CQueryController1.hasQueryString(browseHost) = false then _ + items.append browseHost + + items.sort + +End Sub + +CActionsController.actionUploadsRevealInFinder: +Sub actionUploadsRevealInFinder(targetListBox as CListBox) + + me.CUploadsController1.getTransferPath(targetListBox.listIndex).revealInFinder + +End Sub + +CActionsController.actionUploadsRemove: +Sub actionUploadsRemove(targetListBox as CListBox) + + dim i as integer + + for i = targetListBox.listCount - 1 downto 0 + + if targetListBox.selected(i) then + + if me.CUploadsController1.isCompletedTransferItem(i) then + me.CUploadsController1.remove(i) + + elseif me.CUploadsController1.setCanceled(i) then + me.CCoreController1.sendCommand "cancelUpload|" + me.CUploadsController1.getTransferHashCode(i) + + end + + end + + next + + me.CUploadsController1.statsUpdated + +End Sub + +CActionsController.actionUploadsOpen: +Sub actionUploadsOpen(targetListBox as CListBox) + + me.CUploadsController1.getTransferPath(targetListBox.listIndex).open + +End Sub + +CActionsController.actionResponseSpam: +Sub actionResponseSpam(targetListBox as CListBox) + + dim i, j as integer + + j = targetListBox.listCount - 1 + + for i = 0 to j + + if targetListBox.selected(i) then + me.CCoreController1.sendCommand "addSpamFiles|" + me.CQueryController1.getLocalIndexes(i) + me.CQueryController1.setQuerySpam(i, true) + + end + + next + + me.CCoreController1.sendCommand "applyFilterSettings" + me.CFilterController1.filterResults + +End Sub + +CActionsController.actionResponseFilterResults: +Sub actionResponseFilterResults() + me.CFilterController1.toggleFilterEnabled + me.CFilterController1.filterResults + me.CFilterController1.updateFilter +End Sub + +CActionsController.Action: +Sub Action(item As String) + + try + select case me.actionType + + case 1 //* heading *// + actionHeading item + + case 2 //* network *// + actionNetwork item + + case 3 //* sidebar *// + actionSidebar item + + case 4 //* query results *// + actionResponse item + + case 5 //* downloads *// + actionDownloads item + + case 6 //* uploads *// + actionUploads item + + end + + catch + + end + +End Sub + +CNetworkController.connectionClosed: +Sub connectionClosed(args() as string) + + if ubound(args) <> 1 then return + + dim address as string = args(1) + + if me.representedInfos.hasKey(address) = false then return + + dim infoArray as integer = me.representedInfos.value(address) + + me.remove infoArray + + me.flush + updateCell me.representedInfos.count + +End Sub + +CNetworkController.statsUpdated: +Sub statsUpdated() + + dim i as integer + + for i = ubound(me.representedObjects) downto 0 + + CNetworkModel(me.representedObjects(i)).invalidateValues + + next + + me.flush + +End Sub + +CNetworkController.getHostAndPort: +Function getHostAndPort(index as integer) As string + + return CNetworkModel(me.representedObjects(index)).address + +End Function + +CNetworkController.flush: +Sub flush() + + updateDataSource me.representedObjects + +End Sub + +CNetworkController.getStringColumns: +Protected Sub getStringColumns(byref column as integer, byref temp1() as string, byref temp2() as string, byref temp3() as CStatsModel) + + dim c as CStatsModel + + select case column + + case 0 //* address *// + for each c in me.representedObjects + + temp1.append CNetworkModel(c).address + temp2.append CNetworkModel(c).address + temp3.append c + + next + + case 1 //* agent *// + for each c in me.representedObjects + + temp1.append CNetworkModel(c).agent + temp2.append CNetworkModel(c).agent + temp3.append c + + next + + case 2 //* language *// + for each c in me.representedObjects + + temp1.append CNetworkModel(c).language + temp2.append CNetworkModel(c).language + temp3.append c + + next + + case 3 //* type *// + for each c in me.representedObjects + + temp1.append CNetworkModel(c).type + temp2.append CNetworkModel(c).type + temp3.append c + + next + + end + +End Sub + +CNetworkController.getNumericColumns: +Protected Sub getNumericColumns(byref column as integer, byref temp1() as double, byref temp2() as double, byref temp3() as CStatsModel) + + dim c as CStatsModel + + for each c in me.representedObjects + + temp1.append CNetworkModel(c).uptime + temp2.append CNetworkModel(c).uptime + temp3.append c + + next + +End Sub + +CNetworkController.isNumericColumn: +Protected Function isNumericColumn(column as integer) As boolean + + return column = 4 + +End Function + +CNetworkController.connectionInitialized: +Sub connectionInitialized(args() as string) + + if ubound(args) <> 4 then return + + if me.representedInfos.hasKey(args(1)) then return + + dim c as new CNetworkModel(args) + + me.representedObjects.append c + me.representedInfos.value(c.getRepresentation) = ubound(me.representedObjects) + + me.flush + updateCell me.representedInfos.count + +End Sub + +CPreferencesController.Constructor: +Sub Constructor() + + kAqImportMusicFile = 0 + kAqAdultFilter = false + kAqAllowFreeloaders = true + kAqAutoClearDownloads = false + kAqAutoClearUploads = true + kAqBounceDockIcon = true + kAqCompleteFileSharing = true + kAqConcurrentDownloads = 5 + kAqConnectionSpeed = 350 + kAqDeleteAfterImport = false + kAqDownstreamLimit = 100 + kAqEnableUltrapeer = true + kAqExistingFileMatching = true + kAqID3Title = true + kAqIncompletePurgeTime = 7 + redim kAqIPFilterIPs(-1) + kAqKbFileSize = false + kAqLengthFilter = false + kAqLengthFilterCharacters = 180 + kAqLocale = true + kAqMaxUploads = 15 + kAqMaxUploadsPerPerson = 3 + kAqMoveMovies = false + kAqMoveMoviesLocation = "" + kAqMoveMusic = false + kAqMoveMusicLocation = "" + kAqMovePictures = false + kAqMovePicturesLocation = "" + redim kAqKeywordFilterKeywords(-1) + kAqNetBandwidth = true + kAqPartialFileSharing = true + kAqPlaySong = 0 + kAqPort = 6346 + kAqPositiveFilter = false + kAqPreferLocale = "" + kAqProxyPassword = "" + kAqProxyPort = 0 + kAqProxyPrivate = false + kAqProxyRequiresAuthentication = false + kAqProxyServer = "" + kAqProxyType = 1 + kAqProxyUsername = "" + kAqSaveDirectory = "" + redim kAqSharedDirectories(-1) + kAqSidebarTextFont = kTextFont + kAqSidebarTextSize = kMiddleTextSize + kAqSizeFilter = false + kAqSizeFilterKilobytes = 256 + kAqSpamFilter = true + kAqStandardTextFont = kTextFont + kAqStandardTextSize = kSmallTextSize + kAqTexturedWindow = true + kAqUPnPType = 0 + kAqUpstreamLimit = 100 + kAqUseProxy = false + kAqWarnDownloads = true + kAqWarnOpening = true + kAqWarnQuit = true + + kAqImportMusicFile = defaultsRead("kAqImportMusicFile", kAqImportMusicFile) + kAqAdultFilter = defaultsRead("kAqAdultFilter", kAqAdultFilter) + kAqAllowFreeloaders = defaultsRead("kAqAllowFreeloaders", kAqAllowFreeloaders) + kAqAutoClearDownloads = defaultsRead("kAqAutoClearDownloads", kAqAutoClearDownloads) + kAqAutoClearUploads = defaultsRead("kAqAutoClearUploads", kAqAutoClearUploads) + kAqBounceDockIcon = defaultsRead("kAqBounceDockIcon", kAqBounceDockIcon) + kAqCompleteFileSharing = defaultsRead("kAqCompleteFileSharing", kAqCompleteFileSharing) + kAqConcurrentDownloads = defaultsRead("kAqConcurrentDownloads", kAqConcurrentDownloads) + kAqConnectionSpeed = defaultsRead("kAqConnectionSpeed", kAqConnectionSpeed) + kAqDeleteAfterImport = defaultsRead("kAqDeleteAfterImport", kAqDeleteAfterImport) + kAqDownstreamLimit = defaultsRead("kAqDownstreamLimit", kAqDownstreamLimit) + kAqEnableUltrapeer = defaultsRead("kAqEnableUltrapeer", kAqEnableUltrapeer) + kAqExistingFileMatching = defaultsRead("kAqExistingFileMatching", kAqExistingFileMatching) + kAqID3Title = defaultsRead("kAqID3Title", kAqID3Title) + kAqIncompletePurgeTime = defaultsRead("kAqIncompletePurgeTime", kAqIncompletePurgeTime) + kAqIPFilterIPs = defaultsReadArrayString("kAqIPFilterIPs", kAqIPFilterIPs) + kAqKbFileSize = defaultsRead("kAqKbFileSize", kAqKbFileSize) + kAqLengthFilter = defaultsRead("kAqLengthFilter", kAqLengthFilter) + kAqLengthFilterCharacters = defaultsRead("kAqLengthFilterCharacters", kAqLengthFilterCharacters) + kAqLocale = defaultsRead("kAqLocale", kAqLocale) + kAqMaxUploads = defaultsRead("kAqMaxUploads", kAqMaxUploads) + kAqMaxUploadsPerPerson = defaultsRead("kAqMaxUploadsPerPerson", kAqMaxUploadsPerPerson) + kAqMoveMovies = defaultsRead("kAqMoveMovies", kAqMoveMovies) + kAqMoveMoviesLocation = defaultsRead("kAqMoveMoviesLocation", kAqMoveMoviesLocation) + kAqMoveMusic = defaultsRead("kAqMoveMusic", kAqMoveMusic) + kAqMoveMusicLocation = defaultsRead("kAqMoveMusicLocation", kAqMoveMusicLocation) + kAqMovePictures = defaultsRead("kAqMovePictures", kAqMovePictures) + kAqMovePicturesLocation = defaultsRead("kAqMovePicturesLocation", kAqMovePicturesLocation) + kAqKeywordFilterKeywords = defaultsReadArrayString("kAqKeywordFilterKeywords", kAqKeywordFilterKeywords) + kAqNetBandwidth = defaultsRead("kAqNetBandwidth", kAqNetBandwidth) + kAqPartialFileSharing = defaultsRead("kAqPartialFileSharing", kAqPartialFileSharing) + kAqPlaySong = defaultsRead("kAqPlaySong", kAqPlaySong) + kAqPort = defaultsRead("kAqPort", kAqPort) + kAqPositiveFilter = defaultsRead("kAqPositiveFilter", kAqPositiveFilter) + kAqPreferLocale = defaultsRead("kAqPreferLocale", kAqPreferLocale) + kAqProxyPassword = defaultsRead("kAqProxyPassword", kAqProxyPassword) + kAqProxyPort = defaultsRead("kAqProxyPort", kAqProxyPort) + kAqProxyPrivate = defaultsRead("kAqProxyPrivate", kAqProxyPrivate) + kAqProxyRequiresAuthentication = defaultsRead("kAqProxyRequiresAuthentication", kAqProxyRequiresAuthentication) + kAqProxyServer = defaultsRead("kAqProxyServer", kAqProxyServer) + kAqProxyType = defaultsRead("kAqProxyType", kAqProxyType) + kAqProxyUsername = defaultsRead("kAqProxyUsername", kAqProxyUsername) + kAqSaveDirectory = defaultsRead("kAqSaveDirectory", kAqSaveDirectory) + kAqSharedDirectories = defaultsReadArrayString("kAqSharedDirectories", kAqSharedDirectories) + kAqSidebarTextFont = defaultsRead("kAqSidebarTextFont", kAqSidebarTextFont) + kAqSidebarTextSize = defaultsRead("kAqSidebarTextSize", kAqSidebarTextSize) + kAqSizeFilter = defaultsRead("kAqSizeFilter", kAqSizeFilter) + kAqSizeFilterKilobytes = defaultsRead("kAqSizeFilterKilobytes", kAqSizeFilterKilobytes) + kAqSpamFilter = defaultsRead("kAqSpamFilter", kAqSpamFilter) + kAqStandardTextFont = defaultsRead("kAqStandardTextFont", kAqStandardTextFont) + kAqStandardTextSize = defaultsRead("kAqStandardTextSize", kAqStandardTextSize) + kAqTexturedWindow = defaultsRead("kAqTexturedWindow", kAqTexturedWindow) + kAqUPnPType = defaultsRead("kAqUPnPType", kAqUPnPType) + kAqUpstreamLimit = defaultsRead("kAqUpstreamLimit", kAqUpstreamLimit) + kAqUseProxy = defaultsRead("kAqUseProxy", kAqUseProxy) + kAqWarnDownloads = defaultsRead("kAqWarnDownloads", kAqWarnDownloads) + kAqWarnOpening = defaultsRead("kAqWarnOpening", kAqWarnOpening) + kAqWarnQuit = defaultsRead("kAqWarnQuit", kAqWarnQuit) + + if targetLeopard then + kAqTexturedWindow = false + end + + dim f as folderItem + + if kAqSaveDirectory.lenb <> 0 then f = getPath2FolderItem(kAqSaveDirectory) + + if f <> nil and f.exists then return + + try + #if targetMachO + f = DocumentsFolder.parent.child("Downloads") + + #elseif targetCarbon + f = DocumentsFolder.child("Downloads") + + #elseif targetWin32 + f = DocumentsFolder.fixRbBug.child("Downloads") + + #elseif targetLinux + f = DocumentsFolder.child("Downloads").fixRbBug + + #endif + + kAqSaveDirectory = f.posixPath + + catch + + end + + if ubound(kAqSharedDirectories) = -1 and f <> nil then _ + kAqSharedDirectories.append kAqSaveDirectory + +End Sub + +CPreferencesController.Destructor: +Sub Destructor() + + defaultsWrite "kAqImportMusicFile", kAqImportMusicFile + defaultsWrite "kAqAdultFilter", kAqAdultFilter + defaultsWrite "kAqAllowFreeloaders", kAqAllowFreeloaders + defaultsWrite "kAqAutoClearDownloads", kAqAutoClearDownloads + defaultsWrite "kAqAutoClearUploads", kAqAutoClearUploads + defaultsWrite "kAqBounceDockIcon", kAqBounceDockIcon + defaultsWrite "kAqCompleteFileSharing", kAqCompleteFileSharing + defaultsWrite "kAqConcurrentDownloads", kAqConcurrentDownloads + defaultsWrite "kAqConnectionSpeed", kAqConnectionSpeed + defaultsWrite "kAqDeleteAfterImport", kAqDeleteAfterImport + defaultsWrite "kAqDownstreamLimit", kAqDownstreamLimit + defaultsWrite "kAqEnableUltrapeer", kAqEnableUltrapeer + defaultsWrite "kAqExistingFileMatching", kAqExistingFileMatching + defaultsWrite "kAqID3Title", kAqID3Title + defaultsWrite "kAqIncompletePurgeTime", kAqIncompletePurgeTime + defaultsWriteArrayString "kAqIPFilterIPs", kAqIPFilterIPs + defaultsWrite "kAqKbFileSize", kAqKbFileSize + defaultsWrite "kAqLengthFilter", kAqLengthFilter + defaultsWrite "kAqLengthFilterCharacters", kAqLengthFilterCharacters + defaultsWrite "kAqLocale", kAqLocale + defaultsWrite "kAqMaxUploads", kAqMaxUploads + defaultsWrite "kAqMaxUploadsPerPerson", kAqMaxUploadsPerPerson + defaultsWrite "kAqMoveMovies", kAqMoveMovies + defaultsWrite "kAqMoveMoviesLocation", kAqMoveMoviesLocation + defaultsWrite "kAqMoveMusic", kAqMoveMusic + defaultsWrite "kAqMoveMusicLocation", kAqMoveMusicLocation + defaultsWrite "kAqMovePictures", kAqMovePictures + defaultsWrite "kAqMovePicturesLocation", kAqMovePicturesLocation + defaultsWriteArrayString "kAqKeywordFilterKeywords", kAqKeywordFilterKeywords + defaultsWrite "kAqNetBandwidth", kAqNetBandwidth + defaultsWrite "kAqPartialFileSharing", kAqPartialFileSharing + defaultsWrite "kAqPlaySong", kAqPlaySong + defaultsWrite "kAqPort", kAqPort + defaultsWrite "kAqPositiveFilter", kAqPositiveFilter + defaultsWrite "kAqPreferLocale", kAqPreferLocale + defaultsWrite "kAqProxyPassword", kAqProxyPassword + defaultsWrite "kAqProxyPort", kAqProxyPort + defaultsWrite "kAqProxyPrivate", kAqProxyPrivate + defaultsWrite "kAqProxyRequiresAuthentication", kAqProxyRequiresAuthentication + defaultsWrite "kAqProxyServer", kAqProxyServer + defaultsWrite "kAqProxyType", kAqProxyType + defaultsWrite "kAqProxyUsername", kAqProxyUsername + defaultsWrite "kAqSaveDirectory", kAqSaveDirectory + defaultsWriteArrayString "kAqSharedDirectories", kAqSharedDirectories + defaultsWrite "kAqSidebarTextFont", kAqSidebarTextFont + defaultsWrite "kAqSidebarTextSize", kAqSidebarTextSize + defaultsWrite "kAqSpamFilter", kAqSpamFilter + defaultsWrite "kAqSizeFilter", kAqSizeFilter + defaultsWrite "kAqSizeFilterKilobytes", kAqSizeFilterKilobytes + defaultsWrite "kAqStandardTextFont", kAqStandardTextFont + defaultsWrite "kAqStandardTextSize", kAqStandardTextSize + defaultsWrite "kAqTexturedWindow", kAqTexturedWindow + defaultsWrite "kAqUPnPType", kAqUPnPType + defaultsWrite "kAqUpstreamLimit", kAqUpstreamLimit + defaultsWrite "kAqUseProxy", kAqUseProxy + defaultsWrite "kAqWarnDownloads", kAqWarnDownloads + defaultsWrite "kAqWarnOpening", kAqWarnOpening + defaultsWrite "kAqWarnQuit", kAqWarnQuit + +End Sub + +CPreferencesActionsController.openPreferencesMenu: +Sub openPreferencesMenu(sender as CHierarchicalListBox, row as integer, column as integer, defaults as string, d as Dictionary) + + dim i, j as integer + dim items(-1) as string + + try + me.receiver = sender + me.row = row + me.column = column + me.defaults = defaults + me.d = d + + j = me.d.count - 1 + + for i = 0 to j + + if me.d.key(i).type = 8 and me.d.key(i) = "currentKey" then + // + + elseif items.indexOf(me.d.value(me.d.key(i))) = -1 then + items.append me.d.value(me.d.key(i)) + me.addRow me.d.value(me.d.key(i)) + + end + + next + + me.open + + catch + + finally + me.deleteAllRows + me.receiver = nil + me.row = 0 + me.column = 0 + me.defaults = "" + me.d = nil + + end + +End Sub + +CPreferencesActionsController.Action: +Sub Action(item As String) + + dim f as folderItem + dim i as integer + dim s as string + + select case item + + case getLocalizedString("Clear Spam History", "Preferences") + sendCommand "clearSpamFiles" + + case getLocalizedString("Add Keyword...", "Preferences") + kAqKeywordFilterKeywords.insert 0, "" + me.receiver.expanded(1) = false + me.receiver.expanded(1) = true + me.receiver.editCell(me.row + 1, me.column) + + case getLocalizedString("Add IP Address...", "Preferences") + kAqIPFilterIPs.insert 0, "" + me.receiver.expanded(7) = false + me.receiver.expanded(7) = true + me.receiver.editCell(me.row + 1, me.column) + + case getLocalizedString("Add Folder...", "Preferences") + f = selectFolder + + if f <> nil and kAqSharedDirectories.indexOf(f.posixPath) = -1 then + kAqSharedDirectories.append f.posixPath + me.receiver.valueChanged me.row, me.column + me.receiver.expanded(5) = false + me.receiver.expanded(5) = true + + end + + case getLocalizedString("Remove", "Preferences") + if me.defaults = "kAqSharedDirectories" then + s = me.d.value("currentKey") + + if s <> "" and kAqSharedDirectories.indexOf(s) <> -1 then + kAqSharedDirectories.remove kAqSharedDirectories.indexOf(s) + me.receiver.valueChanged me.row, me.column + me.receiver.removeRow me.row + + end + + elseif me.defaults = "kAqKeywordFilterKeywords" then + s = me.d.value("currentKey") + + if kAqKeywordFilterKeywords.indexOf(s) <> -1 then + kAqKeywordFilterKeywords.remove kAqKeywordFilterKeywords.indexOf(s) + me.receiver.cellTag(me.row, 1) = nil + me.receiver.valueChanged me.row, me.column + me.receiver.removeRow me.row + + end + + elseif me.defaults = "kAqIPFilterIPs" then + s = me.d.value("currentKey") + + if kAqIPFilterIPs.indexOf(s) <> -1 then + kAqIPFilterIPs.remove kAqIPFilterIPs.indexOf(s) + me.receiver.cellTag(me.row, 1) = nil + me.receiver.valueChanged me.row, me.column + me.receiver.removeRow me.row + + end + + end + + case getLocalizedString("Other...", "Preferences") + f = selectFolder + + if f <> nil then + s = f.posixPath + me.d.value(s) = s + me.d.value("currentKey") = s + me.receiver.cell(me.row, me.column) = s + me.receiver.cellTag(me.row, me.column) = me.d + me.receiver.valueChanged me.row, me.column + + end + + else + if me.defaults = "kAqKeywordFilterKeywords" then + me.receiver.editCell(me.row, me.column) + + elseif me.defaults = "kAqIPFilterIPs" then + me.receiver.editCell(me.row, me.column) + + else + for i = me.d.count - 1 downto 0 + + if me.d.key(i).type = 8 and me.d.key(i) = "currentKey" then + // + + elseif me.d.value(me.d.key(i)) = item then + me.d.value("currentKey") = me.d.key(i) + me.receiver.cell(me.row, me.column) = item + me.receiver.cellTag(me.row, me.column) = me.d + me.receiver.valueChanged me.row, me.column + exit + + end + + next + + end + + end + +End Sub + +CQueryController.handleQuery: +Sub handleQuery(arg as String, selected as boolean, keepInSidebar as boolean) + + if arg.lenb = 0 or arg.instrb("|") <> 0 then + beep + return + + end + + dim oldIndex, arrayIndex as integer + dim c as CQueryModel + + if me.queryStrings.haskey(arg) = false then + //* create new query *// + + me.positiveQueryIndex = me.positiveQueryIndex + 1 + + c = new CQueryModel(me.positiveQueryIndex, arg, new CFilterModel(me.getFilterModel), keepInSidebar) + c.queryFilter.enabled = false + c.positiveQueryIndexes.append c.queryIndex + + me.queries.value(c.queryIndex) = c + me.queryStrings.value(c.queryString) = c.queryIndex + + me.representedObjects.append new CSidebarModel(c.queryString, c.queryIndex, 120) + arrayIndex = ubound(me.representedObjects) + me.representedInfos.value(c.queryIndex) = arrayIndex + + else + //* overwrite existing query index *// + + me.positiveQueryIndex = me.positiveQueryIndex + 1 + + oldIndex = me.queryStrings.value(arg) + c = me.queries.value(oldIndex) + + me.queries.remove oldIndex + me.queryStrings.remove c.queryString + + arrayIndex = me.representedInfos.value(c.queryIndex) + me.representedInfos.remove c.queryIndex + + c.queryIndex = me.positiveQueryIndex + c.positiveQueryIndexes.append c.queryIndex + + me.queries.value(c.queryIndex) = c + me.queryStrings.value(c.queryString) = c.queryIndex + + CSidebarModel(me.representedObjects(arrayIndex)).overwriteStats c.queryIndex, 120 + me.representedInfos.value(c.queryIndex) = arrayIndex + + if me.currentIndex = oldIndex then me.currentIndex = c.queryIndex + + end + + updateCell me.representedObjects + + if selected then selectCell arrayIndex + + select case c.queryType + + case 0 //* what's new query *// + me.CCoreController1.sendCommand "queryWhatIsNew" + + case 1 //* browse query *// + me.CCoreController1.sendCommand "doBrowseHost|" + arg.replaceb(":", "|") + + case 2 //* find more sources query *// + me.CCoreController1.sendCommand "queryFindMoreSources|" + c.queryString + + case 3 //* normal query *// + me.CCoreController1.sendCommand "query|" + c.positiveFilterKeywords.join + + end + +End Sub + +CQueryController.handleQueryReply: +Sub handleQueryReply(args() as String) + + if ubound(args) <> 15 then return + + dim queryIndex as integer = args(1).val + + if me.queries.hasKey(queryIndex) = false then return + + dim query as CQueryModel = me.queries.value(queryIndex) + + //* keyword filtering *// + + dim keywords(-1) as string + + keywords = query.positiveFilterKeywords + + if kAqPositiveFilter and ubound(keywords) <> -1 and _ + args(7).lowercase.completeMatches(keywords) = false and _ + args(12).lowercase.completeMatches(keywords) = false and _ + args(13).lowercase.completeMatches(keywords) = false and _ + args(14).lowercase.completeMatches(keywords) = false then return + + keywords = query.negativeFilterKeywords + + if ubound(keywords) <> -1 and _ + ( args(7).lowercase.matches(keywords) or _ + args(12).lowercase.matches(keywords) or _ + args(13).lowercase.matches(keywords) or _ + args(14).lowercase.matches(keywords) ) then return + + //* filename length filtering *// + + if kAqLengthFilter and args(7).lenb >= kAqLengthFilterCharacters then return + + //* file size filtering *// + + if kAqSizeFilter and args(9).val / 1024 <= kAqSizeFilterKilobytes then return + + //* spam filtering *// + + if kAqSpamFilter and args(15).val = 1 then return + + //* response handling *// + + dim c as CResponseModel + dim arrayIndex as integer + + try + + if query.response.representedInfos.hasKey(args(6)) = false then + c = new CResponseModel(args) + c.exists = me.CFileurnsController1.hasKey(c.sha1) + c.marked = me.CDownloadsController1.hasMarkedDownloadItem(c.sha1) + + query.response.representedObjects.append c + query.response.representedInfos.value(c.sha1) = ubound(query.response.representedObjects) //* create hash map *// + + arrayIndex = me.representedInfos.value(queryIndex) + CSidebarModel(me.representedObjects(arrayIndex)).incrementStats _ + (me.currentIndex = queryIndex), _ + me.CFilterController1.isFilteredResponse(c, query.queryFilter) + CSidebarModel(me.representedObjects(arrayIndex)).invalidateValues + + else + arrayIndex = query.response.representedInfos.value(args(6)) + CResponseModel(query.response.representedObjects(arrayIndex)).addResponse args + CResponseModel(query.response.representedObjects(arrayIndex)).invalidateValues + + end + + me.queries.value(queryIndex) = query + + if me.currentIndex = queryIndex then me.CFilterController1.setNeedsSort + + catch + + end + +End Sub + +CQueryController.handleQueryWhatIsNew: +Sub handleQueryWhatIsNew() + + handleQuery getLocalizedString("What's New?", "Misc"), true, true + +End Sub + +CQueryController.getQueryString: +Function getQueryString() As string + + if me.currentIndex <> -1 and me.queries.hasKey(me.currentIndex) then _ + return CQueryModel(me.queries.value(me.currentIndex)).queryString + +End Function + +CQueryController.stopQuery: +Sub stopQuery() + + if me.currentIndex <> -1 then stopQuery me.currentIndex + +End Sub + +CQueryController.startQuery: +Sub startQuery(selected as boolean) + + if me.currentIndex <> -1 then startQuery me.currentIndex, selected + +End Sub + +CQueryController.getResponseCount: +Function getResponseCount() As integer + + return me.getResponseCount(me.currentIndex) + +End Function + +CQueryController.removeQuery: +Sub removeQuery(index as integer) + + if me.queries.hasKey(index) = false then return + + if me.currentIndex = index then me.currentIndex = -1 + + dim c as CQueryModel = me.queries.value(index) + dim arrayIndex as integer + + me.queries.remove c.queryIndex + me.queryStrings.remove c.queryString + + arrayIndex = me.representedInfos.value(c.queryIndex) + me.representedObjects.remove arrayIndex + me.representedInfos.remove c.queryIndex + me.rehash + + updateCell me.representedObjects + + if ubound(c.positiveQueryIndexes) <> -1 then + me.CCoreController1.sendCommand "clearAllResults|" + c.positiveQueryIndexes.join("|") + me.CCoreController1.sendCommand "removeQuery|" + c.positiveQueryIndexes.join("|") + + end + +End Sub + +CQueryController.clearAllResults: +Sub clearAllResults(index as integer) + + if me.queries.hasKey(index) = false then return + + dim c as CQueryModel = me.queries.value(index) + + c.clearAllResults + me.queries.value(index) = c + + if me.currentIndex = index then + me.filteredQuery.clearAllResults + me.flush + end + + dim arrayIndex as integer = me.representedInfos.value(index) + + CSidebarModel(me.representedObjects(arrayIndex)).updateStats 0, 0 + CSidebarModel(me.representedObjects(arrayIndex)).invalidateValues + + updateCell me.representedObjects + + if ubound(c.positiveQueryIndexes) <> -1 then _ + me.CCoreController1.sendCommand "clearAllResults|" + c.positiveQueryIndexes.join("|") + +End Sub + +CQueryController.removeAllQueries: +Sub removeAllQueries() + + me.currentIndex = -1 + me.queries.clear + me.queryStrings.clear + redim me.representedObjects(-1) + me.representedInfos.clear + me.filteredQuery = new CQueryModel + + updateCell me.representedObjects + + me.CCoreController1.sendCommand "removeAllQueries" + +End Sub + +CQueryController.getResponseModel: +Function getResponseModel(listIndex as integer) As CResponseModel + + return CResponseModel(me.filteredQuery.response.representedObjects(listIndex)) + +End Function + +CQueryController.Initialize: +Sub Initialize(core as CCoreController, filter as CFilterController, fileurns as CFileurnsController, downloads as CDownloadsController) + + me.CCoreController1 = core + me.CFilterController1 = filter + me.CFileurnsController1 = fileurns + me.CDownloadsController1 = downloads + + dim queryString(-1), keyword(-1), columnWidths(-1) as string + dim enabled(-1) as boolean + dim media(-1), bitrate(-1), size(-1), sources(-1), speed(-1), sortColumn(-1), sortDirection(-1) as integer + dim i, j as integer + + queryString = defaultsReadArrayString("kAqSearchControllerStringsKey", queryString) + keyword = defaultsReadArrayString("kAqFilterControllerKeyword", keyword) + enabled = defaultsReadArrayBoolean("kAqFilterControllerEnabled", enabled) + media = defaultsReadArrayInteger("kAqFilterControllerMedia", media) + bitrate = defaultsReadArrayInteger("kAqFilterControllerBitrate", bitrate) + size = defaultsReadArrayInteger("kAqFilterControllerSize", size) + sources = defaultsReadArrayInteger("kAqFilterControllerSources", sources) + speed = defaultsReadArrayInteger("kAqFilterControllerSpeed", speed) + sortColumn = defaultsReadArrayInteger("kAqFilterControllerSortColumn", sortColumn) + sortDirection = defaultsReadArrayInteger("kAqFilterControllerSortDirection", sortDirection) + columnWidths = defaultsReadArrayString("kAqFilterControllerColumnWidths", columnWidths) + + j = ubound(queryString) + + for i = 0 to j + + try + handleQueryInitial queryString(i), _ + new CFilterModel( _ + keyword(i), enabled(i), media(i), bitrate(i), _ + size(i), sources(i), speed(i), _ + sortColumn(i), sortDirection(i), columnWidths(i) _ + ) + + catch + handleQueryInitial queryString(i), new CFilterModel + + end + + next + + updateCell me.representedObjects + +End Sub + +CQueryController.getQueryModel: +Function getQueryModel(index as integer) As CQueryModel + + if me.queries.hasKey(index) then return me.queries.value(index) + +End Function + +CQueryController.setCurrentIndex: +Sub setCurrentIndex(index as integer) + + me.currentIndex = index + +End Sub + +CQueryController.setQueryModel: +Sub setQueryModel(index as integer, query as CQueryModel) + + me.queries.value(index) = query + +End Sub + +CQueryController.startQuery: +Sub startQuery(index as integer, selected as boolean) + + if me.queries.hasKey(index) = false then return + + dim c as CQueryModel = me.queries.value(index) + + handleQuery c.queryString, selected, c.keepInSidebar + +End Sub + +CQueryController.stopQuery: +Sub stopQuery(index as integer) + + if me.queries.hasKey(index) = false then return + + dim c as CQueryModel = me.queries.value(index) + dim arrayIndex as integer + + //* overwrite existing query index *// + + me.negativeQueryIndex = me.negativeQueryIndex - 1 + + me.queries.remove c.queryIndex + me.queryStrings.remove c.queryString + + arrayIndex = me.representedInfos.value(c.queryIndex) + me.representedInfos.remove c.queryIndex + + c.queryIndex = me.negativeQueryIndex + me.queries.value(c.queryIndex) = c + me.queryStrings.value(c.queryString) = c.queryIndex + + CSidebarModel(me.representedObjects(arrayIndex)).overwriteStats c.queryIndex, -1 + me.representedInfos.value(c.queryIndex) = arrayIndex + + if me.currentIndex = index then me.currentIndex = c.queryIndex + + updateCell me.representedObjects + +End Sub + +CQueryController.Finalize: +Sub Finalize() + + dim i, j as integer + dim queryString(-1), keyword(-1), columnWidths(-1) as string + dim enabled(-1) as boolean + dim media(-1), bitrate(-1), size(-1), sources(-1), speed(-1), sortColumn(-1), sortDirection(-1) as integer + dim c as CQueryModel + + j = ubound(me.representedObjects) + + for i = 0 to j + + c = me.queries.value(CSidebarModel(me.representedObjects(i)).index) + + if c.keepInSidebar then + queryString.append c.queryString + keyword.append c.queryFilter.keyword + enabled.append c.queryFilter.enabled + media.append c.queryFilter.media + bitrate.append c.queryFilter.bitrate + size.append c.queryFilter.size + sources.append c.queryFilter.sources + speed.append c.queryFilter.speed + sortColumn.append c.queryFilter.sortColumn + sortDirection.append c.queryFilter.sortDirection + columnWidths.append c.queryFilter.columnWidths + + end + + next + + defaultsWriteArrayString "kAqSearchControllerStringsKey", queryString + defaultsWriteArrayString "kAqFilterControllerKeyword", keyword + defaultsWriteArrayBoolean "kAqFilterControllerEnabled", enabled + defaultsWriteArrayInteger "kAqFilterControllerMedia", media + defaultsWriteArrayInteger "kAqFilterControllerBitrate", bitrate + defaultsWriteArrayInteger "kAqFilterControllerSize", size + defaultsWriteArrayInteger "kAqFilterControllerSources", sources + defaultsWriteArrayInteger "kAqFilterControllerSpeed", speed + defaultsWriteArrayInteger "kAqFilterControllerSortColumn", sortColumn + defaultsWriteArrayInteger "kAqFilterControllerSortDirection", sortDirection + defaultsWriteArrayString "kAqFilterControllerColumnWidths", columnWidths + +End Sub + +CQueryController.handleQueryInitial: +Sub handleQueryInitial(queryString as string, filter as CFilterModel) + + dim c as CQueryModel + + if me.queryStrings.haskey(queryString) = false then + //* create new query *// + + me.negativeQueryIndex = me.negativeQueryIndex - 1 + + c = new CQueryModel(me.negativeQueryIndex, queryString, filter, true) + + me.queries.value(c.queryIndex) = c + me.queryStrings.value(c.queryString) = c.queryIndex + me.representedObjects.append new CSidebarModel(c.queryString, c.queryIndex, -1) + me.representedInfos.value(c.queryIndex) = ubound(me.representedObjects) + + end + +End Sub + +CQueryController.handleQueryBrowse: +Sub handleQueryBrowse(arg as string) + + handleQuery arg, false, false + +End Sub + +CQueryController.getCurrentIndex: +Function getCurrentIndex() As integer + + return me.currentIndex + +End Function + +CQueryController.clearAllResults: +Sub clearAllResults() + + if me.currentIndex <> -1 then _ + clearAllResults me.currentIndex + +End Sub + +CQueryController.removeQuery: +Sub removeQuery() + + if me.currentIndex <> -1 then removeQuery me.currentIndex + +End Sub + +CQueryController.setQueryMarked: +Sub setQueryMarked(arrayIndex as integer, value as boolean) + + dim c as CResponseModel = CResponseModel(me.filteredquery.response.representedObjects(arrayIndex)) + + c.marked = value + c.invalidateValues + me.filteredquery.response.representedObjects(arrayIndex) = c + + dim sha1 as string = c.sha1 + + if me.currentIndex <> -1 and _ + CQueryModel(me.queries.value(me.currentIndex)).response.representedInfos.hasKey(sha1) then + arrayIndex = CQueryModel(me.queries.value(me.currentIndex)).response.representedInfos.value(sha1) + CQueryModel(me.queries.value(me.currentIndex)).response.representedObjects(arrayIndex) = c + + end + +End Sub + +CQueryController.hasQueryModel: +Function hasQueryModel(index as integer) As boolean + + return me.queries.hasKey(index) + +End Function + +CQueryController.setFilteredQuery: +Sub setFilteredQuery(filteredQuery as CQueryModel) + + me.filteredQuery = filteredQuery + me.flush + + dim arrayIndex as integer = me.representedInfos.value(me.currentIndex) + + CSidebarModel(me.representedObjects(arrayIndex)).updateStats me.getResponseCount, me.filteredQuery.response.representedInfos.count + CSidebarModel(me.representedObjects(arrayIndex)).invalidateValues + + updateCell me.representedObjects + +End Sub + +CQueryController.hasQueryString: +Function hasQueryString(browseQueryString as string) As boolean + + return me.queryStrings.hasKey(browseQueryString) + +End Function + +CQueryController.getLocalIndexes: +Function getLocalIndexes(listIndex as integer) As string + + dim c as CResponseModel = CResponseModel(me.filteredquery.response.representedObjects(listIndex)) + + dim i, j as integer + dim results(-1) as string + + j = ubound(c.queryIndexes) + + //* download index *// + + for i = 0 to j + + results.append c.queryIndexes(i).stringValue + ":" + c.localIndexes(i).stringValue + + next + + return results.join("|") + +End Function + +CQueryController.Constructor: +Sub Constructor() + + super.Constructor + + me.queries = new DIctionary + me.queryStrings = new Dictionary + me.filteredQuery = new CQueryModel + me.currentIndex = -1 + me.positiveQueryIndex = -1 + me.negativeQueryIndex = -1 + +End Sub + +CQueryController.setFilterModel: +Sub setFilterModel(c as CFilterModel) + + if me.currentIndex <> -1 and me.queries.hasKey(me.currentIndex) then _ + CQueryModel(me.queries.value(me.currentIndex)).queryFilter = c + +End Sub + +CQueryController.getFilterModel: +Function getFilterModel() As CFilterModel + + if me.currentIndex <> -1 and me.queries.hasKey(me.currentIndex) then + return CQueryModel(me.queries.value(me.currentIndex)).queryFilter + + else + return me.CFilterController1.getFilterModel + + end + +End Function + +CQueryController.browseHostFailed: +Sub browseHostFailed(args() as string) + + if ubound(args) <> 1 then return + + dim queryIndex as integer = args(1).val + + if me.representedInfos.hasKey(queryIndex) = false then return + + dim c as CSidebarModel = CSidebarModel(me.representedObjects(me.representedInfos.value(queryIndex))) + + if me.getKeepInSidebar(c.index) = false and me.getResponseCount(c.index) = 0 then + me.removeQuery c.index + else + me.stopQuery c.index + end + +End Sub + +CQueryController.flush: +Sub flush() + + updateDataSource me.filteredQuery.response.representedObjects + +End Sub + +CQueryController.convertEncoding: +Sub convertEncoding(arrayIndex as integer, type as integer) + + dim sha1 as string + dim c as CResponseModel = CResponseModel(me.filteredquery.response.representedObjects(arrayIndex)) + + c.convertEncoding type + c.invalidateValues + me.filteredquery.response.representedObjects(arrayIndex) = c + + if me.currentIndex <> -1 and _ + CQueryModel(me.queries.value(me.currentIndex)).response.representedInfos.hasKey(c.sha1) then + arrayIndex = CQueryModel(me.queries.value(me.currentIndex)).response.representedInfos.value(c.sha1) + CQueryModel(me.queries.value(me.currentIndex)).response.representedObjects(arrayIndex) = c + + end + +End Sub + +CQueryController.getKeepInSidebar: +Function getKeepInSidebar(index as integer) As boolean + + if me.queries.hasKey(index) then return CQueryModel(me.queries.value(index)).keepInSidebar + +End Function + +CQueryController.setKeepInSidebar: +Sub setKeepInSidebar(index as integer, value as boolean) + + if me.queries.hasKey(index) then CQueryModel(me.queries.value(index)).keepInSidebar = value + +End Sub + +CQueryController.getResponseCount: +Function getResponseCount(index as integer) As integer + + if me.queries.hasKey(index) then _ + return CQueryModel(me.queries.value(index)).response.representedInfos.count + +End Function + +CQueryController.setSidebarHighlighted: +Sub setSidebarHighlighted(index as integer, value as boolean) + + CSidebarModel(me.representedObjects(index)).highlighted = value + +End Sub + +CQueryController.reorderSidebarDatasource: +Sub reorderSidebarDatasource(newPosition as integer, selectedItems() as integer) + + dim i, j, index as integer + dim temp(-1) as CStatsModel + + try + newPosition = me.representedObjects(newPosition).getRepresentation + + j = ubound(me.representedObjects) + + for i = 0 to j + + if selectedItems.indexOf(i) = - 1 then temp.append me.representedObjects(i) + + if me.representedObjects(i).getRepresentation = newPosition then newPosition = i + + next + + j = ubound(selectedItems) + + for i = 0 to j + + temp.insert newPosition + i, me.representedObjects(selectedItems(i)) + + next + + me.representedObjects = temp + me.rehash + + updateCell me.representedObjects + selectCell -1 + + catch + + end + +End Sub + +CQueryController.handleQueryFindMoreSources: +Sub handleQueryFindMoreSources(arg as string) + + handleQuery arg, false, false + +End Sub + +CQueryController.handleQueryNormal: +Sub handleQueryNormal(arg as string) + + handleQuery arg, true, true + +End Sub + +CQueryController.setQuerySpam: +Sub setQuerySpam(arrayIndex as integer, spam as boolean) + + dim sha1 as string + dim c as CResponseModel = CResponseModel(me.filteredquery.response.representedObjects(arrayIndex)) + + c.spam = spam + c.invalidateValues + me.filteredquery.response.representedObjects(arrayIndex) = c + sha1 = c.sha1 + + if me.currentIndex <> -1 and _ + CQueryModel(me.queries.value(me.currentIndex)).response.representedInfos.hasKey(sha1) then + arrayIndex = CQueryModel(me.queries.value(me.currentIndex)).response.representedInfos.value(sha1) + CQueryModel(me.queries.value(me.currentIndex)).response.representedObjects(arrayIndex) = c + + end + +End Sub + +CQueryController.statsUpdated: +Sub statsUpdated() + + dim i as integer + dim c as CSidebarModel + + for i = ubound(me.representedObjects) downto 0 + + c = CSidebarModel(me.representedObjects(i)) + + if c.interval > 0 then + c.interval = c.interval - 1 + + me.representedObjects(i) = c + + if c.interval = 0 then + if me.getKeepInSidebar(c.index) = false and me.getResponseCount(c.index) = 0 then + me.removeQuery c.index + + else + me.stopQuery c.index + + end + + end + + end + + next + + updateCell me.representedObjects + +End Sub + +CResourceController.getSmallMediaPicture: +Function getSmallMediaPicture(c as CResponseModel) As picture + + if c.marked then return me.controlPictures(0) + + #if targetMachO + if me.smallIconCache.hasKey(c.extension) or me.appendIconCache(c.extension) then _ + return me.smallIconCache.value(c.extension) + + #endif + + return me.smallMediaPictures(c.mediaType) + +End Function + +CResourceController.getLargeMediaPicture: +Function getLargeMediaPicture(type as integer, extension as string) As picture + + #if targetMachO + if me.largeIconCache.hasKey(extension) or me.appendIconCache(extension) then _ + return me.largeIconCache.value(extension) + + #endif + + return me.largeMediaPictures(type) + +End Function + +CResourceController.getMaskedPicture: +Function getMaskedPicture(pictureName as string) As picture + + try + #if debugBuild and targetMachO + return getFolderItem("Contents").child("Resources").child(pictureName).openAsMaskedPicture + + #elseif targetMachO + return App.ExecutableFile.parent.parent.child("Resources").child(pictureName).openAsMaskedPicture + + #elseif targetCarbon + return App.ExecutableFile.parent.child("Contents").child("Resources").child(pictureName).openAsMaskedPicture + + #elseif targetWin32 + return App.ExecutableFile.fixRbBug.parent.child("Contents").child("Resources").child(pictureName).openAsMaskedPicture + + #elseif targetLinux + return App.ExecutableFile.parent.child("Contents").fixRbBug.child("Resources").fixRbBug.child(pictureName).fixRbBug.openAsMaskedPicture + + #endif + + catch + + end + +End Function + +CResourceController.getControlPicture: +Function getControlPicture(type as integer) As picture + + return me.controlPictures(type) + +End Function + +CResourceController.appendIconCache: +Protected Function appendIconCache(extension as string) As boolean + + #if targetMachO + dim f as folderItem + dim b as BinaryStream + dim p as picture + + try + f = PreferencesFolder.parent.Child("Caches").child("Cabos").child("icon." + extension) + + try + b = f.CreateBinaryFile("") + catch + + finally + if b <> nil then b.close + end + + p = new MacIcon(f, 32) + if p <> nil then me.largeIconCache.value(extension) = p + + p = new MacIcon(f, 16) + if p <> nil then me.smallIconCache.value(extension) = p + + return me.largeIconCache.hasKey(extension) and me.smallIconCache.hasKey(extension) + + catch + + end + + #endif + +End Function + +CResourceController.getChasingArrows: +Function getChasingArrows(type as integer) As picture + + return me.chasingArrows(type) + +End Function + +CResourceController.Constructor: +Sub Constructor() + + #if targetMachO + me.largeIconCache = new Dictionary + me.smallIconCache = new Dictionary + + dim i as integer + dim f as FolderItem + dim p as picture + dim extension as string + + try + f = PreferencesFolder.parent.child("Caches") + if f.exists = false then f.createAsFolder + f = f.child("Cabos") + if f.exists = false then f.createAsFolder + + for i = f.count downto 1 + if f.item(i).name.inStrb("icon.") <> 0 then + extension = f.item(i).name.getExtension + + if extension.lenb <> 0 then + p = new MacIcon(f.item(i), 32) + if p <> nil then me.largeIconCache.value(extension) = p + p = new MacIcon(f.item(i), 16) + if p <> nil then me.smallIconCache.value(extension) = p + end + + end + + next + + catch + + end + + for i = 0 to 5 + + me.chasingArrows(i) = me.getMaskedPicture(str(i) + ".png") + me.chasingArrows(i + 6) = me.getSilhouettePicture(me.chasingArrows(i)) + + next + + me.smallMediaPictures(1) = me.getMaskedPicture("music-small.png") + me.smallMediaPictures(2) = me.getMaskedPicture("pictures-small.png") + me.smallMediaPictures(3) = me.getMaskedPicture("movies-small.png") + me.smallMediaPictures(4) = me.getMaskedPicture("text-small.png") + me.smallMediaPictures(5) = me.getMaskedPicture("files-small.png") + + me.largeMediaPictures(1) = me.getMaskedPicture("music.png") + me.largeMediaPictures(2) = me.getMaskedPicture("pictures.png") + me.largeMediaPictures(3) = me.getMaskedPicture("movies.png") + me.largeMediaPictures(4) = me.getMaskedPicture("text.png") + me.largeMediaPictures(5) = me.getMaskedPicture("files.png") + + me.controlPictures(0) = me.getMaskedPicture("complete_small.png") + me.controlPictures(1) = me.getMaskedPicture("find_small.png") + me.controlPictures(2) = me.getMaskedPicture("network_small.png") + me.controlPictures(3) = me.getMaskedPicture("download_small.png") + me.controlPictures(4) = me.getMaskedPicture("upload_small.png") + me.controlPictures(5) = me.getSilhouettePicture(me.controlPictures(1)) + + #elseif targetCarbon + dim i as integer + + for i = 0 to 5 + + me.chasingArrows(i) = me.getMaskedPicture(str(i) + ".png") + me.chasingArrows(i + 6) = me.getSilhouettePicture(me.chasingArrows(i)) + + next + + me.smallMediaPictures(1) = me.getMaskedPicture("music-small.png") + me.smallMediaPictures(2) = me.getMaskedPicture("pictures-small.png") + me.smallMediaPictures(3) = me.getMaskedPicture("movies-small.png") + me.smallMediaPictures(4) = me.getMaskedPicture("text-small.png") + me.smallMediaPictures(5) = me.getMaskedPicture("files-small.png") + + me.largeMediaPictures(1) = me.getMaskedPicture("music.png") + me.largeMediaPictures(2) = me.getMaskedPicture("pictures.png") + me.largeMediaPictures(3) = me.getMaskedPicture("movies.png") + me.largeMediaPictures(4) = me.getMaskedPicture("text.png") + me.largeMediaPictures(5) = me.getMaskedPicture("files.png") + + me.controlPictures(0) = me.getMaskedPicture("complete_small.png") + me.controlPictures(1) = me.getMaskedPicture("find_small.png") + me.controlPictures(2) = me.getMaskedPicture("network_small.png") + me.controlPictures(3) = me.getMaskedPicture("download_small.png") + me.controlPictures(4) = me.getMaskedPicture("upload_small.png") + me.controlPictures(5) = me.getSilhouettePicture(me.controlPictures(1)) + + #elseif targetWin32 or targetLinux + dim i as integer + + for i = 0 to 5 + + me.chasingArrows(i) = me.getMaskedPicture(str(i) + ".gif") + me.chasingArrows(i + 6) = me.getSilhouettePicture(me.chasingArrows(i)) + + next + + me.smallMediaPictures(1) = me.getMaskedPicture("music-small.gif") + me.smallMediaPictures(2) = me.getMaskedPicture("pictures-small.gif") + me.smallMediaPictures(3) = me.getMaskedPicture("movies-small.gif") + me.smallMediaPictures(4) = me.getMaskedPicture("text-small.gif") + me.smallMediaPictures(5) = me.getMaskedPicture("files-small.gif") + + me.largeMediaPictures(1) = me.getMaskedPicture("music.gif") + me.largeMediaPictures(2) = me.getMaskedPicture("pictures.gif") + me.largeMediaPictures(3) = me.getMaskedPicture("movies.gif") + me.largeMediaPictures(4) = me.getMaskedPicture("text.gif") + me.largeMediaPictures(5) = me.getMaskedPicture("files.gif") + + me.controlPictures(0) = me.getMaskedPicture("complete_small.gif") + me.controlPictures(1) = me.getMaskedPicture("find_small.gif") + me.controlPictures(2) = me.getMaskedPicture("network_small.gif") + me.controlPictures(3) = me.getMaskedPicture("download_small.gif") + me.controlPictures(4) = me.getMaskedPicture("upload_small.gif") + me.controlPictures(5) = me.getSilhouettePicture(me.controlPictures(1)) + + #endif + +End Sub + +CResourceController.getSilhouettePicture: +Protected Function getSilhouettePicture(p as picture) As picture + + #if targetMachO or targetWin32 or targetLinux + dim result as picture + dim x, y as integer + + try + result = new picture(p.width, p.height, 32) + + for x = result.width downto 0 + + for y = result.height downto 0 + + result.RGBSurface.pixel(x, y) = &cFFFFFF + result.mask.RGBSurface.pixel(x, y) = p.mask.RGBSurface.pixel(x, y) + + next + + next + + return result + + catch + + end + + #elseif targetCarbon + return p + + #endif + +End Function + +CResponseController.getNumericColumns: +Protected Sub getNumericColumns(byref column as integer, byref temp1() as double, byref temp2() as double, byref temp3() as CStatsModel) + + dim c as CStatsModel + + select case column + + case 4 //* size *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).fileSize + temp2.append CResponseModel(c).fileSize + temp3.append c + + next + + case 5 //* bitrate *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).bitrate + temp2.append CResponseModel(c).bitrate + temp3.append c + + next + + case 6 //* seconds *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).seconds + temp2.append CResponseModel(c).seconds + temp3.append c + + next + + case 7 //* sources *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).sources + temp2.append CResponseModel(c).sources + temp3.append c + + next + + case 8 //* speed *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).speed + temp2.append CResponseModel(c).speed + temp3.append c + + next + + end + +End Sub + +CResponseController.getStringColumns: +Protected Sub getStringColumns(byref column as integer, byref temp1() as string, byref temp2() as string, byref temp3() as CStatsModel) + + dim c as CStatsModel + + select case column + + case 0 //* icon *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).extension + temp2.append CResponseModel(c).extension + temp3.append c + + next + + case 1 //* dispaly name *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).displayName + temp2.append CResponseModel(c).displayName + temp3.append c + + next + + case 2 //* artist *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).artist + temp2.append CResponseModel(c).artist + temp3.append c + + next + + case 3 //* album *// + for each c in me.representedObjects + + temp1.append CResponseModel(c).album + temp2.append CResponseModel(c).album + temp3.append c + + next + + end + +End Sub + +CResponseController.isNumericColumn: +Protected Function isNumericColumn(column as integer) As boolean + + select case column + + case 0 //* icon *// + return false + + case 1 //* dispaly name *// + return false + + case 2 //* artist *// + return false + + case 3 //* album *// + return false + + case 4 //* size *// + return true + + case 5 //* bitrate *// + return true + + case 6 //* seconds *// + return true + + case 7 //* sources *// + return true + + case 8 //* speed *// + return true + + end + +End Function + +CStatsController.Constructor: +Sub Constructor() + + me.representedInfos = new Dictionary + +End Sub + +CStatsController.rehash: +Sub rehash() + + dim i, j as integer + + j = ubound(me.representedObjects) + + for i = 0 to j + + me.representedInfos.value(me.representedObjects(i).getRepresentation) = i + + next + +End Sub + +CStatsController.remove: +Sub remove(index as integer) + + me.representedInfos.remove me.representedObjects(index).getRepresentation + me.representedObjects.remove index + me.rehash + +End Sub + +CStatsController.sort: +Sub sort(column as integer, direction as integer) + + if column = -1 or ubound(me.representedObjects) < 1 then return + + try + if me.isNumericColumn(column) then + me.sortNumber column, direction + + else + me.sortString column, direction + + end + + catch + + end + +End Sub + +CStatsController.sortNumber: +Protected Sub sortNumber(column as integer, direction as integer) + + dim temp1(-1), temp2(-1) as double + dim temp3(-1) as CStatsModel + dim c as CStatsModel + + me.getNumericColumns column, temp1, temp2, temp3 + + temp1.sort + + dim i, j, arrayIndex as integer + + j = ubound(temp1) + + if direction = 1 then + for i = 0 to j + + arrayIndex = temp2.indexOf(temp1(i)) + me.representedObjects(i) = temp3(arrayIndex) + me.representedInfos.value(me.representedObjects(i).getRepresentation) = i + temp2.remove arrayIndex + temp3.remove arrayIndex + + next + + else + for i = 0 to j + + arrayIndex = temp2.indexOf(temp1(j - i)) + me.representedObjects(i) = temp3(arrayIndex) + me.representedInfos.value(me.representedObjects(i).getRepresentation) = i + temp2.remove arrayIndex + temp3.remove arrayIndex + + next + + end + +End Sub + +CStatsController.getNumericColumns: +Protected Sub getNumericColumns(byref column as integer, byref temp1() as double, byref temp2() as double, byref temp3() as CStatsModel) + + //* Override *// + +End Sub + +CStatsController.sortString: +Protected Sub sortString(column as integer, direction as integer) + + dim temp1(-1), temp2(-1) as string + dim temp3(-1) as CStatsModel + dim c as CStatsModel + + me.getStringColumns column, temp1, temp2, temp3 + + temp1.stringSort + + dim i, j, arrayIndex as integer + + j = ubound(temp1) + + if direction = 1 then + for i = 0 to j + + arrayIndex = temp2.indexOf(temp1(i)) + me.representedObjects(i) = temp3(arrayIndex) + me.representedInfos.value(me.representedObjects(i).getRepresentation) = i + temp2.remove arrayIndex + temp3.remove arrayIndex + + next + + else + for i = 0 to j + + arrayIndex = temp2.indexOf(temp1(j - i)) + me.representedObjects(i) = temp3(arrayIndex) + me.representedInfos.value(me.representedObjects(i).getRepresentation) = i + temp2.remove arrayIndex + temp3.remove arrayIndex + + next + + end + +End Sub + +CStatsController.isNumericColumn: +Protected Function isNumericColumn(column as integer) As boolean + + //* Override *// + +End Function + +CStatsController.getStringColumns: +Protected Sub getStringColumns(byref column as integer, byref temp1() as string, byref temp2() as string, byref temp3() as CStatsModel) + + //* Override *// + +End Sub + +CTransferController.hasActiveTransfers: +Function hasActiveTransfers() As boolean + + dim i as integer + + for i = ubound(me.representedObjects) downto 0 + + if CTransferModel(me.representedObjects(i)).isActive then return true + + next + +End Function + +CTransferController.isCompletedTransferItem: +Function isCompletedTransferItem(index as integer) As boolean + + return CTransferModel(me.representedObjects(index)).isComplete + +End Function + +CTransferController.setCanceled: +Function setCanceled(index as integer) As boolean + + if CTransferModel(me.representedObjects(index)).canRemove then + CTransferModel(me.representedObjects(index)).isCanceled = true + return true + + end + +End Function + +CTransferController.getTransferPath: +Function getTransferPath(index as integer) As string + + return CTransferModel(me.representedObjects(index)).path + +End Function + +CTransferController.getTransferHashCode: +Function getTransferHashCode(index as integer) As variant + + return CTransferModel(me.representedObjects(index)).hashCode + +End Function + +CTransferController.getNumericColumns: +Protected Sub getNumericColumns(byref column as integer, byref temp1() as double, byref temp2() as double, byref temp3() as CStatsModel) + + dim c as CStatsModel + + select case column + + case 2 //* transfer *// + for each c in me.representedObjects + + temp1.append CTransferModel(c).amountRequested + temp2.append CTransferModel(c).amountRequested + temp3.append c + + next + + case 3 //* progress *// + for each c in me.representedObjects + + temp1.append CTransferModel(c).progress + temp2.append CTransferModel(c).progress + temp3.append c + + next + + case 4 //* time *// + for each c in me.representedObjects + + temp1.append CTransferModel(c).timeRemaining + temp2.append CTransferModel(c).timeRemaining + temp3.append c + + next + + end + +End Sub + +CTransferController.getStringColumns: +Protected Sub getStringColumns(byref column as integer, byref temp1() as string, byref temp2() as string, byref temp3() as CStatsModel) + + dim c as CStatsModel + + if column = 0 then //* extension *// + for each c in me.representedObjects + + temp1.append CTransferModel(c).extension + temp2.append CTransferModel(c).extension + temp3.append c + + next + + elseif column = 1 then //* filename *// + for each c in me.representedObjects + + temp1.append CTransferModel(c).fileName + temp2.append CTransferModel(c).fileName + temp3.append c + + next + + end + +End Sub + +CTransferController.isNumericColumn: +Protected Function isNumericColumn(column as integer) As boolean + + return column <> 0 and column <> 1 + +End Function + +CTransferController.getTransferFileName: +Function getTransferFileName(index as integer) As string + + return CTransferModel(me.representedObjects(index)).fileName + +End Function + +CTransferController.flush: +Sub flush() + + updateDataSource me.representedObjects + +End Sub + +CUploadsController.addUpload: +Sub addUpload(args() as string) + + if ubound(args) <> 10 then return + + if me.representedInfos.hasKey(args(1).val) then return + + dim c as new CUploadModel(args) + + me.representedObjects.append c + me.representedInfos.value(c.getRepresentation) = ubound(me.representedObjects) + + me.flush + +End Sub + +CUploadsController.removeUpload: +Sub removeUpload(args() as string) + + if ubound(args) <> 1 then return + + dim hashCode as integer = args(1).val + + if me.representedInfos.hasKey(hashCode) = false then return + + dim infoArray as integer = me.representedInfos.value(hashCode) + dim c as CUploadModel = CUploadModel(me.representedObjects(infoArray)) + + c.isComplete = true + + if c.isCanceled or kAqAutoClearUploads or c.amountTransfered = c.startingPoint then + me.remove infoArray + + else + c.invalidateValues + me.representedObjects(infoArray) = c + + end + + me.flush + +End Sub + +CUploadsController.updateUploadStats: +Sub updateUploadStats(args() as string) + + if ubound(args) <> 6 then return + + dim hashCode as integer = args(1).val + + if me.representedInfos.hasKey(hashCode) = false then return + + dim infoArray as integer = me.representedInfos.value(hashCode) + dim c as CUploadModel = CUploadModel(me.representedObjects(infoArray)) + + c.updateStats args + c.invalidateValues + + me.representedObjects(infoArray) = c + +End Sub + +CUploadsController.statsUpdated: +Sub statsUpdated() + + dim c as CTransferModel + dim i, uploading as integer + dim bandwidth as double + + for i = ubound(me.representedObjects) downto 0 + + c = CTransferModel(me.representedObjects(i)) + + if c.isActive then + uploading = uploading + 1 + bandwidth = bandwidth + c.measuredBandwidth + + end + + next + + me.flush + updateCell uploading, bandwidth + +End Sub + +CUploadsController.getUploadIPAndPort: +Function getUploadIPAndPort(index as integer) As string + + dim c as CUploadModel = CUploadModel(me.representedObjects(index)) + + if c.isBrowseHostEnabled then return c.ip + ":" + c.port + +End Function + +CAppController.UnhandledException: +Function UnhandledException(error As RuntimeException) As Boolean + + System.debugLog error.message + return true + +End Function + +CAppController.Open: +Sub Open() + + initializeDefaults + initializeLocalization + initializePreferences + initializeResources + initializeColors + + localizeSubMenus getMenuHandle(CWindow1.handle), me.menuBar + drawMenuItems CWindow1.handle + + CWindow1.show + CWindow1.loadSplitterPosition + +End Sub + +CAppController.EnableMenuItems: +Sub EnableMenuItems() + + #if targetWin32 or targetLinux + FileMainWindow.enabled = false + + #endif + +End Sub + +CAppController.Close: +Sub Close() + + finalizeLocalization + finalizeResources + finalizePreferences + finalizeDefaults + +End Sub + +CAppController.Activate: +Sub Activate() + + if me.isFinalized = false then notifyStop CWindow1 + + #if targetMachO + if CWindow1.visible = false then CWindow1.show + + #endif + +End Sub + +CWindow1.askQuitting: +Function askQuitting() As boolean + + dim m as messageDialog + + if kAqWarnQuit and me.CDownloadsController1.hasActiveTransfers then + m = getDialog( _ + getLocalizedString("Do you really wish to quit?", "Dialogs"), _ + getLocalizedString("Cabos is actively downloading files. Quitting will terminate these downloads and there is no guarantee that they will proceed successfully at a later time.", "Dialogs"), _ + getLocalizedString("Quit", "Dialogs"), _ + getLocalizedString("Cancel", "Dialogs")) + + if m.showModal = m.cancelButton then return false //Cancel + + end + + return true //Quit + +End Function + +CWindow1.preFinalize: +Sub preFinalize() + + me.CCoreController1.shutdown + + #if targetMacOS + self.show + + #endif + + CWindow2.showModalWithin me + +End Sub + +CWindow1.loadSplitterPosition: +Sub loadSplitterPosition() + + //* restore splitter position *// + + dim result as integer = 170 + result = defaultsRead("CSplitter kAqMainSplitterLeft" , result) + + if self.CSplitter1.left <> result then setSplitter result + +End Sub + +CWindow1.setSplitter: +Sub setSplitter(position as integer) + position = min(position, self.width - 10 - self.CEditField2.width - self.CStaticText2.width - self.PopupMenu1.width - self.CStaticText1.width - self.CSplitter1.width) + position = max(position, self.CListBox1.left + CListBox.kScrollbarWidth) + + self.CSplitter1.left = position + + //* control order is important! *// + + self.CEditField1.width = self.CSplitter1.left - self.CEditField1.left + self.CListBox1.width = self.CSplitter1.left - self.CListBox1.left + self.CListBox1.textSize = self.CListBox1.textSize + self.CListBox6.width = self.CSplitter1.left - self.CListBox6.left + self.CListBox6.textSize = self.CListBox6.textSize + self.CToolbar1.left = self.CSplitter1.left + self.CSplitter1.width + self.CToolbar1.width = self.width - 10 - self.CToolbar1.left + + self.PagePanel1.left = self.CSplitter1.left + 5 + self.PagePanel1.width = self.width - self.PagePanel1.left - 5 + self.CListBox3.width = self.PagePanel1.width - 10 + self.CListBox3.textSize = self.CListBox3.textSize + self.CListBox4.width = self.PagePanel1.width - 10 + self.CListBox4.textSize = self.CListBox4.textSize + self.CListBox5.width = self.PagePanel1.width - 10 + self.CListBox5.textSize = self.CListBox5.textSize + self.CListBox2.width = self.PagePanel1.width - 10 + self.CListBox2.textSize = self.CListBox2.textSize + + self.CEditField2.left = self.width - 10 - self.CEditField2.width + self.Slider2.left = self.CEditField2.left + self.Slider4.left = self.CEditField2.left + + self.CStaticText2.left = self.CEditField2.left - 5 - self.CStaticText2.width + self.CStaticText4.left = self.CStaticText2.left + self.CStaticText6.left = self.CStaticText2.left + + self.PopupMenu1.left = self.CStaticText2.left - 5 - self.PopupMenu1.width + self.Slider1.left = self.PopupMenu1.left + self.Slider3.left = self.PopupMenu1.left + + self.CStaticText1.left = self.PopupMenu1.left - 5 - self.CStaticText1.width + self.CStaticText3.left = self.CStaticText1.left + self.CStaticText5.left = self.CStaticText1.left + + self.refresh + +End Sub + +CWindow1.Resized: +Sub Resized() + + setSplitter self.CSplitter1.left + +End Sub + +CWindow1.EnableMenuItems: +Sub EnableMenuItems() + + dim i as integer + + if me.CListBox3.listCount <> 0 then FileConnect.enabled = false + + if me.CListBox1.listIndex = -1 then + SearchStartSelectedSearches.enabled = false + SearchStopSelectedSearches.enabled = false + SearchDeleteSelectedSearches.enabled = false + + end + + if me.PagePanel1.value <> 4 or me.CListBox2.listIndex = -1 then + EditConvertSelectedTags.item(0).enabled = false + EditConvertSelectedTags.item(1).enabled = false + 'EditConvertSelectedTags.item(2).enabled = false + + end + + if me.CListBox1.listCount = 0 then + SearchClearSearchSidebar.enabled = false + 'SearchStartAllQueries.enabled = false + + end + + ViewFilterResults.enabled = (me.PagePanel1.value = 4) + + select case me.PagePanel1.value + + case 2 //* downloads *// + TransfersDownloadSelected.enabled = false + + if me.CListBox4.listIndex = -1 then + TransfersRevealFileinFinder.enabled = false + TransfersOpenSelectedFile.enabled = false + TransfersCancelTransfer.enabled = false + + end + + case 3 //* uploads *// + TransfersDownloadSelected.enabled = false + + if me.CListBox5.listIndex = -1 then + TransfersRevealFileinFinder.enabled = false + TransfersOpenSelectedFile.enabled = false + TransfersCancelTransfer.enabled = false + + end + + case 4 //* network *// + if me.ClistBox2.listIndex = -1 then TransfersDownloadSelected.enabled = false + + TransfersRevealFileinFinder.enabled = false + TransfersOpenSelectedFile.enabled = false + TransfersCancelTransfer.enabled = false + + else + TransfersDownloadSelected.enabled = false + TransfersRevealFileinFinder.enabled = false + TransfersOpenSelectedFile.enabled = false + TransfersCancelTransfer.enabled = false + + end + +End Sub + +CWindow1.CancelClose: +Function CancelClose(appQuitting as Boolean) As Boolean + + if appQuitting or App.isFinalized then return false + + #if targetMacOS + me.hide + + #elseif targetWin32 or targetLinux + if me.askQuitting then me.preFinalize + + #endif + + return true + +End Function + +CWindow1.Close: +Sub Close() + + me.saveSizeAndState "kAqMainWindow" + + //* Finalize Controllers *// + + me.CQueryController1.Finalize + +End Sub + +CWindow1.Open: +Sub Open() + + me.loadSizeAndState "kAqMainWindow" + + //* Initialize Controllers *// + + me.CMenuActionsController1.Initialize _ + me.CCoreController1, me.CQueryController1, me.CFilterController1, me.CNetworkController1, me.CDownloadsController1, me.CUploadsController1 + me.CQueryController1.Initialize me.CCoreController1, me.CFilterController1, me.CFileurnsController1, me.CDownloadsController1 + me.CFilterController1.Initialize me.CQueryController1 + me.CCoreController1.Initialize _ + me.CNetworkController1, me.CQueryController1, me.CDownloadsController1, me.CUploadsController1, me.CFileurnsController1, CFilterController1 + +End Sub + +CWindow1.CEditField1.MouseDown: +Function MouseDown(X As Integer, Y As Integer) As Boolean + + if isCMMClick then + return self.CEditMenuController1.openEditMenu(me) + + end + +End Function + +CWindow1.CEditField1.Open: +Sub Open() + + me.textSize = kMiddleTextSize + +End Sub + +CWindow1.CEditField1.KeyDown: +Function KeyDown(key as string) As boolean + + if key.ascb = 13 or key.ascb = 3 then + self.CQueryController1.handleQueryNormal me.text + me.text="" + return true + + end + +End Function + +CWindow1.PagePanel1.Change: +Sub Change() + + self.CToolbar1.visible = false + self.CToolbar1.clearMenu + + select case me.value + + case 0 //* sidebar *// + self.setTitle getLocalizedString("Cabos", "Window") + + case 1 //* network *// + self.setTitle getLocalizedString("Cabos - Network", "Window") + self.CToolbar1.appendMenu getLocalizedString("Browse", "Toolbar"), _ + getLocalizedString("Browse Host", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Remove", "Toolbar"), _ + getLocalizedString("Remove Connection", "Toolbar") + + case 2 //* downloads *// + self.setTitle getLocalizedString("Cabos - Downloads", "Window") + self.CToolbar1.appendMenu getLocalizedString("Browse", "Toolbar"), _ + getLocalizedString("Browse Host", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Remove", "Toolbar"), _ + getLocalizedString("Remove Download", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Clear", "Toolbar"), _ + getLocalizedString("Clear Completed", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Reveal", "Toolbar"), _ + getLocalizedString("Reveal in Finder", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Resume", "Toolbar"), _ + getLocalizedString("Resume Download", "Toolbar") + + #if targetMachO or targetWin32 or targetLinux + self.CToolbar1.appendMenu getLocalizedString("Pause", "Toolbar"), _ + getLocalizedString("Pause Download", "Toolbar") + + #endif + + case 3 //* uploads *// + self.setTitle getLocalizedString("Cabos - Uploads", "Window") + self.CToolbar1.appendMenu getLocalizedString("Browse", "Toolbar"), _ + getLocalizedString("Browse Host", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Remove", "Toolbar"), _ + getLocalizedString("Remove Upload", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Clear", "Toolbar"), _ + getLocalizedString("Clear Completed", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Reveal", "Toolbar"), _ + getLocalizedString("Reveal in Finder", "Toolbar") + + case 4 //* query results *// + self.setTitle getLocalizedStringWithStringData("Cabos - %@", "Window", _ + self.CQueryController1.getQueryString) + self.CToolbar1.appendMenu getLocalizedString("Browse", "Toolbar"), _ + getLocalizedString("Browse Host", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Download", "Toolbar"), _ + getLocalizedString("Download Selected Files", "Toolbar") + self.CToolbar1.appendMenu getLocalizedString("Filter", "Toolbar"), _ + getLocalizedString("Filter Results", "Toolbar") + + end + + self.CToolbar1.visible = true + +End Sub + +CWindow1.CNetworkController1.updateDataSource: +Sub updateDataSource(c() as CStatsModel) + + self.CListBox3.dataSourceChanged c + +End Sub + +CWindow1.CNetworkController1.updateCell: +Sub updateCell(online as variant) + + if online <> 0 then + CSidebarModel(self.CListBox6.dataSource(0)).pState = online + + else + CSidebarModel(self.CListBox6.dataSource(0)).pState = nil + + end + + self.CListBox6.list(0) = "" + +End Sub + +CWindow1.CQueryController1.selectCell: +Sub selectCell(index as integer) + + self.CListBox1.listIndex = index + +End Sub + +CWindow1.CQueryController1.updateDataSource: +Sub updateDataSource(c() as CStatsModel) + + self.CListBox2.saveSelectedItems + self.CListBox2.dataSourceChanged c + self.CListBox2.restoreSelectedItems + +End Sub + +CWindow1.CQueryController1.updateCell: +Sub updateCell(c() as CStatsModel) + + self.CListBox1.dataSourceChanged c + self.CListBox1.addOrRemoveScrollbar + +End Sub + +CWindow1.CDownloadsController1.updateDataSource: +Sub updateDataSource(c() as CStatsModel) + + self.CListBox4.dataSourceChanged c + +End Sub + +CWindow1.CDownloadsController1.downloadCompleted: +Sub downloadCompleted(c as CDownloadModel) + + if kAqBounceDockIcon then notifyStart self + + if kAqImportMusicFile = 0 or c.fileName.isiTunesAudio = false then return + + #if targetMacOS + if targetLeopard then return + + dim playlistIndex as integer + dim trackID as integer + dim f as folderItem + + try + if self.CiTunesController1.LaunchiTunes = false then return + + f = getPath2FolderItem(c.path) + + if f = nil then return + + trackID = self.CiTunesController1.addFileToLibrary(f) + + if trackID = -1 then return + + if kAqImportMusicFile = 2 then + playlistIndex = self.CiTunesController1.getPlaylistIndex(kiTunesPlaylistName) + + if playlistIndex < 1 then + playlistIndex = self.CiTunesController1.makePlaylist(kiTunesPlaylistName) + //fix iTunes bug + playlistIndex = self.CiTunesController1.getPlaylistIndex(kiTunesPlaylistName) + end + + trackID = self.CiTunesController1.addTrackToPlaylist(trackID, playlistIndex) + + if trackID = -1 then return + + end + + select case kAqPlaySong + + case 0 //* Do not play the song *// + + case 1 //* Play the song *// + if kAqImportMusicFile = 2 then + if self.CiTunesController1.play(trackID, playlistIndex) = false then return + + else + if self.CiTunesController1.play(trackID) = false then return + + end + + case 2 //* Play the song if nothing else is playing *// + if self.CiTunesController1.getPlayerState = 1 then return + + if kAqImportMusicFile = 2 then + if self.CiTunesController1.play(trackID, playlistIndex) = false then return + + else + if self.CiTunesController1.play(trackID) = false then return + + end + + case 3 //* Add to iTunes "Party Shuffle" *// + playlistIndex = 2 + + if self.CiTunesController1.addTrackToPlaylist(trackID, playlistIndex) = -1 then return + + end + + if kAqDeleteAfterImport then f.delete + + catch + + end + + #elseif targetWin32 + dim track as OLEObject + dim partyShufflePlaylist as string + dim f as folderItem + + try + f = getPath2FolderItem(c.path) + + if f = nil then return + + track = self.CiTunesController1.addFileToLibrary(f) + + if track = nil then return + + if kAqImportMusicFile = 2 then + if self.CiTunesController1.getPlaylistIndex(kiTunesPlaylistName) = 0 and _ + self.CiTunesController1.makePlaylist(kiTunesPlaylistName) = false then return + + track = self.CiTunesController1.addTrackToPlaylist(track, kiTunesPlaylistName) + + if track = nil then return + + end + + select case kAqPlaySong + + case 0 //* Do not play the song *// + + case 1 //* Play the song *// + if self.CiTunesController1.play(track) = false then return + + case 2 //* Play the song if nothing else is playing *// + if self.CiTunesController1.getPlayerState = 1 then return + + if self.CiTunesController1.play(track) = false then return + + case 3 //* Add to iTunes "Party Shuffle" *// + partyShufflePlaylist = self.CiTunesController1.getPlaylistName(2) + + if self.CiTunesController1.addTrackToPlaylist(track, partyShufflePlaylist) = nil then return + + end + + if kAqDeleteAfterImport then f.delete + + catch + + end + + #elseif targetLinux + 'todo + + #endif + +End Sub + +CWindow1.CDownloadsController1.updateCell: +Sub updateCell(downloading as variant, negociating as variant, bandwidth as double) + + if kAqNetBandwidth and downloading <> 0 and bandwidth <> 0 then + CSidebarModel(self.CListBox6.dataSource(1)).caption = bandwidth.getKbs + CSidebarModel(self.CListBox6.dataSource(1)).pState = downloading + "/" + negociating + + elseif downloading <> 0 or negociating <> 0 then + CSidebarModel(self.CListBox6.dataSource(1)).caption = getLocalizedString("Downloads", "ListBox") + CSidebarModel(self.CListBox6.dataSource(1)).pState = downloading + "/" + negociating + + else + CSidebarModel(self.CListBox6.dataSource(1)).caption = getLocalizedString("Downloads", "ListBox") + CSidebarModel(self.CListBox6.dataSource(1)).pState = nil + + end + + self.CListBox6.list(1) = "" + +End Sub + +CWindow1.CUploadsController1.updateDataSource: +Sub updateDataSource(c() as CStatsModel) + + 'self.CListBox5.saveSelectedItems + self.CListBox5.dataSourceChanged c + 'self.CListBox5.restoreSelectedItems + +End Sub + +CWindow1.CUploadsController1.updateCell: +Sub updateCell(uploading as variant, bandwidth as double) + + if kAqNetBandwidth and bandwidth <> 0 then + CSidebarModel(self.CListBox6.dataSource(2)).caption = bandwidth.getKbs + CSidebarModel(self.CListBox6.dataSource(2)).pState = uploading + + elseif uploading <> 0 then + CSidebarModel(self.CListBox6.dataSource(2)).caption = getLocalizedString("Uploads", "ListBox") + CSidebarModel(self.CListBox6.dataSource(2)).pState = uploading + + else + CSidebarModel(self.CListBox6.dataSource(2)).caption = getLocalizedString("Uploads", "ListBox") + CSidebarModel(self.CListBox6.dataSource(2)).pState = nil + + end + + self.CListBox6.list(2) = "" + +End Sub + +CWindow1.CMenuActionsController1.askOpening: +Function askOpening() As boolean + + dim m as messageDialog = getDialog( _ + getlocalizedString("Do you really wish to open the selected file?", "Dialogs"), _ + getLocalizedString("Cabos is trying to open incomplete file and current downloads may be affected.", "Dialogs"), _ + getLocalizedString("Open File", "Dialogs"), _ + getLocalizedString("Cancel", "Dialogs")) + + return (m.showModal = m.actionButton) + +End Function + +CWindow1.CMenuActionsController1.openPreferences: +Sub openPreferences() + + CWindow4.CHierarchicalListBox1.collapseAll + CWindow4.CHierarchicalListBox1.expanded(1) = true + 'CWindow4.show + +End Sub + +CWindow1.CMenuActionsController1.askRemoving: +Function askRemoving() As boolean + + dim m as messageDialog = getDialog( _ + getlocalizedString("Do you really wish to remove the selected files?", "Dialogs"), _ + getLocalizedString("Removing the selected files cannot be undone and whatever data has already been downloaded will be deleted.", "Dialogs"), _ + getLocalizedString("Remove Files", "Dialogs"), _ + getLocalizedString("Cancel", "Dialogs")) + + return (m.showModal = m.actionButton) + +End Function + +CWindow1.CFilterController1.filterChanged: +Sub filterChanged(c as CFilterModel) + + //* control order is important! *// + dim i as integer + + i = (c.bitrate / 320) * self.Slider2.maximum + if self.Slider2.value <> i then self.Slider2.value = i + + i = (c.speed / 1000) * self.Slider4.maximum + if self.Slider4.value <> i then self.Slider4.value = i + + if self.CEditField2.text <> c.keyword then self.CEditField2.text = c.keyword + + if self.PopupMenu1.listIndex <> c.media then self.PopupMenu1.listIndex = c.media + + i = (c.size / 104857600) * self.Slider1.maximum + if self.Slider1.value <> i then self.Slider1.value = i + + i = (c.sources / 10) * self.Slider3.maximum + if self.Slider3.value <> i then self.Slider3.value = i + + self.CToolbar1.setKeepPressed c.enabled + + if self.CEditField2.visible <> c.enabled then + self.PagePanel1.visible = false + + if c.enabled then + self.CListBox2.top = self.CListBox1.top + self.CListBox6.height + 6 + self.CListBox2.height = self.CListBox1.height + end + + self.CEditField2.visible = c.enabled + self.Slider2.visible = c.enabled + self.Slider4.visible = c.enabled + + self.CStaticText2.visible = c.enabled + self.CStaticText4.visible = c.enabled + self.CStaticText6.visible = c.enabled + + self.PopupMenu1.visible = c.enabled + self.Slider1.visible = c.enabled + self.Slider3.visible = c.enabled + + self.CStaticText1.visible = c.enabled + self.CStaticText3.visible = c.enabled + self.CStaticText5.visible = c.enabled + + if c.enabled = false then + self.CListBox2.top = self.CListBox1.top + self.CListBox2.height = self.CListBox1.height + 6 + self.CListBox6.height + end + + self.PagePanel1.visible = true + + end + + if c.sortColumn <> -1 and self.CListBox2.columnSortDirection(c.sortColumn) <> c.sortDirection then _ + self.CListBox2.columnSortDirection(c.sortColumn) = c.sortDirection + + if self.CListBox2.sortedColumn <> c.sortColumn then + self.CListBox2.headingIndex = c.sortColumn + self.CListBox2.sortedColumn = c.sortColumn + + end + + if self.CListBox2.columnWidths <> c.columnWidths then _ + self.CListBox2.setColumnWidths c.columnWidths + + if self.CListBox2.scrollPosition <> c.scrollPosition then _ + self.CListBox2.scrollPosition = c.scrollPosition + +End Sub + +CWindow1.CCoreController1.coreCrashed: +Sub coreCrashed() + + App.isFinalized = true + CWindow2.close + Quit + +End Sub + +CWindow1.CCoreController1.coreBlockedByFirewall: +Sub coreBlockedByFirewall() + + dim m as messageDialog = getDialog( _ + getLocalizedString("Cabos was unable to initialize.", "Dialogs"), _ + getLocalizedString("This is usually due to a personal firewall blocking Java access to the internet. Please allow Java access to the internet and restart Cabos.", "Dialogs"), _ + getLocalizedString("More Info...", "Dialogs"), _ + getLocalizedString("Quit", "Dialogs")) + + if m.showModal = m.actionButton then showURL "http://sourceforge.jp/projects/cabos/forums/" + + App.isFinalized = true + Quit + +End Sub + +CWindow1.CCoreController1.coreCorrupted: +Sub coreCorrupted() + + dim m as messageDialog = getDialog( _ + getLocalizedString("Your copy of Cabos is corrupted.", "Dialogs"), _ + getLocalizedString("Certain files necessary for the program are either missing or corrupted. Please redownload the application to fix this situation.", "Dialogs"), _ + getLocalizedString("More Info...", "Dialogs"), _ + getLocalizedString("Quit", "Dialogs")) + + if m.showModal = m.actionButton then showURL "http://cabos.sourceforge.jp/" + + App.isFinalized = true + Quit + +End Sub + +CWindow1.CCoreController1.coreStopped: +Sub coreStopped() + + App.isFinalized = true + CWindow2.close + Quit + +End Sub + +CWindow1.CCoreController1.coreLoadingError: +Sub coreLoadingError() + + dim m as messageDialog = getDialog( _ + getLocalizedString("The Java software cannot be loaded.", "Dialogs"), _ + getLocalizedString("Please visit Java software site to easily obtain the Java software.", "Dialogs"), _ + getLocalizedString("More Info...", "Dialogs"), _ + getLocalizedString("Quit", "Dialogs")) + + if m.showModal = m.actionButton then showURL "http://www.java.com/" + + App.isFinalized = true + CWindow2.close + Quit + +End Sub + +CWindow1.CCoreController1.coreStarted: +Sub coreStarted() + + #if not targetMachO and targetCarbon + call hideApplication "CabosCore" + + #endif + + if ubound(kAqSharedDirectories) <> -1 then return + + dim m as messageDialog = getDialog( _ + getLocalizedString("You should share some files.", "Dialogs"), _ + getLocalizedString("The Gnutella network benefits when users share files. You will likely be rewarded with greater success finding and downloading files.", "Dialogs"), _ + getLocalizedString("Share Files...", "Dialogs"), _ + getLocalizedString("Later", "Dialogs")) + + dim f as folderItem + + if m.showModal = m.actionButton then + CWindow4.CHierarchicalListBox1.collapseAll + CWindow4.CHierarchicalListBox1.expanded(5) = true + CWindow4.CHierarchicalListBox1.listIndex = 6 + CWindow4.show + f = selectFolder + + if f <> nil and kAqSharedDirectories.indexOf(f.posixPath) = -1 then + kAqSharedDirectories.append f.posixPath + CWindow4.CHierarchicalListBox1.valueChanged 5, 1 + CWindow4.CHierarchicalListBox1.expanded(5) = false + CWindow4.CHierarchicalListBox1.expanded(5) = true + + end + + end + +End Sub + +CWindow1.CToolbar1.Action: +Sub Action(item as string) + + select case self.PagePanel1.value + + case 0 //* sidebar *// + //self.CMenuActionsController1.openSidebarMenu self.CListBox1 + + case 1 //* network *// + self.CMenuActionsController1.openNetworkMenu self.CListBox3, item + + case 2 //* downloads *// + self.CMenuActionsController1.openDownloadsMenu self.CListBox4, item + + case 3 //* uploads *// + self.CMenuActionsController1.openUploadsMenu self.CListBox5, item + + case 4 //* query results *// + self.CMenuActionsController1.openResponseMenu self.CListBox2, item + + end + +End Sub + +CWindow1.CSplitter1.Close: +Sub Close() + //* save splitter position *// + + defaultsWrite "CSplitter kAqMainSplitterLeft", me.left + +End Sub + +CWindow1.CSplitter1.Open: +Sub Open() + + me.mouseCursor = resizeCursor + +End Sub + +CWindow1.CSplitter1.MouseUp: +Sub MouseUp(X As Integer, Y As Integer) + + me.isDragging = false + + //* double click action *// + + if self.CEditField1.width = me.left - 10 then + if me.singleClicked = false then + me.singleClicked = true + me.mouseCursor = arrowCursor + me.refresh + return + + else + me.singleClicked = false + me.mouseCursor = resizeCursor + + if me.left <> self.CListBox1.left + CListBox.kScrollbarWidth then + me.left = self.CListBox1.left + CListBox.kScrollbarWidth + + else + me.left = 170 + + end + + end + + end + + setSplitter me.left + +End Sub + +CWindow1.CSplitter1.MouseMove: +Sub MouseMove(X As Integer, Y As Integer) + + #if targetMacOS + if me.singleClicked then + me.singleClicked = false + me.mouseCursor = resizeCursor + + end + + #endif + +End Sub + +CWindow1.CSplitter1.MouseDrag: +Sub MouseDrag(X As Integer, Y As Integer) + + me.left = min(max(me.left - (me.targetX - x), self.CListBox1.left + CListBox.kScrollbarWidth), _ + self.width - 10 - self.CEditField2.width - self.CStaticText2.width - self.PopupMenu1.width - self.CStaticText1.width - me.width) + me.refresh + +End Sub + +CWindow1.CSplitter1.MouseDown: +Function MouseDown(X As Integer, Y As Integer) As Boolean + + me.targetX = x + me.isDragging = true + return true + +End Function + +CWindow1.CSplitter1.MouseExit: +Sub MouseExit() + + me.singleClicked = false + me.mouseCursor = resizeCursor + +End Sub + +CWindow1.CSplitter1.Paint: +Sub Paint(g As Graphics) + + if me.isDragging then + g.foreColor = &c101010 + g.drawRect 0, 0, g.width, g.height + + end + +End Sub + +CWindow1.Slider1.Open: +Sub Open() + + #if targetMacOS + me.top = me.top + 4 + + #endif + +End Sub + +CWindow1.Slider1.ValueChanged: +Sub ValueChanged() + + dim i as integer = (me.value / me.maximum) * 104857600 + + me.helpTag = i.getShortSize + self.CFilterController1.setSizeFilter i + self.CFilterController1.filterResults + +End Sub + +CWindow1.Slider2.Open: +Sub Open() + + #if targetMacOS + me.top = me.top + 4 + + #endif + +End Sub + +CWindow1.Slider2.ValueChanged: +Sub ValueChanged() + + dim i as integer = (me.value / me.maximum) * 320 + + me.helpTag = i.getKbps + self.CFilterController1.setBitrateFilter i + self.CFilterController1.filterResults + +End Sub + +CWindow1.CEditField2.Open: +Sub Open() + + me.textSize = kMiddleTextSize + +End Sub + +CWindow1.CEditField2.TextChange: +Sub TextChange() + + self.CFilterController1.setKeywordFilter me.text + self.CFilterController1.filterResults + +End Sub + +CWindow1.CStaticText1.Open: +Sub Open() + + me.textSize = kSmallTextSize + +End Sub + +CWindow1.CStaticText2.Open: +Sub Open() + + me.textSize = kSmallTextSize + +End Sub + +CWindow1.CStaticText3.Open: +Sub Open() + + me.textSize = kSmallTextSize + +End Sub + +CWindow1.CStaticText4.Open: +Sub Open() + + me.textSize = kSmallTextSize + +End Sub + +CWindow1.Slider3.Open: +Sub Open() + + #if targetMacOS + me.top = me.top + 4 + + #endif + +End Sub + +CWindow1.Slider3.ValueChanged: +Sub ValueChanged() + + dim i as integer = (me.value / me.maximum) * 10 + + me.helpTag = str(i) + self.CFilterController1.setSourcesFilter i + self.CFilterController1.filterResults + +End Sub + +CWindow1.Slider4.Open: +Sub Open() + + #if targetMacOS + me.top = me.top + 4 + + #endif + +End Sub + +CWindow1.Slider4.ValueChanged: +Sub ValueChanged() + + dim i as integer = (me.value / me.maximum) * 1000 + + me.helpTag = i.getKb + self.CFilterController1.setSpeedFilter i + self.CFilterController1.filterResults + +End Sub + +CWindow1.CStaticText5.Open: +Sub Open() + + me.textSize = kSmallTextSize + +End Sub + +CWindow1.CStaticText6.Open: +Sub Open() + + me.textSize = kSmallTextSize + +End Sub + +CWindow1.CListBox4.SortColumn: +Function SortColumn(column As Integer) As Boolean + + self.CDownloadsController1.sort column, me.columnSortDirection(column) + return true + +End Function + +CWindow1.CListBox4.KeyDown: +Function KeyDown(key As String) As Boolean + + select case key.ascb + + case 8, 127 + self.CMenuActionsController1.actionDownloadsRemove me + return true + + case 13, 3 + self.CMenuActionsController1.actionDownloadsOpen me + return true + + case 28, 29 + clearFocus + self.CListBox1.setFocus + return true + + end + +End Function + +CWindow1.CListBox4.DoubleClick: +Sub DoubleClick() + + self.CMenuActionsController1.actionDownloadsOpen me + +End Sub + +CWindow1.CListBox4.CMMClicked: +Sub CMMClicked() + + self.CMenuActionsController1.openDownloadsMenu me + +End Sub + +CWindow1.CListBox4.Open: +Sub Open() + + me.textFont = kAqStandardTextFont + me.textSize = kAqStandardTextSize + + dim result as string + + result = defaultsRead("CListBox kAqDownloadsColumnWidths", result) + me.setColumnWidths result + + me.columnSortDirection(2) = ListBox.sortDescending + me.columnSortDirection(3) = ListBox.sortDescending + me.columnSortDirection(4) = ListBox.sortDescending + +End Sub + +CWindow1.CListBox4.Close: +Sub Close() + + defaultsWrite "CListBox kAqDownloadsColumnWidths", me.columnWidths + +End Sub + +CWindow1.CListBox4.HeaderCMMClicked: +Sub HeaderCMMClicked() + + self.CMenuActionsController1.openHeadingMenu me + +End Sub + +CWindow1.CListBox5.DoubleClick: +Sub DoubleClick() + + self.CMenuActionsController1.actionUploadsOpen me + +End Sub + +CWindow1.CListBox5.KeyDown: +Function KeyDown(key As String) As Boolean + + select case key.ascb + + case 8, 127 + self.CMenuActionsController1.actionUploadsRemove me + return true + + case 13, 3 + self.CMenuActionsController1.actionUploadsOpen me + return true + + case 28, 29 + clearFocus + self.CListBox1.setFocus + return true + + end + +End Function + +CWindow1.CListBox5.CMMClicked: +Sub CMMClicked() + + self.CMenuActionsController1.openUploadsMenu me + +End Sub + +CWindow1.CListBox5.SortColumn: +Function SortColumn(column As Integer) As Boolean + + self.CUploadsController1.sort column, me.columnSortDirection(column) + return true + +End Function + +CWindow1.CListBox5.Close: +Sub Close() + + defaultsWrite "CListBox kAqUploadsColumnWidths", me.columnWidths + +End Sub + +CWindow1.CListBox5.Open: +Sub Open() + + me.textFont = kAqStandardTextFont + me.textSize = kAqStandardTextSize + + dim result as string + + result = defaultsRead("CListBox kAqUploadsColumnWidths", result) + me.setColumnWidths result + + me.columnSortDirection(2) = ListBox.sortDescending + me.columnSortDirection(3) = ListBox.sortDescending + me.columnSortDirection(4) = ListBox.sortDescending + +End Sub + +CWindow1.CListBox5.HeaderCMMClicked: +Sub HeaderCMMClicked() + + self.CMenuActionsController1.openHeadingMenu me + +End Sub + +CWindow1.CListBox3.SortColumn: +Function SortColumn(column As Integer) As Boolean + + self.CNetworkController1.sort column, me.columnSortDirection(column) + return true + +End Function + +CWindow1.CListBox3.KeyDown: +Function KeyDown(key As String) As Boolean + + select case key.ascb + + case 28, 29 + clearFocus + self.CListBox1.setFocus + return true + + case 8, 127 + self.CMenuActionsController1.actionNetworkRemove me + return true + + end + +End Function + +CWindow1.CListBox3.Close: +Sub Close() + + defaultsWrite "CListBox kAqNetworkConnectionsColumnWidths", me.columnWidths + +End Sub + +CWindow1.CListBox3.CMMClicked: +Sub CMMClicked() + + self.CMenuActionsController1.openNetworkMenu me + +End Sub + +CWindow1.CListBox3.Open: +Sub Open() + + me.textFont = kAqStandardTextFont + me.textSize = kAqStandardTextSize + + dim result as string + + result = defaultsRead("CListBox kAqNetworkConnectionsColumnWidths", result) + me.setColumnWidths result + + me.columnSortDirection(4) = ListBox.sortDescending + +End Sub + +CWindow1.CListBox3.HeaderCMMClicked: +Sub HeaderCMMClicked() + + self.CMenuActionsController1.openHeadingMenu me + +End Sub + +CWindow1.CListBox2.HeaderPressed: +Function HeaderPressed(column as Integer) As Boolean + + self.CFilterController1.setSortColumn column + + if column <> -1 then + self.CFilterController1.setSortDirection me.columnSortDirection(column) + + else + self.CFilterController1.setSortDirection ListBox.sortAscending + + end + +End Function + +CWindow1.CListBox2.SortColumn: +Function SortColumn(column As Integer) As Boolean + + self.CFilterController1.updateResults + return true + +End Function + +CWindow1.CListBox2.KeyDown: +Function KeyDown(key As String) As Boolean + + select case key.ascb + + case 13, 3 + self.CMenuActionsController1.actionResponseDownload me + return true + + case 28, 29 + clearFocus + self.CListBox1.setFocus + return true + + case 8, 127 + self.CMenuActionsController1.actionResponseSpam me + return true + + end + +End Function + +CWindow1.CListBox2.DoubleClick: +Sub DoubleClick() + + self.CMenuActionsController1.actionResponseDownload me + +End Sub + +CWindow1.CListBox2.Close: +Sub Close() + + 'defaultsWrite "CListBox kAqResponseColumnWidths", me.columnWidths + +End Sub + +CWindow1.CListBox2.CMMClicked: +Sub CMMClicked() + + self.CMenuActionsController1.openResponseMenu me + +End Sub + +CWindow1.CListBox2.Open: +Sub Open() + + me.textFont = kAqStandardTextFont + me.textSize = kAqStandardTextSize + + 'dim result as string + ' + 'result = defaultsRead("CListBox kAqResponseColumnWidths", result) + 'me.setColumnWidths result + + me.columnSortDirection(4) = ListBox.sortDescending + me.columnSortDirection(5) = ListBox.sortDescending + me.columnSortDirection(6) = ListBox.sortDescending + me.columnSortDirection(7) = ListBox.sortDescending + me.columnSortDirection(8) = ListBox.sortDescending + +End Sub + +CWindow1.CListBox2.HeaderCMMClicked: +Sub HeaderCMMClicked() + + self.CMenuActionsController1.openHeadingMenu me + +End Sub + +CWindow1.CListBox6.KeyDown: +Function KeyDown(key As String) As Boolean + + select case key.ascb + + case 28, 29 + clearFocus + + select case self.PagePanel1.value + + case 1 + self.CListBox3.setFocus + + case 2 + self.CListBox4.setFocus + + case 3 + self.CListBox5.setFocus + + case 4 + self.CListBox2.setFocus + + end + + return true + + end + +End Function + +CWindow1.CListBox6.Change: +Sub Change() + + self.PagePanel1.value = me.listIndex + 1 + +End Sub + +CWindow1.CListBox6.Open: +Sub Open() + + me.textFont = kAqSidebarTextFont + me.textSize = kAqSidebarTextSize + + dim c(2) as CStatsModel + + c(0) = new CSidebarModel(getLocalizedString("Network", "ListBox")) + c(1) = new CSidebarModel(getLocalizedString("Downloads", "ListBox")) + c(2) = new CSidebarModel(getLocalizedString("Uploads", "ListBox")) + + me.dataSourceChanged c + + #if targetWin32 or targetLinux//* to clear scrollbar *// + me.top = me.top - 2 + me.height = me.height + 2 + + #endif + +End Sub + +CWindow1.CListBox1.DoubleClick: +Sub DoubleClick() + + if CStatsModel(me.dataSource(me.listIndex)).getRepresentation < 0 then + self.CQueryController1.startQuery CStatsModel(me.dataSource(me.listIndex)).getRepresentation, false + + else + self.CQueryController1.stopQuery CStatsModel(me.dataSource(me.listIndex)).getRepresentation + + end + +End Sub + +CWindow1.CListBox1.MouseMove: +Sub MouseMove(row as integer, column as integer, x as integer, y as integer) + + if row <> -1 and x > 3 and x < 21 then + me.mouseCursor = handCursor + + else + me.mouseCursor = arrowCursor + + end + +End Sub + +CWindow1.CListBox1.DragReorderRows: +Function DragReorderRows(newPosition as Integer) As Boolean + + self.CQueryController1.reorderSidebarDatasource newPosition, me.getSelectedRows + + return true + +End Function + +CWindow1.CListBox1.CellClick: +Function CellClick(row as Integer, column as Integer, x as Integer, y as Integer) As Boolean + + if x > 3 and x < 21 then + if CStatsModel(me.dataSource(row)).getRepresentation < 0 then + self.CQueryController1.startQuery CStatsModel(me.dataSource(row)).getRepresentation, false + + else + self.CQueryController1.stopQuery CStatsModel(me.dataSource(row)).getRepresentation + + end + + return true + + end + +End Function + +CWindow1.CListBox1.KeyDown: +Function KeyDown(key As String) As Boolean + + select case key.ascb + + 'case 32 + 'me.listIndex = me.listIndex + 'return true + + case 28, 29 + clearFocus + + select case self.PagePanel1.value + + case 1 + self.CListBox3.setFocus + + case 2 + self.CListBox4.setFocus + + case 3 + self.CListBox5.setFocus + + case 4 + self.CListBox2.setFocus + + end + + return true + + case 8, 127 + self.CMenuActionsController1.actionSidebarRemove me + return true + + end + +End Function + +CWindow1.CListBox1.CMMClicked: +Sub CMMClicked() + + self.CMenuActionsController1.openSidebarMenu me + +End Sub + +CWindow1.CListBox1.Close: +Sub Close() + + self.CFilterController1.setColumnWidths self.CListBox2.columnWidths + +End Sub + +CWindow1.CListBox1.Open: +Sub Open() + + me.textFont = kAqSidebarTextFont + me.textSize = kAqSidebarTextSize + + #if targetWin32 or targetLinux//* to clear scrollbar *// + me.height = me.height - 2 + + #endif + +End Sub + +CWindow1.CListBox1.Change: +Sub Change() + + if ubound(me.dataSource) <> me.listCount - 1 then me.listIndex = -1 + + self.CFilterController1.setScrollPosition self.CListBox2.scrollPosition + self.CFilterController1.setColumnWidths self.CListBox2.columnWidths + + if me.listIndex = -1 or me.selCount > 1 then + self.CQueryController1.setCurrentIndex -1 + + self.PagePanel1.value = 0 + + 'self.CFilterController1.setFilterModel + + else + self.CQueryController1.setCurrentIndex CStatsModel(me.dataSource(me.listIndex)).getRepresentation + self.CQueryController1.setSidebarHighlighted me.listIndex, false + + self.PagePanel1.value = 4 + + self.CFilterController1.setFilterModel + self.CFilterController1.updateResults + self.CFilterController1.updateFilter + ' + 'if CStatsModel(me.dataSource(me.listIndex)).getRepresentation < 0 then _ + 'self.CQueryController1.startQuery CStatsModel(me.dataSource(me.listIndex)).getRepresentation, false + ' + end + +End Sub + +CWindow1.PopupMenu1.Change: +Sub Change() + + self.CFilterController1.setMediaFilter me.listIndex + self.CFilterController1.filterResults + +End Sub + +CWindow1.PopupMenu1.Open: +Sub Open() + + me.textSize = kSmallTextSize + me.addRow getLocalizedString("All Types", "PopupMenu") + me.addRow getLocalizedString("Music", "PopupMenu") + me.addRow getLocalizedString("Pictures", "PopupMenu") + me.addRow getLocalizedString("Movies", "PopupMenu") + me.addRow getLocalizedString("Text", "PopupMenu") + me.addRow getLocalizedString("Files", "PopupMenu") + me.listIndex = 0 + +End Sub + +CWindow2.CStaticText1.Open: +Sub Open() + + me.textSize = kLargeTextSize + +End Sub + +CWindow3.Canvas1.Open: +Sub Open() + + #if targetMacOS + me.backdrop = getMaskedPicture("icon.png") + + #elseif targetWin32 or targetLinux + me.backdrop = getMaskedPicture("icon.gif") + + #endif + +End Sub + +CWindow3.CStaticText2.Open: +Sub Open() + + me.text = getLocalizedStringWithIntegerData("Version %i", "StaticText", App.PackageInfo) + +End Sub + +CWindow4.getMyFolderSet: +Protected Function getMyFolderSet(path as string) As dictionary + + dim d as new dictionary + dim f as folderItem + + try + #if targetMachO + d.value(DesktopFolder.posixPath) = DesktopFolder.posixPath + d.value(DocumentsFolder.posixPath) = DocumentsFolder.posixPath + d.value(DocumentsFolder.parent.child("Music").posixPath) _ + = DocumentsFolder.parent.child("Music").posixPath + d.value(DocumentsFolder.parent.child("Pictures").posixPath) _ + = DocumentsFolder.parent.child("Pictures").posixPath + d.value(DocumentsFolder.parent.child("Movies").posixPath) _ + = DocumentsFolder.parent.child("Movies").posixPath + + #elseif targetCarbon or targetLinux + d.value(DesktopFolder.posixPath) = DesktopFolder.posixPath + d.value(DocumentsFolder.posixPath) = DocumentsFolder.posixPath + d.value(DocumentsFolder.child("Music").fixRbBug.posixPath) _ + = DocumentsFolder.child("Music").fixRbBug.posixPath + d.value(DocumentsFolder.child("Pictures").fixRbBug.posixPath) _ + = DocumentsFolder.child("Pictures").fixRbBug.posixPath + d.value(DocumentsFolder.child("Movies").fixRbBug.posixPath) _ + = DocumentsFolder.child("Movies").fixRbBug.posixPath + + #elseif targetWin32 + f = DesktopFolder.fixRbBug + d.value(f.posixPath) = f.posixPath + f = DocumentsFolder.fixRbBug + d.value(f.posixPath) = f.posixPath + d.value(f.child("My Music").posixPath) = f.child("My Music").posixPath + d.value(f.child("My Pictures").posixPath) = f.child("My Pictures").posixPath + d.value(f.child("My Videos").posixPath) = f.child("My Videos").posixPath + + #endif + + catch + + end + + d.value(0) = "-" + d.value(1) = getLocalizedString("Other...", "Preferences") + + if path <> "" then + d.value(path) = path + d.value("currentKey") = path + + else + d.value(2) = getLocalizedString("None", "Preferences") + d.value("currentKey") = 2 + + end + + return d + +End Function + +CWindow4.requiresRestart: +Protected Sub requiresRestart() + + dim m as new messageDialog + + m.icon = 0 + m.message = getLocalizedString("The change will take effect the next time Cabos is restarted.", "Dialogs") + + #if targetMachO or targetWin32 or targetLinux + m.actionButton.caption = getLocalizedString("OK", "Dialogs") + + #elseif targetCarbon + m.actionButton.caption = getLocalizedString("OK", "Dialogs").convertEncoding(Encodings.systemDefault) + + #endif + + call m.showModal + +End Sub + +CWindow4.Close: +Sub Close() + + me.saveSizeAndState "kAqPreferencesWindow" + +End Sub + +CWindow4.Open: +Sub Open() + + me.loadSizeAndState "kAqPreferencesWindow" + +End Sub + +CWindow4.CPreferencesMenuController1.sendCommand: +Sub sendCommand(arg as string) + + CWindow1.CCoreController1.sendCommand arg + +End Sub + +CWindow4.CHierarchicalListBox1.KeyDown: +Function KeyDown(key As String) As Boolean + + if me.listIndex = -1 then return false + + select case key.ascb + + case 13, 3 + if me.cellTag(me.listIndex, 1) isa Dictionary then + self.CPreferencesMenuController1.openPreferencesMenu _ + me, me.listIndex, 1, me.cellTag(me.listIndex, 0), me.cellTag(me.listIndex, 1) + + elseif me.cellType(me.listIndex, 1) = 3 then + me.editCell me.listIndex, 1 + + end + + return true + + case 32 + if me.cellType(me.listIndex, 0) = 2 then + me.cellCheck(me.listIndex, 0) = not me.cellCheck(me.listIndex, 0) + + end + + return true + + case 28 + me.expanded(me.listIndex) = false + return true + + case 29 + me.expanded(me.listIndex) = true + return true + + end + +End Function + +CWindow4.CHierarchicalListBox1.SortColumn: +Function SortColumn(column As Integer) As Boolean + + return true + +End Function + +CWindow4.CHierarchicalListBox1.Close: +Sub Close() + + defaultsWrite "CListBox kAqPreferencesColumnWidths", me.columnWidths + +End Sub + +CWindow4.CHierarchicalListBox1.CellAction: +Sub CellAction(row as integer, column as integer) + + dim defaults as string = me.cellTag(row, 0) + dim s as string + + //* fix rb bug *// + try + select case defaults + + //* general *// + + case "kAqPositiveFilter" + kAqPositiveFilter = me.cellCheck(row, column) + + case "kAqKeywordFilterKeywords" + if me.cellTag(row, column) <> nil and _ + kAqKeywordFilterKeywords.indexOf(Dictionary(me.cellTag(row, column)).value("currentKey")) <> -1 then + s = me.cell(row, column).lowercase.trim + me.cell(row, column) = s + KAqKeywordFilterKeywords(kAqKeywordFilterKeywords.indexOf(Dictionary(me.cellTag(row, column)).value("currentKey"))) = s + Dictionary(me.cellTag(row, column)).clear + Dictionary(me.cellTag(row, column)).value(s) = s + Dictionary(me.cellTag(row, column)).value(0) = "-" + Dictionary(me.cellTag(row, column)).value(1) = getLocalizedString("Remove", "Preferences") + Dictionary(me.cellTag(row, column)).value("currentKey") = s + end + CWindow1.CCoreController1.setValue defaults + + case "kAqAdultFilter" + kAqAdultFilter = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqSpamFilter" + kAqSpamFilter = me.cellCheck(row, column) + CWindow1.CFilterController1.filterResults + + case "kAqLengthFilter" + kAqLengthFilter = me.cellCheck(row, 0) + kAqLengthFilterCharacters = max(min(me.cell(row, 1).val, 255), 0) + me.cell(row, 1) = str(kAqLengthFilterCharacters) + + case "kAqSizeFilter" + kAqSizeFilter = me.cellCheck(row, 0) + kAqSizeFilterKilobytes = max(min(me.cell(row, 1).val, 1024), 0) + me.cell(row, 1) = str(kAqSizeFilterKilobytes) + + case "kAqExistingFileMatching" + kAqExistingFileMatching = me.cellCheck(row, column) + + case "kAqKbFileSize" + kAqKbFileSize = me.cellCheck(row, column) + + case "kAqID3Title" + kAqID3Title = me.cellCheck(row, column) + + case "kAqAutoClearDownloads" + kAqAutoClearDownloads = me.cellCheck(row, column) + + case "kAqAutoClearUploads" + kAqAutoClearUploads = me.cellCheck(row, column) + + case "kAqBounceDockIcon" + kAqBounceDockIcon = me.cellCheck(row, column) + + case "kAqNetBandwidth" + kAqNetBandwidth = me.cellCheck(row, column) + + case "kAqWarnDownloads" + kAqWarnDownloads = me.cellCheck(row, column) + + case "kAqWarnOpening" + kAqWarnOpening = me.cellCheck(row, column) + + case "kAqWarnQuit" + kAqWarnQuit = me.cellCheck(row, column) + + //* Appearance *// + + case "kAqSidebarTextFont" + kAqSidebarTextFont = Dictionary(me.cellTag(row, column)).value("currentKey") + resizeAllListBoxes + + case "kAqSidebarTextSize" + kAqSidebarTextSize = Dictionary(me.cellTag(row, column)).value("currentKey") + resizeAllListBoxes + + case "kAqStandardTextFont" + kAqStandardTextFont = Dictionary(me.cellTag(row, column)).value("currentKey") + resizeAllListBoxes + + case "kAqStandardTextSize" + kAqStandardTextSize = Dictionary(me.cellTag(row, column)).value("currentKey") + resizeAllListBoxes + + case "kAqTexturedWindow" + kAqTexturedWindow = me.cellCheck(row, column) + self.requiresRestart + + //* Download *// + + case "kAqSaveDirectory" + if Dictionary(me.cellTag(row, 1)).value("currentKey").type = 8 then + kAqSaveDirectory = Dictionary(me.cellTag(row, 1)).value("currentKey") + + else + kAqSaveDirectory = "" + + end + + CWindow1.CCoreController1.setValue defaults + + case "kAqMoveMusic" + kAqMoveMusic = me.cellCheck(row, 0) + + if Dictionary(me.cellTag(row, 1)).value("currentKey").type = 8 then + kAqMoveMusicLocation = Dictionary(me.cellTag(row, 1)).value("currentKey") + + else + kAqMoveMusicLocation = "" + + end + + case "kAqMoveMovies" + kAqMoveMovies = me.cellCheck(row, 0) + + if Dictionary(me.cellTag(row, 1)).value("currentKey").type = 8 then + kAqMoveMoviesLocation = Dictionary(me.cellTag(row, 1)).value("currentKey") + + else + kAqMoveMoviesLocation = "" + + end + + case "kAqMovePictures" + kAqMovePictures = me.cellCheck(row, 0) + if Dictionary(me.cellTag(row, 1)).value("currentKey").type = 8 then + kAqMovePicturesLocation = Dictionary(me.cellTag(row, 1)).value("currentKey") + + else + kAqMovePicturesLocation = "" + + end + + case "kAqIncompletePurgeTime" + kAqIncompletePurgeTime = max(min(me.cell(row, column).val, 100), 0) + me.cell(row, column) = str(kAqIncompletePurgeTime) + CWindow1.CCoreController1.setValue defaults + + case "kAqConcurrentDownloads" + kAqConcurrentDownloads = Dictionary(me.cellTag(row, column)).value("currentKey") + CWindow1.CCoreController1.setValue defaults + + case "kAqDownstreamLimit" + kAqDownstreamLimit = max(min(me.cell(row, column).val, 100), 25) + me.cell(row, column) = str(kAqDownstreamLimit) + CWindow1.CCoreController1.setValue defaults + + //* iTunes *// + + case "kAqImportMusicFile" + kAqImportMusicFile = Dictionary(me.cellTag(row, column)).value("currentKey") + + case "kAqPlaySong" + kAqPlaySong = Dictionary(me.cellTag(row, column)).value("currentKey") + + case "kAqDeleteAfterImport" + kAqDeleteAfterImport = me.cellCheck(row, column) + + //* Sharing *// + + case "kAqSharedDirectories" + CWindow1.CCoreController1.setValue defaults + + case "kAqPartialFileSharing" + kAqPartialFileSharing = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqCompleteFileSharing" + kAqCompleteFileSharing = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqMaxUploads" + kAqMaxUploads = Dictionary(me.cellTag(row, column)).value("currentKey") + CWindow1.CCoreController1.setValue defaults + + case "kAqMaxUploadsPerPerson" + kAqMaxUploadsPerPerson = Dictionary(me.cellTag(row, column)).value("currentKey") + CWindow1.CCoreController1.setValue defaults + + case "kAqUpstreamLimit" + kAqUpstreamLimit = max(min(me.cell(row, column).val, 100), 25) + me.cell(row, column) = str(kAqUpstreamLimit) + CWindow1.CCoreController1.setValue defaults + + //* Network *// + + case "kAqConnectionSpeed" + kAqConnectionSpeed = Dictionary(me.cellTag(row, column)).value("currentKey") + CWindow1.CCoreController1.setValue defaults + + case "kAqPort" + kAqPort = max(min(me.cell(row, column).val, 65536), 0) + me.cell(row, column) = str(kAqPort) + CWindow1.CCoreController1.setValue defaults + self.requiresRestart + + case "kAqUPnPType" + kAqUPnPType = Dictionary(me.cellTag(row, column)).value("currentKey") + CWindow1.CCoreController1.setValue defaults + self.requiresRestart + + case "kAqEnableUltrapeer" + kAqEnableUltrapeer = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqLocale" + kAqLocale = me.cellCheck(row, 0) + CWindow1.CCoreController1.setValue defaults + kAqPreferLocale = Dictionary(me.cellTag(row, 1)).value("currentKey") + CWindow1.CCoreController1.setValue "kAqPreferLocale" + + case "kAqAllowFreeloaders" + kAqAllowFreeloaders = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + //* Advanced *// + + case "kAqUseProxy" + kAqUseProxy = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqProxyServer" + kAqProxyServer = me.cell(row, column).trim + CWindow1.CCoreController1.setValue defaults + + case "kAqProxyPort" + kAqProxyPort = max(min(me.cell(row, column).val, 65536), 0) + me.cell(row, column) = str(kAqProxyPort) + CWindow1.CCoreController1.setValue defaults + + case "kAqProxyType" + kAqProxyType = Dictionary(me.cellTag(row, column)).value("currentKey") + CWindow1.CCoreController1.setValue "kAqUseProxy" + + case "kAqProxyRequiresAuthentication" + kAqProxyRequiresAuthentication = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqProxyUsername" + kAqProxyUsername = me.cell(row, column).trim + me.cell(row, column) = kAqProxyUsername + CWindow1.CCoreController1.setValue defaults + + case "kAqProxyPassword" + kAqProxyPassword = me.cell(row, column).trim + me.cell(row, column) = kAqProxyPassword + CWindow1.CCoreController1.setValue defaults + + case "kAqProxyPrivate" + kAqProxyPrivate = me.cellCheck(row, column) + CWindow1.CCoreController1.setValue defaults + + case "kAqIPFilterIPs" + if me.cellTag(row, column) <> nil and _ + kAqIPFilterIPs.indexOf(Dictionary(me.cellTag(row, column)).value("currentKey")) <> -1 then + s = me.cell(row, column).lowercase.trim + me.cell(row, column) = s + kAqIPFilterIPs(kAqIPFilterIPs.indexOf(Dictionary(me.cellTag(row, column)).value("currentKey"))) = s + Dictionary(me.cellTag(row, column)).clear + Dictionary(me.cellTag(row, column)).value(s) = s + Dictionary(me.cellTag(row, column)).value(0) = "-" + Dictionary(me.cellTag(row, column)).value(1) = getLocalizedString("Remove", "Preferences") + Dictionary(me.cellTag(row, column)).value("currentKey") = s + end + CWindow1.CCoreController1.setValue defaults + + end + + catch + + end + +End Sub + +CWindow4.CHierarchicalListBox1.CellClick: +Function CellClick(row as Integer, column as Integer, x as Integer, y as Integer) As Boolean + + if me.cellTag(row, column) isa Dictionary then + me.listIndex = row + me.refresh + self.CPreferencesMenuController1.openPreferencesMenu _ + me, row, column, me.cellTag(row, 0), me.cellTag(row, 1) + return true + + elseif me.cellType(row, column) = ListBox.TypeEditable then + me.listIndex = row + me.refresh + me.editCell(row, column) + return true + + end + +End Function + +CWindow4.CHierarchicalListBox1.ExpandRow: +Sub ExpandRow(row As Integer) + + dim test as string + + dim f as folderItem + dim d as dictionary + dim i, j as integer + dim s as string = me.list(row) + + select case s + + //* General *// + + case getLocalizedString("General", "Preferences") + me.addrow getLocalizedString("Transfers:", "Preferences") + me.addrow getLocalizedString("Clear completed downloads", "Preferences"), _ + "kAqAutoClearDownloads", kAqAutoClearDownloads + me.addrow getLocalizedString("Clear completed uploads", "Preferences"), _ + "kAqAutoClearUploads", kAqAutoClearUploads + me.addrow getLocalizedString("Bounce Dock icon upon download success", "Preferences"), _ + "kAqBounceDockIcon", kAqBounceDockIcon + me.addrow getLocalizedString("Display bandwidth usage in Sidebar", "Preferences"), _ + "kAqNetBandwidth", kAqNetBandwidth + + me.addrow getLocalizedString("Prompt user:", "Preferences") + me.addrow getLocalizedString("Before removing partially downloaded files", "Preferences"), _ + "kAqWarnDownloads", kAqWarnDownloads + me.addrow getLocalizedString("Before opening partially downloaded files", "Preferences"), _ + "kAqWarnOpening", kAqWarnOpening + me.addrow getLocalizedString("Before quitting with active downloads", "Preferences"), _ + "kAqWarnQuit", kAqWarnQuit + + //* Searching *// + + case getLocalizedString("Searching", "Preferences") + + me.addrow getLocalizedString("Gray out files that are already on this computer", "Preferences"), _ + "kAqExistingFileMatching", kAqExistingFileMatching + me.addrow getLocalizedString("Show track name as file name", "Preferences"), _ + "kAqID3Title", kAqID3Title + me.addrow getLocalizedString("Show file size in bytes", "Preferences"), _ + "kAqKbFileSize", kAqKbFileSize + + me.addrow getLocalizedString("Ignore files that do not contain the search keywords", "Preferences"), _ + "kAqPositiveFilter", kAqPositiveFilter + me.addRow getLocalizedString("Ignore files that are adult content", "Preferences"), _ + "kAqAdultFilter", kAqAdultFilter + + #if targetMachO or targetWin32 or targetLinux + d = new Dictionary + d.value(0) = getLocalizedString("Clear Spam History", "Preferences") + d.value("currentKey") = 0 + me.addrow getLocalizedString("Ignore files that are spam content", "Preferences"), _ + "kAqSpamFilter", kAqSpamFilter, d + + #endif + + me.addrow getLocalizedString("Ignore files that are longer than (characters)", "Preferences"), _ + "kAqLengthFilter", kAqLengthFilter, str(kAqLengthFilterCharacters) + me.addrow getLocalizedString("Ignore files that are smaller than (kB)", "Preferences"), _ + "kAqSizeFilter", kAqSizeFilter, str(kAqSizeFilterKiloBytes) + + d = new Dictionary + d.value(0) = getLocalizedString("Add Keyword...", "Preferences") + d.value("currentKey") = 0 + me.addrow _ + getLocalizedString("Ignore files that contain following keywords:", "Preferences"), _ + "kAqKeywordFilterKeywords", d + + j = ubound(kAqKeywordFilterKeywords) + + for i = 0 to j + + d = new Dictionary + d.value(kAqKeywordFilterKeywords(i)) = kAqKeywordFilterKeywords(i) + d.value(0) = "-" + d.value(1) = getLocalizedString("Remove", "Preferences") + d.value("currentKey") = kAqKeywordFilterKeywords(i) + me.addrow "", "kAqKeywordFilterKeywords", d + + next + + + //* Appearance *// + + case getLocalizedString("Appearance", "Preferences") + d = new Dictionary + j = fontCount - 1 + + for i = 0 to j + + d.value(Font(i).convertEncoding(Encodings.UTF8)) = Font(i).convertEncoding(Encodings.UTF8) + + next + + d.value("currentKey") = kAqSidebarTextFont + me.addRow getLocalizedString("Sidebar Text Font", "Preferences"), _ + "kAqSidebarTextFont", d + + d = new Dictionary + d.value(kSmallTextSize) = getLocalizedString("Small", "Preferences") + d.value(kMiddleTextSize) = getLocalizedString("Middle", "Preferences") + d.value(kLargeTextSize) = getLocalizedString("Large", "Preferences") + d.value("currentKey") = kAqSidebarTextSize + me.addRow getLocalizedString("Sidebar Text Size", "Preferences"), _ + "kAqSidebarTextSize", d + + d = new Dictionary + j = fontCount - 1 + + for i = 0 to j + + #if targetMachO or targetCarbon + d.value(Font(i).convertEncoding(Encodings.UTF8)) = Font(i).convertEncoding(Encodings.UTF8) + + #elseif targetWin32 + if Font(i).leftb(1) <> "@" then _ + d.value(Font(i).convertEncoding(Encodings.UTF8)) = Font(i).convertEncoding(Encodings.UTF8) + + #endif + + next + + d.value("currentKey") = kAqStandardTextFont + me.addRow getLocalizedString("Standard Text Font", "Preferences"), _ + "kAqStandardTextFont", d + + d = new Dictionary + d.value(kSmallTextSize) = getLocalizedString("Small", "Preferences") + d.value(kMiddleTextSize) = getLocalizedString("Middle", "Preferences") + d.value(kLargeTextSize) = getLocalizedString("Large", "Preferences") + d.value("currentKey") = kAqStandardTextSize + me.addRow getLocalizedString("Standard Text Size", "Preferences"), _ + "kAqStandardTextSize", d + + #if targetMachO + if targetLeopard = false then + me.addrow getLocalizedString("Use textured window", "Preferences"), _ + "kAqTexturedWindow", kAqTexturedWindow + end + + #endif + + //* Download *// + + case getLocalizedString("Download", "Preferences") + d = self.getMyFolderSet(kAqSaveDirectory) + + me.addrow getLocalizedString("Save downloaded files in", "Preferences"), _ + "kAqSaveDirectory", d + + d = self.getMyFolderSet(kAqMoveMusicLocation) + + me.addrow getLocalizedString("Move completed music files to", "Preferences"), _ + "kAqMoveMusic", kAqMoveMusic, d + + d = self.getMyFolderSet(kAqMovePicturesLocation) + + me.addrow getLocalizedString("Move completed picture files to", "Preferences"), _ + "kAqMovePictures", kAqMovePictures, d + + d = self.getMyFolderSet(kAqMoveMoviesLocation) + + me.addrow getLocalizedString("Move completed movie files to", "Preferences"), _ + "kAqMoveMovies", kAqMoveMovies, d + + me.addrow getLocalizedString("Minimum days to keep incomplete files", "Preferences"), _ + "kAqIncompletePurgeTime", kAqIncompletePurgeTime + + d = new Dictionary + d.value(1) = 1 + d.value(2) = 2 + d.value(3) = 3 + d.value(4) = 4 + d.value(5) = 5 + d.value(6) = 6 + d.value(7) = 7 + d.value(8) = 8 + d.value(9) = 9 + d.value(10) = 10 + d.value(11) = 11 + d.value(12) = 12 + d.value(13) = 13 + d.value(14) = 14 + d.value(15) = 15 + d.value(16) = "-" + d.value(100) = getLocalizedString("Unlimited", "Preferences") + d.value("currentKey") = kAqConcurrentDownloads + me.addrow getLocalizedString("Maximum downloads", "Preferences"), _ + "kAqConcurrentDownloads", d + me.addrow getLocalizedString("Downstream bandwidth limit (%)", "Preferences"), _ + "kAqDownstreamLimit", kAqDownstreamLimit + + //* iTunes *// + + case getLocalizedString("iTunes", "Preferences") + d = new Dictionary + d.value(0) = getLocalizedString("Do not import to iTunes", "Preferences") + d.value(1) = getLocalizedString("Add to iTunes Library", "Preferences") + d.value(2) = getLocalizedString("Add to iTunes 'Cabos' Playlist", "Preferences") + d.value("currentKey") = kAqImportMusicFile + me.addrow getLocalizedString("Completed music file", "Preferences"), _ + "kAqImportMusicFile", d + + d = new Dictionary + d.value(0) = getLocalizedString("Do not play", "Preferences") + d.value(1) = getLocalizedString("Play", "Preferences") + d.value(2) = getLocalizedString("Play if nothing else is playing", "Preferences") + d.value(3) = getLocalizedString("Add to iTunes 'Party Shuffle'", "Preferences") + d.value("currentKey") = kAqPlaySong + me.addrow getLocalizedString("Imported music file", "Preferences"), "kAqPlaySong", d + + me.addrow getLocalizedString("Delete original music file after successful import", "Preferences"), _ + "kAqDeleteAfterImport", kAqDeleteAfterImport + + //* Sharing *// + + case getLocalizedString("Sharing", "Preferences") + d = new Dictionary + d.value(0) = getLocalizedString("Add Folder...", "Preferences") + d.value("currentKey") = 0 + me.addrow _ + getLocalizedString("Share files in the following folders:", "Preferences"), _ + "kAqSharedDirectories", d + + j = ubound(kAqSharedDirectories) + + for i = 0 to j + + if kAqSharedDirectories(i) <> "" then + d = new Dictionary + d.value(kAqSharedDirectories(i)) = kAqSharedDirectories(i) + d.value(0) = "-" + d.value(1) = getLocalizedString("Remove", "Preferences") + d.value("currentKey") = kAqSharedDirectories(i) + me.addrow "", "kAqSharedDirectories", d + + end + + next + + me.addRow getLocalizedString("Share partially downloaded files (Recommended)", "Preferences"), _ + "kAqPartialFileSharing", kAqPartialFileSharing + + #if targetMachO or targetWin32 or targetLinux + me.addRow getLocalizedString("Share completely downloaded files (Recommended)", "Preferences"), _ + "kAqCompleteFileSharing", kAqCompleteFileSharing + + #endif + + d = new Dictionary + d.value(1) = 1 + d.value(2) = 2 + d.value(3) = 3 + d.value(4) = 4 + d.value(5) = 5 + d.value(6) = 6 + d.value(7) = 7 + d.value(8) = 8 + d.value(9) = 9 + d.value(10) = 10 + d.value(11) = 11 + d.value(12) = 12 + d.value(13) = 13 + d.value(14) = 14 + d.value(15) = 15 + d.value(16) = "-" + d.value(100) = getLocalizedString("Unlimited", "Preferences") + d.value("currentKey") = kAqMaxUploads + me.addRow getLocalizedString("Maximum uploads", "Preferences"), _ + "kAqMaxUploads", d + + d = new Dictionary + d.value(1) = 1 + d.value(2) = 2 + d.value(3) = 3 + d.value(4) = 4 + d.value(5) = 5 + d.value(6) = 6 + d.value(7) = 7 + d.value(8) = 8 + d.value(9) = 9 + d.value(10) = 10 + d.value(11) = 11 + d.value(12) = 12 + d.value(13) = 13 + d.value(14) = 14 + d.value(15) = 15 + d.value(16) = "-" + d.value(100) = getLocalizedString("Unlimited", "Preferences") + d.value("currentKey") = kAqMaxUploadsPerPerson + me.addRow getLocalizedString("Maximum uploads per person", "Preferences"), _ + "kAqMaxUploadsPerPerson", d + + me.addRow getLocalizedString("Upstream bandwidth limit (%)", "Preferences"), _ + "kAqUpstreamLimit", kAqUpstreamLimit + + //* Network *// + + case getLocalizedString("Network", "Preferences") + d = new Dictionary + d.value(56) = getLocalizedString("Modem", "Preferences") + d.value(350) = getLocalizedString("Cable or DSL", "Preferences") + d.value(1000) = getLocalizedString("T1", "Preferences") + d.value(3000) = getLocalizedString("T3", "Preferences") + d.value("currentKey") = kAqConnectionSpeed + me.addRow getLocalizedString("I connect to the internet via", "Preferences"), _ + "kAqConnectionSpeed", d + + me.addRow getLocalizedString("Listen for incoming connections on port", "Preferences"), _ + "kAqPort", kAqPort + + d = new Dictionary + d.value(0) = getLocalizedString("Automatically (Requires UPnP)", "Preferences") + d.value(1) = getLocalizedString("Manually", "Preferences") + d.value(2) = getLocalizedString("Do nothing", "Preferences") + d.value("currentKey") = kAqUPnPType + me.addRow getLocalizedString("Configure my router to work behind a firewall", "Preferences"), _ + "kAqUPnPType", d + + me.addrow getLocalizedString("Allow this computer to become an Ultrapeer", "Preferences"), _ + "kAqEnableUltrapeer", kAqEnableUltrapeer + + d = new Dictionary + d.value("") = getLocalizedString("Default", "Preferences") + d.value(0) = "-" + d.value("af") = "Afrikaans" + d.value("ar") = "لغة عربية" + d.value("be") = "Беларускі" + d.value("bg") = "Български" + d.value("bn") = "Bengla" + d.value("br") = "Brezhoneg" + d.value("bu") = "Myanmarese" + d.value("ca") = "Català" + d.value("cs") = "Čeština" + d.value("da") = "Dansk" + d.value("de") = "Deutsch" + d.value("el") = "Ελληνικά" + d.value("en") = "English" + d.value("es") = "Español" + d.value("et") = "Eesti" + d.value("eu") = "Euskara" + d.value("fa") = "فارسی" + d.value("fi") = "Suomi" + d.value("fr") = "Français" + d.value("gl") = "Gallego" + d.value("hi") = "Hindi" + d.value("hr") = "Hrvatsky" + d.value("hu") = "Magyar" + d.value("id") = "Bahasa Indonesia" + d.value("is") = "Íslenska" + d.value("it") = "Italiano" + d.value("iw") = "עברית" + d.value("ja") = "日本語" + d.value("kk") = "Казах" + d.value("ko") = "한글" + d.value("lt") = "Lietuvių" + d.value("lv") = "Latviešu" + d.value("mg") = "Malagasy" + d.value("mk") = "Македонски јазик" + d.value("ms") = "Bahasa Malaysia" + d.value("nl") = "Nederlands" + d.value("nn") = "Norsk Nynorsk" + d.value("no") = "Norsk Bokmål" + d.value("pl") = "Polski" + d.value("pt") = "Português" + d.value("ro") = "Romana" + d.value("ru") = "Русский" + d.value("sk") = "Slovenčina" + d.value("sl") = "Slovenski" + d.value("sq") = "Shqipe" + d.value("sr") = "Српски" + d.value("sv") = "Svenska" + d.value("ta") = "Tamil" + d.value("th") = "ภาษาไทย" + d.value("tl") = "Tagalog" + d.value("tr") = "Türkçe" + d.value("uk") = "Українська мова" + d.value("ur") = "اردو" + d.value("vi") = "Tiếng Việt Nam" + d.value("zh") = "汉语" + d.value("currentKey") = kAqPreferLocale + me.addrow getLocalizedString("Preferentially connect to hosts that are", "Preferences"), _ + "kAqLocale", kAqLocale, d + + me.addrow getLocalizedString("Allow freeloaders to connect to this computer", "Preferences"), _ + "kAqAllowFreeloaders", kAqAllowFreeloaders + + //* Advanced *// + + case getLocalizedString("Advanced", "Preferences") + me.addrow getLocalizedString("Proxy Server:", "Preferences") + me.addrow getLocalizedString("Use a proxy server", "Preferences"), _ + "kAqUseProxy", kAqUseProxy + + me.addIndentRow getLocalizedString("Server", "Preferences"), _ + "kAqProxyServer", kAqProxyServer + me.addIndentRow getLocalizedString("Port", "Preferences"), _ + "kAqProxyPort", kAqProxyPort + + d = new Dictionary + d.value(1) = getLocalizedString("HTTP proxy", "Preferences") + d.value(4) = getLocalizedString("SOCKS v4 proxy", "Preferences") + d.value(5) = getLocalizedString("SOCKS v5 proxy", "Preferences") + d.value("currentKey") = kAqProxyType + me.addIndentRow getLocalizedString("Type", "Preferences"), _ + "kAqProxyType", d + + me.addrow getLocalizedString("Requires authentication", "Preferences"), _ + "kAqProxyRequiresAuthentication", kAqProxyRequiresAuthentication + me.addIndentRow getLocalizedString("Username", "Preferences"), _ + "kAqProxyUsername", kAqProxyUsername + me.addIndentRow getLocalizedString("Password", "Preferences"), _ + "kAqProxyPassword", kAqProxyPassword + + me.addrow getLocalizedString("Use proxy server for private IP addresses", "Preferences"), _ + "kAqProxyPrivate", kAqProxyPrivate + + d = new Dictionary + d.value(0) = getLocalizedString("Add IP Address...", "Preferences") + d.value("currentKey") = 0 + me.addrow _ + getLocalizedString("Ignore hosts that contain following IP addresses:", "Preferences"), _ + "kAqIPFilterIPs", d + + j = ubound(kAqIPFilterIPs) + + for i = 0 to j + + d = new Dictionary + d.value(kAqIPFilterIPs(i)) = kAqIPFilterIPs(i) + d.value(0) = "-" + d.value(1) = getLocalizedString("Remove", "Preferences") + d.value("currentKey") = kAqIPFilterIPs(i) + me.addrow "", "kAqIPFilterIPs", d + + next + + end + + try + for i = me.listCount - 1 downto 0 + + if me.list(i) <> s and me.expanded(i) then me.expanded(i) = false + + next + + catch + + end + +End Sub + +CWindow4.CHierarchicalListBox1.Open: +Sub Open() + + me.textFont = kAqStandardTextFont + me.textSize = kAqStandardTextSize + + dim result as string + + result = defaultsRead("CListBox kAqPreferencesColumnWidths", result) + me.setColumnWidths result + + me.addFolder getLocalizedString("General", "Preferences") + me.addFolder getLocalizedString("Searching", "Preferences") + me.addFolder getLocalizedString("Appearance", "Preferences") + me.addFolder getLocalizedString("Download", "Preferences") + if targetLeopard = false then _ + me.addFolder getLocalizedString("iTunes", "Preferences") + me.addFolder getLocalizedString("Sharing", "Preferences") + me.addFolder getLocalizedString("Network", "Preferences") + me.addFolder getLocalizedString("Advanced", "Preferences") + +End Sub + +AssertionException.Constructor: +Sub Constructor(description as String) + +End Sub + +InvalidParameterException.Constructor: +Sub Constructor(msg as String) + #if targetMacOS + me.Message = msg + #endif +End Sub + +InvalidParameterException.Constructor: +Sub Constructor(className as String, methodName as String, msg as String) + #if targetMacOS + me.Message = className + "." + methodName + ": " + msg + "." + #endif +End Sub + +MacOSException.Constructor: +Sub Constructor(theFunction as String, theError as Integer) + #if targetMacOS + me.pFunctionName = theFunction + me.pOSError = theError + #endif +End Sub + +MacOSException.ErrorCode: +Function ErrorCode() As Integer + #if targetMacOS + Return me.pOSError + #endif +End Function + +MacOSException.FunctionName: +Function FunctionName() As String + #if targetMacOS + Return me.pFunctionName + #endif +End Function + +CFArray.Constructor: +Sub Constructor(theArray as CFArray) + #if targetMachO + //copies theArray + Declare Function CFArrayCreateCopy Lib CarbonLib (allocator as Integer, theArray as Integer) as Integer + + dim theRef as Integer + dim nullList(-1) as CFType + + If theArray Is Nil then + me.Constructor nullList + Else + theRef = CFArrayCreateCopy(CoreFoundation.kCFAllocatorDefault, me) + CoreFoundation.CheckCFTypeRef theRef, "CFArray", "CopyConstructor", "CFArrayCreateCopy" + me.Constructor theRef + End if + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFArray.Value: +Function Value(index as Integer) As Integer + #if targetMachO + Declare Function CFArrayGetCount Lib CarbonLib (theArray as Integer) as Integer + Declare Function CFArrayGetValueAtIndex Lib CarbonLib (theArray as Integer, idx as Integer) as Integer + + If index < 0 or index > CFArrayGetCount(me) - 1 then + Raise new OutOfBoundsException + End if + + Return CFArrayGetValueAtIndex(me, index) + #endif +End Function + +CFArray.Count: +Function Count() As Integer + #if targetMachO + Declare Function CFArrayGetCount Lib CarbonLib (theArray as Integer) as Integer + + Return CFArrayGetCount(me) + #endif +End Function + +CFArray.Constructor: +Sub Constructor(theList() as CFType) + #if targetMachO + Declare Function CFArrayCreate Lib CarbonLib (allocator as Integer, values as Ptr, numValues as Integer, callbacks as Ptr) as Integer + Declare Function CFArrayCreate Lib CarbonLib (allocator as Integer, values as Integer, numValues as Integer, callbacks as Ptr) as Integer + + dim bundleItem as FolderItem + dim bundleURL as CFURL + dim bundle as CFBundle + dim bundleError as RuntimeException + dim arrayRef as Integer + dim thevalues as MemoryBlock + dim i as Integer + dim defaultCallBacks as MemoryBlock + + Const kCFTypeArrayCallBacks = "kCFTypeArrayCallBacks" + Const CarbonFramework = "com.apple.Carbon" + Const Null = 0 + + bundle = new CFBundle(CarbonFramework) + defaultCallBacks = bundle.DataPointer(kCFTypeArrayCallBacks) + If defaultCallBacks Is Nil then + bundleError = new RuntimeException + bundleError.Message = "CFArray.Constructor: Could not resolve " + kCFTypeArrayCallBacks + "." + Raise bundleError + End if + + If UBound(theList) > -1 then + theValues = new MemoryBlock(4*(1 + UBound(theList))) + For i = 0 to UBound(theList) + thevalues.Long(4*i) = theList(i) + Next + arrayRef = CFArrayCreate(CoreFoundation.kCFAllocatorDefault, theValues, UBound(theList) + 1, defaultCallBacks) + Else + arrayRef = CFArrayCreate(CoreFoundation.kCFAllocatorDefault, Null, UBound(theList) + 1, defaultCallBacks) + End if + CoreFoundation.CheckCFTypeRef arrayRef, "CFArray", "Constructor", "CFArrayCreate" + me.Constructor arrayRef + + Finally + CoreFoundation.Release arrayRef + + #endif + +End Sub + +CFBoolean.Constructor: +Sub Constructor(theValue as Boolean) + #if targetMachO + dim frameworkBundle as CFBundle + dim symbolName as CFString + dim p as MemoryBlock + + Const CFBooleanFalse = "kCFBooleanFalse" + Const CFBooleanTrue = "kCFBooleanTrue" + Const CarbonFramework = "com.apple.Carbon" + + If theValue then + symbolName = new CFString(CFBooleanTrue) + Else + symbolName = new CFString(CFBooleanFalse) + End if + frameworkBundle = new CFBundle(CarbonFramework) + p = frameworkBundle.DataPointer(symbolName) + me.Constructor p.Long(0) + + //in Rb 6 we can use static variables here, I think... + #endif +End Sub + +CFBoolean.Operator_Convert: +Function Operator_Convert() As Boolean + #if targetMachO + Declare Function CFBooleanGetValue Lib CarbonLib (cf as Integer) as Boolean + + Return CFBooleanGetValue(me) + #endif +End Function + +CFBundle.Constructor: +Sub Constructor(theURL as CFURL) + #if targetMachO + Declare Function CFBundleCreate Lib CarbonLib (allocator as Integer, bundleURL as Integer) as Integer + + dim bundleRef as Integer + + If theURL Is Nil then + me.Constructor() + Else + bundleRef = CFBundleCreate(CoreFoundation.kCFAllocatorDefault, theURL) + CoreFoundation.CheckCFTypeRef bundleRef, "CFBundle", "Constructor", "CFBundleCreate" + me.Constructor bundleRef + End if + + Finally + CoreFoundation.Release bundleRef + + #endif + +End Sub + +CFBundle.ExecutableFile: +Function ExecutableFile() As CFURL + #if targetMachO + Declare Function CFBundleCopyExecutableURL Lib CarbonLib (theBundle as Integer) as Integer + + dim theRef as Integer + dim theURL as CFURL + + theRef = CFBundleCopyExecutableURL(me) + If theRef = 0 then + Return Nil + End if + theURL = new CFURL(theRef) + + Finally + CoreFoundation.Release theRef + Return theURL + + #endif + +End Function + +CFBundle.Resource: +Function Resource(name as CFString, type as CFString, subDirectoryName as CFString) As CFURL + #if targetMachO + Declare Function CFBundleCopyResourceURL Lib CarbonLib (bundle as Integer, resourceName as Integer, resourceType as Integer, subDirName as Integer) as Integer + Declare Function CFBundleCopyResourceURLInDirectory Lib CarbonLib (bundleURL as Integer, resourceName as Integer, resourceType as Integer, subDirName as Integer) as Integer + Declare Function CFBundleCopyBundleURL Lib CarbonLib (bundle as Integer) as Integer + + dim theRef as Integer + dim theURL as CFURL + dim typeRef as Integer + dim subDirRef as Integer + dim urlRef as Integer + + If name Is Nil then + Return Nil + End if + If type Is Nil then + typeRef = 0 + Else + typeRef = type + End if + If subDirectoryName Is Nil then + subDirRef = 0 + Else + subDirRef = subDirectoryName + End if + + theRef = CFBundleCopyResourceURL(me, name, typeRef, subDirRef) + CoreFoundation.CheckCFTypeRef theRef, "CFBundle", "Resource", "CFBundleCopyResourceURL" + theURL = new CFURL(theRef) + + Exception oops as CFTypeRefException + theURL = Nil + + Finally + CoreFoundation.Release theRef + Return theURL + + #endif + +End Function + +CFBundle.ResourcesDirectory: +Function ResourcesDirectory() As CFURL + #if targetMachO + Declare Function CFBundleCopyResourcesDirectoryURL Lib CarbonLib (theBundle as Integer) as Integer + + dim theRef as Integer + dim theURL as CFURL + + theRef = CFBundleCopyResourcesDirectoryURL(me) + CoreFoundation.CheckCFTypeRef theRef, "CFBundle", "ResourcesDirectory", "CFBundleCopyResourcesDirectoryURL" + theURL = new CFURL(theRef) + + Exception theProblem as CFTypeRefException + theURL = Nil + + Finally + CoreFoundation.Release theRef + Return theURL + + #endif + +End Function + +CFBundle.DataPointer: +Function DataPointer(symbolName as String) As MemoryBlock + #if targetMachO + Declare Function CFBundleGetDataPointerForName Lib CarbonLib (bundle as Integer, symbolName as Integer) as Integer + + dim ptr as MemoryBlock + + ptr = new MemoryBlock(4) + ptr.Long(0) = CFBundleGetDataPointerForName(me, new CFString(symbolName)) + If ptr.Long(0) <> 0 then + ptr = ptr.Ptr(0) + Else + ptr = Nil + End if + Return ptr + #endif +End Function + +CFBundle.Identifier: +Function Identifier() As CFString + #if targetMachO + Declare Function CFBundleGetIdentifier Lib CarbonLib (bundle as Integer) as Integer + + dim theRef as Integer + dim theString as CFString + + theRef = CFBundleGetIdentifier(me) + If theRef <> 0 then + theString = new CFString(theRef) + Else //no identifier was specified in the bundle plist, perhaps + theString = new CFString("") + End if + Return theString + #endif +End Function + +CFBundle.URL: +Function URL() As CFURL + #if targetMachO + Declare Function CFBundleCopyBundleURL Lib CarbonLib (bundle as Integer) as Integer + + dim theRef as Integer + dim theURL as CFURL + + theRef = CFBundleCopyBundleURL(me) + If theRef = 0 then + Return Nil + End if + theURL = new CFURL(theRef) + + Finally + CoreFoundation.Release theRef + Return theURL + + #endif + +End Function + +CFBundle.FunctionPointer: +Function FunctionPointer(symbolName as CFString) As Integer + #if targetMachO + Declare Function CFBundleGetFunctionPointerForName Lib CarbonLib (bundle as Integer, symbolName as Integer) as Integer + + If symbolName Is Nil then + Return 0 + End if + + Return CFBundleGetFunctionPointerForName(me, symbolName) + #endif +End Function + +CFBundle.InfoDictionary: +Function InfoDictionary() As CFDictionary + #if targetMachO + Declare Function CFBundleGetInfoDictionary Lib CarbonLib (bundle as Integer) as Integer + + dim dictRef as Integer + dim theDictionary as CFDictionary + dim noKeys(-1) as CFType + dim noValues(-1) as CFType + + dictRef = CFBundleGetInfoDictionary(me) + If dictRef = 0 then //return an empty Dictionary + theDictionary = new CFDictionary(noKeys, noValues) + End if + theDictionary = new CFDictionary(dictRef) + Return theDictionary + #endif +End Function + +CFBundle.InfoDictionaryValue: +Function InfoDictionaryValue(key as CFString) As CFType + #if targetMachO + Declare Function CFBundleGetValueForInfoDictionaryKey Lib CarbonLib (bundle as Integer, key as Integer) as Integer + + dim valueRef as Integer + dim theValue as CFPropertyList + + Const kCFPropertyListImmutable = 0 + + If key Is Nil then + Return Nil + End if + + valueRef = CFBundleGetValueForInfoDictionaryKey(me, key) + If valueRef = 0 then //return an empty Dictionary + Return nil + End if + theValue = CoreFoundation.NewCFPropertyListObject(valueRef, kCFPropertyListImmutable) + Return CFType(theValue) + #endif +End Function + +CFBundle.Constructor: +Sub Constructor() + #if targetMachO + Declare Function CFBundleGetMainBundle Lib CarbonLib () as Integer + + dim theRef as Integer + + theRef = CFBundleGetMainBundle + CoreFoundation.CheckCFTypeRef theRef, "CFBundle", "Constructor", "GetMainBundle" + me.Constructor(theRef) + #endif +End Sub + +CFBundle.Constructor: +Sub Constructor(bundleIdentifier as String) + #if targetMachO + Declare Function CFBundleGetBundleWithIdentifier Lib CarbonLib (bundleID as Integer) as Integer + + dim theRef as Integer + + theRef = CFBundleGetBundleWithIdentifier(new CFString(bundleIdentifier)) + CoreFoundation.CheckCFTypeRef theRef, "CFBundle", "Constructor3", "CFBundleGetBundleWithIdentifier" + me.Constructor(theRef) + #endif +End Sub + +CFBundle.LocalizedString: +Function LocalizedString(key as CFString, value as CFString, tableName as CFString) As CFString + #if targetMachO + Declare Function CFBundleCopyLocalizedString Lib CarbonLib (bundle as Integer, key as Integer, value as Integer, tableName as Integer) as Integer + + dim theRef as Integer + dim theString as CFString + + theRef = CFBundleCopyLocalizedString(me, key, value, tableName) + If theRef <> 0 then + theString = new CFString(theRef) + Else //no identifier was specified in the bundle plist, perhaps + theString = new CFString("") + End if + Return theString + #endif +End Function + +CFBundle.Localizations: +Function Localizations() As CFArray + #if targetMachO + Declare Function CFBundleCopyBundleLocalizations Lib CarbonLib (theBundle as Integer) as Integer + + dim theRef as Integer + dim theArray as CFArray + + theRef = CFBundleCopyBundleLocalizations(me) + CoreFoundation.CheckCFTypeRef theRef, "CFBundle", "Localizations", "CFBundleCopyBundleLocalizations" + theArray = new CFArray(theRef) + + Exception theProblem as CFTypeRefException + theArray = Nil + + Finally + CoreFoundation.Release theRef + Return theArray + + #endif + +End Function + +CFBundle.PreferredLocalizations: +Function PreferredLocalizations(locArray as CFArray) As CFArray + #if targetMachO + Declare Function CFBundleCopyPreferredLocalizationsFromArray Lib CarbonLib (locArray as Integer) as Integer + + dim theRef as Integer + dim theArray as CFArray + + theRef = CFBundleCopyPreferredLocalizationsFromArray(locArray) + CoreFoundation.CheckCFTypeRef theRef, "CFBundle", "PreferredLocalizations", "CFBundleCopyPreferredLocalizationsFromArray" + theArray = new CFArray(theRef) + + Exception theProblem as CFTypeRefException + theArray = Nil + + Finally + CoreFoundation.Release theRef + Return theArray + + #endif + +End Function + +CFData.Constructor: +Sub Constructor(theData as String) + #if targetMachO + Declare Function CFDataCreate Lib CarbonLib (allocator as Integer, bytes as CString, length as Integer) as Integer + + dim theRef as Integer + + Const kCFAllocatorDefault = 0 + + theRef = CFDataCreate(kCFAllocatorDefault, theData, LenB(theData)) + CoreFoundation.CheckCFTypeRef theRef, "CFData", "Constructor", "CFDataCreate failed." + me.Constructor theRef + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFData.Data: +Function Data() As MemoryBlock + dim L as Integer + dim m as MemoryBlock + + #if targetMachO + Declare Function CFDataGetLength Lib CarbonLib (theData as Integer) as Integer + Declare Sub CFDataGetBytes Lib CarbonLib (theData as Integer, rangeStart as Integer, rangeLength as Integer, buffer as Ptr) + + L = CFDataGetLength(me) + If L > 0 then + m = new MemoryBlock(L) + CFDataGetBytes me, 0, L, m + Else + m = nil + End if + Return m + #endif + +End Function + +CFData.Constructor: +Sub Constructor(theData as MemoryBlock) + + #if targetMachO + Declare Function CFDataCreate Lib CarbonLib (allocator as Integer, bytes as Ptr, length as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim theRef as Integer + + Const kCFAllocatorDefault = 0 + + If theData Is Nil then + me.Constructor "" + Else + theRef = CFDataCreate(kCFAllocatorDefault, theData, theData.Size) + CoreFoundation.CheckCFTypeRef theRef, "CFData", "Constructor2", "CFDataCreate" + me.Constructor theRef + End if + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFDate.Constructor: +Sub Constructor(absTime as Double) + #if targetMachO + Declare Function CFDateCreate Lib CarbonLib (at as Double) as Integer + + dim theRef as Integer + + theRef = CFDateCreate(absTime) + CoreFoundation.CheckCFTypeRef theRef, "CFDate", "Constructor", "CFDateCreate" + me.Constructor theRef + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFDate.Constructor: +Sub Constructor(d as Date) + #if targetMachO + Declare Function CFDateCreate Lib CarbonLib (allocator as Integer, at as Double) as Integer + + dim bundle as CFBundle + dim p as MemoryBlock + dim theRef as Integer + + Const CarbonFramework = "com.apple.Carbon" + Const kCFAbsoluteTimeIntervalSince1904 = "kCFAbsoluteTimeIntervalSince1904" + Const kCFAllocatorDefault = 0 + + If d Is Nil then + d = New Date + End if + + bundle = new CFBundle(CarbonFramework) + p = bundle.DataPointer(kCFAbsoluteTimeIntervalSince1904) + theRef = CFDateCreate(kCFAllocatorDefault, d.TotalSeconds - p.DoubleValue(0)) + CoreFoundation.CheckCFTypeRef theRef, "CFDate", "Constructor", "CFDateCreate" + me.Constructor theRef + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFDate.Operator_Convert: +Function Operator_Convert() As Date + dim bundle as CFBundle + dim p as MemoryBlock + dim d as Date + + Const CarbonFramework = "com.apple.Carbon" + Const kCFAbsoluteTimeIntervalSince1904 = "kCFAbsoluteTimeIntervalSince1904" + + bundle = new CFBundle(CarbonFramework) + p = bundle.DataPointer(kCFAbsoluteTimeIntervalSince1904) + d = new Date + d.TotalSeconds = me.AbsoluteTime + p.DoubleValue(0) + Return d +End Function + +CFDate.AbsoluteTime: +Function AbsoluteTime() As Double + #if targetMachO + Declare Function CFDateGetAbsoluteTime Lib CarbonLib (theDate as Integer) as Double + + Return CFDateGetAbsoluteTime(me) + #endif +End Function + +CFDate.Constructor: +Sub Constructor(theRef as Integer) + Super.Constructor theRef + //works around an Rb bug. +End Sub + +CFDictionary.Count: +Function Count() As Integer + #if targetMachO + Declare Function CFDictionaryGetCount Lib CarbonLib (theDict as Integer) as Integer + + Return CFDictionaryGetCount(me) + #endif +End Function + +CFDictionary.Value: +Function Value(key as Integer) As Integer + #if targetMachO + Declare Function CFDictionaryGetValueIfPresent Lib CarbonLib (theDict as Integer, key as Integer, ByRef value as Integer) as Boolean + + dim theValue as Integer + + If CFDictionaryGetValueIfPresent(me, key, theValue) then + Return theValue + Else + Raise new KeyNotFoundException + End if + #endif +End Function + +CFDictionary.HasKey: +Function HasKey(key as Integer) As Boolean + #if targetMachO + Declare Function CFDictionaryContainsKey Lib CarbonLib (theDict as Integer, key as Integer) as Boolean + + Return CFDictionaryContainsKey(me, key) + #endif +End Function + +CFDictionary.Key: +Function Key(index as Integer) As Integer + #if targetMachO + Declare Function CFDictionaryGetCount Lib CarbonLib (theDict as Integer) as Integer + Declare Sub CFDictionaryGetKeysAndValues Lib CarbonLib (theDict as Integer, keys as Ptr, values as Integer) + + Const Null = 0 + + If index < 0 or index > CFDictionaryGetCount(me) - 1 then + Raise new OutOfBoundsException + End if + + If me.keyList Is Nil then + me.keyList = new MemoryBlock(4*CFDictionaryGetCount(me)) //if Count = 0 then guard clause raised an exception + CFDictionaryGetKeysAndValues me, me.keyList, Null + End if + Return me.keyList.Long(4*index) + #endif +End Function + +CFDictionary.Constructor: +Sub Constructor(theKeys() as CFType, theValues() as CFType) + #if targetMachO + Declare Function CFDictionaryCreate Lib CarbonLib (allocator as Integer, keys as Ptr, values as Ptr, numValues as Integer, keyCallBacks as Ptr, valueCallBacks as Ptr) as Integer + Declare Function CFDictionaryCreate Lib CarbonLib (allocator as Integer, keys as Integer, values as Integer, numValues as Integer, keyCallBacks as Ptr, valueCallBacks as Ptr) as Integer + + dim bundle as CFBundle + dim keyBlock as MemoryBlock + dim valueBlock as MemoryBlock + dim keyCallbacks as MemoryBlock + dim valueCallbacks as MemoryBlock + dim theRef as Integer + dim i as Integer + + Const kCFAllocatorDefault = 0 + Const CarbonFramework = "com.apple.Carbon" + Const defaultKeyCallBacks = "kCFTypeDictionaryKeyCallBacks" + Const defaultValueCallBacks = "kCFTypeDictionaryValueCallBacks" + Const Null = 0 + + if UBound(theKeys) <> UBound(theValues) then + Raise new InvalidParameterException("Key count must equal value count.") + End if + + bundle = new CFBundle(CarbonFramework) + keyCallbacks = bundle.DataPointer(defaultKeyCallBacks) + valueCallbacks = bundle.DataPointer(defaultValueCallBacks) + + If UBound(theKeys) > 0 then + keyBlock = new MemoryBlock(4*(1 + UBound(theKeys))) + valueBlock = new MemoryBlock(4*(1 + UBound(theValues))) + For i = 0 to UBound(theKeys) + keyBlock.Long(4*i) = theKeys(i) + valueBlock.Long(4*i) = theValues(i) + Next + theRef = CFDictionaryCreate(kCFAllocatorDefault, keyBlock, valueBlock, 1 + UBound(theKeys), keyCallbacks, valueCallbacks) + Else + theRef = CFDictionaryCreate(kCFAllocatorDefault, Null, Null, 1 + UBound(theKeys), keyCallbacks, valueCallbacks) + End if + CoreFoundation.CheckCFTypeRef theRef, me.ClassName, "Constructor", "CFDictionaryCreate" + me.Constructor theRef + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFDictionary.Constructor: +Sub Constructor(theDictionary as CFDictionary) + #if targetMachO + Declare Function CFDictionaryCreateCopy Lib CarbonLib (allocator as Integer, theDict as Integer) as Integer + + dim theRef as Integer + dim noKeys(-1) as CFType, noValues(-1) as CFType + + Const kCFAllocatorDefault = 0 + + If theDictionary Is Nil then + me.Constructor(noKeys, noValues) + Else + theRef = CFDictionaryCreateCopy(kCFAllocatorDefault, me) + CoreFoundation.CheckCFTypeRef theRef, me.ClassName, "Constructor", "CFDictionaryCreateCopy" + me.Constructor theRef + End if + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFMutableArray.Value: +Sub Value(index as Integer, Assigns theValue as Integer) + #if targetMachO + Declare Function CFArrayGetCount Lib CarbonLib (theArray as Integer) as Integer + Declare Sub CFArraySetValueAtIndex Lib CarbonLib (theArray as Integer, idx as Integer, theVal as Integer) + + If index < 0 or index > CFArrayGetCount(me) - 1 then + Raise new OutOfBoundsException + End if + + CFArraySetValueAtIndex me, index, theValue + #endif +End Sub + +CFMutableArray.Constructor: +Sub Constructor() + + #if targetMachO + Declare Function CFArrayCreateMutable Lib CarbonLib (allocator as Integer, capacity as Integer, callbacks as Ptr) as Integer + + dim carbonBundle as CFBundle + dim p as MemoryBlock + dim theRef as Integer + + Const kCFAllocatorDefault = 0 + Const CarbonFramework = "com.apple.Carbon" + Const defaultCallBacks = "kCFTypeArrayCallBacks" + Const unlimited = 0 + + carbonBundle = new CFBundle(CarbonFramework) + p = carbonBundle.DataPointer(defaultCallBacks) + theRef = CFArrayCreateMutable(kCFAllocatorDefault, unlimited, p) + CoreFoundation.CheckCFTypeRef theRef, "CFMutableArray", "Constructor", "CFArrayCreateMutable" + me.Constructor theRef + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFMutableArray.Append: +Sub Append(theItem as CFType) + #if targetMachO + Declare Sub CFArrayAppendValue Lib CarbonLib (theArray as Integer, theValue as Integer) + + If theItem <> nil then + CFArrayAppendValue me, theItem + Else + CFArrayAppendValue me, 0 + End if + #endif +End Sub + +CFMutableString.Constructor: +Sub Constructor(s as String) + me.Constructor + me.Append s +End Sub + +CFMutableString.Append: +Sub Append(s as String) + Declare Sub CFStringAppendCString Lib CarbonLib (theString as Integer, cStr as CString, encoding as Integer) + + Const kCFTextEncodingUnknown = &hffff + + If Encoding(s) <> nil then + CFStringAppendCString me, s, s.Encoding.Code + Else + CFStringAppendCString me, s, kCFTextEncodingUnknown + End if +End Sub + +CFMutableString.Uppercase: +Sub Uppercase() + #if TargetMachO + Declare Sub CFStringUppercase Lib CarbonLib (theString as Integer, locale as Integer) + Declare Function CFLocaleGetSystem Lib CarbonLib () as Integer + + dim systemLocale as Integer + + systemLocale = CFLocaleGetSystem() + If systemLocale = 0 then + Return + End if + CFStringUppercase me, systemLocale + #endif +End Sub + +CFMutableString.Lowercase: +Sub Lowercase() + #if TargetMachO + Declare Sub CFStringLowercase Lib CarbonLib (theString as Integer, locale as Integer) + Declare Function CFLocaleGetSystem Lib CarbonLib () as Integer + + dim systemLocale as Integer + + systemLocale = CFLocaleGetSystem() + If systemLocale = 0 then + Return + End if + CFStringLowercase me, systemLocale + #endif +End Sub + +CFMutableString.Constructor: +Sub Constructor() + #if targetMachO + Declare Function CFStringCreateMutable Lib CarbonLib (alloc as Integer, maxLength as Integer) as Integer + + dim theRef as Integer + + theRef = CFStringCreateMutable(CoreFoundation.kCFAllocatorDefault, 0) + CoreFoundation.CheckCFTypeRef theRef, "CFMutableString", "Constructor", "CFStringCreateMutable" + me.Constructor(theRef) + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFNumber.IntegerValue: +Function IntegerValue() As Integer + #if targetMachO + Declare Function CFNumberGetValue Lib CarbonLib (number as Integer, theType as Integer, ByRef valuePtr as Integer) as Boolean + + dim theValue as Integer + + Const kCFNumberSInt32Type = 3 + + If CFNumberGetValue(me, kCFNumberSInt32Type, theValue) then + Return theValue + Else + Return theValue //but it's an approximate value + End if + #endif +End Function + +CFNumber.DoubleValue: +Function DoubleValue() As Double + #if targetMachO + Declare Function CFNumberGetValue Lib CarbonLib (number as Integer, theType as Integer, ByRef valuePtr as Double) as Boolean + + dim theValue as Double + + Const kCFNumberDoubleType = 13 + + if CFNumberGetValue(me, kCFNumberDoubleType, theValue) then + Return theValue + Else + Return theValue //but it's an approximate value + End if + #endif +End Function + +CFPreferences.Value: +Protected Function Value(key as CFString) As CFPropertyList + #if targetMachO + Declare Function CFPreferencesCopyAppValue Lib CarbonLib (key as Integer, appID as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim theRef as Integer + dim theValue as CFPropertyList + + theRef = CFPreferencesCopyAppValue(key, kCurrentApplication) + If theRef <> 0 then + theValue = NewCFPropertyListObject(theRef, 0) + Else + theValue = nil + End if + + Finally + CoreFoundation.Release theRef + Return theValue + + #endif + +End Function + +CFPreferences.Value: +Protected Sub Value(key as CFString, Assigns theValue as CFPropertyList) + #if targetMachO + Declare Sub CFPreferencesSetAppValue Lib CarbonLib (key as Integer, aValue as Integer, appID as Integer) + + CFPreferencesSetAppValue key, CFType(theValue), kCurrentApplication + #endif +End Sub + +CFPreferences.Save: +Protected Sub Save() + #if targetMachO + Declare Function CFPreferencesAppSynchronize Lib CarbonLib (appID as Integer) as Boolean + + If CFPreferencesAppSynchronize(kCurrentApplication) then + //success + Else + //failure + End if + #endif +End Sub + +CFPreferences.kCurrentApplication: +Private Function kCurrentApplication() As Integer + #if targetMachO + dim frameworkBundle as CFBundle + dim p as MemoryBlock + + Const CarbonFramework = "com.apple.Carbon" + + frameworkBundle = new CFBundle(CarbonFramework) + p = frameworkBundle.DataPointer("kCFPreferencesCurrentApplication") + If p Is Nil then + Return 0 + End if + Return p.Long(0) + #endif +End Function + +CFPropertyList.Operator_Convert: +Function Operator_Convert() As Integer + +End Function + +CFString.Operator_Convert: +Function Operator_Convert() As String + #if targetMachO + Declare Function CFStringGetLength Lib CarbonLib (theString as Integer) as Integer + Declare Function CFStringGetMaximumSizeForEncoding Lib CarbonLib (length as Integer, enc as Integer) as Integer + Declare Function CFStringGetCString Lib CarbonLib (theString as Integer, buffer as Ptr, bufferSize as Integer, enc as Integer) as Boolean + + dim charCount as Integer + dim maxSize as Integer + dim buffer as MemoryBlock + + Const kCFStringEncodingUTF8 = &h08000100 + + charCount = CFStringGetLength(me) + maxSize = CFStringGetMaximumSizeForEncoding(charCount, kCFStringEncodingUTF8) + buffer = new MemoryBlock(1 + maxSize) //one extra byte for CString terminator + If CFStringGetCString(me, buffer, buffer.Size, kCFStringEncodingUTF8) then + Return Left(DefineEncoding(buffer.StringValue(0, maxSize), Encodings.UTF8), charCount) + Else + Return "" + End if + #endif +End Function + +CFString.Constructor: +Sub Constructor(s as String) + #if targetMachO + Declare Function CFStringCreateWithCString Lib CarbonLib (alloc as Integer, cStr as CString,encoding as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (ref as Integer) + + dim theRef as Integer + + Const kCFAllocatorDefault = 0 + Const kCFStringEncodingInvalidId = &hffffffff + + If Encoding(s) <> nil then + theRef = CFStringCreateWithCString(kCFAllocatorDefault, s, Encoding(s).code) + Else + theRef = CFStringCreateWithCString(kCFAllocatorDefault, s, kCFStringEncodingInvalidId) + End if + CoreFoundation.CheckCFTypeRef theRef, "CFString", "Constructor", "CFStringCreateWithCString" + me.Constructor theRef + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFTimeZone.Constructor: +Sub Constructor(timeZoneName as CFString) + #if targetMachO + Declare Function CFTimeZoneCreateWithName Lib CarbonLib (allocator as Integer, name as Integer, tryAbbrev as Boolean) as Integer + + dim theRef as Integer + + Const kCFAllocatorDefault = 0 + + If timeZoneName Is Nil then + me.Constructor() + Else + theRef = CFTimeZoneCreateWithName(kCFAllocatorDefault, timeZoneName, true) + CoreFoundation.CheckCFTypeRef theRef, "CFTimeZone", "Constructor", "CFTimeZoneCreateWithName" + me.Constructor theRef + End if + + Finally + CoreFoundation.Release theRef + + #endif + +End Sub + +CFTimeZone.Name: +Function Name() As CFString + #if targetMachO + Declare Function CFTimeZoneGetName Lib CarbonLib (tz as Integer) as Integer + + dim theRef as Integer + dim theName as CFString + + theRef = CFTimeZoneGetName(me) + If theRef <> 0 then + theName = new CFString(theRef) + Else + theName = new CFString("") + End if + Return theName + + #endif + +End Function + +CFTimeZone.IsDST: +Function IsDST(d as Date) As Boolean + #if targetMachO + Declare Function CFTimeZoneIsDaylightSavingsTime Lib CarbonLib (tz as Integer, at as Double) as Boolean + + dim theDate as CFDate + + If d Is Nil then + d = new Date + End if + + theDate = new CFDate(d) + Return CFTimeZoneIsDaylightSavingsTime(me, theDate.AbsoluteTime) + #endif +End Function + +CFTimeZone.Constructor: +Sub Constructor() + #if targetMachO + Declare Function CFTimeZoneCopySystem Lib CarbonLib () as Integer + + dim theRef as Integer + + theRef = CFTimeZoneCopySystem() + CoreFoundation.CheckCFTypeRef theRef, "CFTimeZone", "Constructor", "CFTimeZoneCopySystem" + me.Constructor(theRef) + #endif +End Sub + +CFTimeZone.Abbreviation: +Function Abbreviation(d as Date) As String + #if targetMachO + Declare Function CFTimeZoneCopyAbbreviation Lib CarbonLib (tz as Integer, at as Double) as Integer + + dim abbrRef as Integer + dim abbr as CFString + dim theDate as CFDate + + If d Is Nil then + d = new Date + End if + + theDate = new CFDate(d) + abbrRef = CFTimeZoneCopyAbbreviation(me, theDate.AbsoluteTime) + If abbrRef <> 0 then + abbr = new CFString(abbrRef) + Else + abbr = new CFString("") + End if + + Finally + CoreFoundation.Release abbrRef + Return abbr + + #endif + +End Function + +CFTimeZone.Offset: +Function Offset(d as Date) As Double + + #if targetMachO + Declare Function CFTimeZoneGetSecondsFromGMT Lib CarbonLib (tz as Integer, at as Double) as Double + + dim theDate as CFDate + + If d Is Nil then + d = new Date + End if + + theDate = new CFDate(d) + Return CFTimeZoneGetSecondsFromGMT(me, theDate.AbsoluteTime)// value in seconds + #endif +End Function + +CFType.Constructor: +Sub Constructor(theRef as Integer) + #if targetMachO + Declare Function CFRetain Lib CarbonLib (ref as Integer) as Integer + + If theRef = 0 then + Raise new CFTypeRefException(me.ClassName, "Constructor", "CFRetain") + End if + + me.Ref = CFRetain(theRef) + CoreFoundation.CheckCFTypeRef me.Ref, me.ClassName, "Constructor", "CFRetain" + #endif +End Sub + +CFType.Destructor: +Sub Destructor() + #if targetMachO + Declare Sub CFRelease Lib CarbonLib (ref as Integer) + + If me.Ref <> 0 then + CFRelease me.Ref + me.Ref = 0 + End if + #endif +End Sub + +CFType.Equals: +Function Equals(theObj as CFType) As Boolean + #if targetMachO + Declare Function CFEqual Lib CarbonLib (cf1 as Integer, cf2 as Integer) as Boolean + + Return CFEqual(me, theObj) + #endif +End Function + +CFType.TypeID: +Function TypeID() As Integer + #if targetMachO + Declare Function CFGetTypeID Lib CarbonLib (cf as Integer) as Integer + + Return CFGetTypeID(me.Ref) + #endif +End Function + +CFType.Description: +Function Description() As CFString + #if targetMachO + Declare Function CFCopyDescription Lib CarbonLib (cf as Integer) as Integer + + dim descriptionRef as Integer + dim theDescription as CFString + + descriptionRef = CFCopyDescription(me.Ref) + If descriptionRef <> 0 then + theDescription = new CFString(descriptionRef) + Else + theDescription = new CFString("") + End if + + Finally + CoreFoundation.Release descriptionRef + Return theDescription + + #endif + +End Function + +CFType.TypeDescription: +Function TypeDescription() As CFString + #if targetMachO + Declare Function CFCopyTypeIDDescription Lib CarbonLib (cf as Integer) as Integer + + dim descriptionRef as Integer + dim theDescription as CFString + + descriptionRef = CFCopyTypeIDDescription(me.Ref) + If descriptionRef <> 0 then + theDescription = new CFString(descriptionRef) + Else + theDescription = new CFString("") + End if + + Finally + CoreFoundation.Release descriptionRef + Return theDescription + + #endif + +End Function + +CFType.RefCount: +Function RefCount() As Integer + #if targetMachO + Declare Function CFGetRetainCount Lib CarbonLib (cf as Integer) as Integer + #endif + + #if targetMachO + Return CFGetRetainCount(me.Ref) + #endif +End Function + +CFType.Hash: +Function Hash() As Integer + #if targetMachO + Declare Function CFHash Lib CarbonLib (cf as Integer) as Integer + + Return CFHash(me.Ref) + #endif +End Function + +CFType.Operator_Convert: +Function Operator_Convert() As Integer + Return me.Ref +End Function + +CFType.Show: +Sub Show() + #if targetMachO + Declare Sub CFShow Lib CarbonLib (obj as Integer) + + CFShow me + #endif +End Sub + +CFTypeRefException.Constructor: +Sub Constructor(theClass as String, theMethod as String, theCFFunction as String) + me.pClassName = theClass + me.pMethodName = theMethod + me.pFunctionName = theCFFunction +End Sub + +CFTypeRefException.ClassName: +Function ClassName() As String + Return me.pClassName +End Function + +CFTypeRefException.MethodName: +Function MethodName() As String + Return me.pMethodName +End Function + +CFTypeRefException.FunctionName: +Function FunctionName() As String + Return me.pFunctionName +End Function + +CFTypeRefException.Log: +Sub Log() + System.Log System.LogLevelError, me.ClassName + "." + me.MethodName + ": " + me.FunctionName + " failed." +End Sub + +CFURL.Constructor: +Sub Constructor(theURL as String) + me.Constructor Nil, theURL +End Sub + +CFURL.StringValue: +Function StringValue() As CFString + #if targetMachO + Declare Function CFURLGetString Lib CarbonLib (anURL as Integer) as Integer + + dim stringRef as Integer + dim cfStr as CFString + + stringRef = CFURLGetString(me) + CoreFoundation.CheckCFTypeRef stringRef, "CFURL", "StringValue", "CFURLGetString" + cfStr = new CFString(stringRef) + + Exception oops as CFTypeRefException + cfStr = new CFString("") + + Finally + CoreFoundation.Release stringRef + Return cfStr + + #endif + +End Function + +CFURL.Scheme: +Function Scheme() As CFString + + #if targetMachO + dim schemeRef as Integer + dim scheme as CFString + + Declare Function CFURLCopyScheme Lib CarbonLib (anURL as Integer) as Integer + + schemeRef = CFURLCopyScheme(me) + CoreFoundation.CheckCFTypeRef schemeRef, "CFURL", "Scheme", "CFURLCopyScheme" + scheme = new CFString(schemeRef) + + Exception theError as CFTypeRefException + scheme = new CFString("") + + Finally + CoreFoundation.Release schemeRef + Return scheme + + #endif + +End Function + +CFURL.NetLocation: +Function NetLocation() As CFString + + #if targetMachO + Declare Function CFURLCopyNetLocation Lib CarbonLib (anURL as Integer) as Integer + + dim netLocationRef as Integer + dim netLocation as CFString + + netLocationRef = CFURLCopyNetLocation(me) + CoreFoundation.CheckCFTypeRef netLocationRef, "CFURL", "NetLocation", "CFURLCopyNetLocation" + netLocation = new CFString(netLocationRef) + + Exception oops as CFTypeRefException + netLocation = new CFString("") + + Finally + CoreFoundation.Release netLocationRef + Return netLocation + + #endif + +End Function + +CFURL.Constructor: +Sub Constructor(f as FolderItem) + + #if targetMachO + Declare Function CFURLCreateFromFSRef Lib CarbonLib (allocator as Integer, fsRef as Ptr) as Integer + Declare Function CFURLCreateWithBytes Lib CarbonLib (allocator as Integer, relativeURLBytes as CString, length as Integer, encoding as Integer, baseURL as Integer) as Integer + + dim theFSRef as FSRef + dim parentURL as CFURL + dim theURLRef as Integer + + If f Is Nil then + Raise new InvalidParameterException("CFURL", "Constructor", "f cannot be nil.") + End if + + If f.Exists then + theFSRef = new FSRef(f) + theURLRef = CFURLCreateFromFSRef(CoreFoundation.kCFAllocatorDefault, theFSRef) + CoreFoundation.CheckCFTypeRef theURLRef, "CFURL", "Constructor", "CFURLCreateFromFSRef" + Else + If (f.Parent Is Nil OR NOT f.Parent.Exists) then + //the impossible has happened + Raise new RuntimeException + End if + parentURL = new CFURL(f.Parent) + theURLRef = CFURLCreateWithBytes(CoreFoundation.kCFAllocatorDefault, f.Name, LenB(f.Name), Encoding(f.Name).code, parentURL) + CoreFoundation.CheckCFTypeRef theURLRef, "CFURL", "Constructor", "CFURLCreateWithBytes" + End if + me.Constructor theURLRef + + Finally + CoreFoundation.Release theURLRef + + #endif + +End Sub + +CFURL.Constructor: +Sub Constructor(baseURL as CFURL, relativeURL as String) + #if targetMachO + Declare Function CFURLCreateWithBytes Lib CarbonLib (allocator as Integer, URLBytes as CString, length as Integer, encoding as Integer, baseURL as Integer) as Integer + + dim theURLRef as Integer + dim baseURLRef as Integer + + Const kCFAllocatorDefault = 0 + Const kCFStringEncodingInvalidId = &hffffffff + + If relativeURL <> "" then + If baseURL Is Nil then + baseURLRef = 0 + Else + baseURLRef = baseURL + End if + + If Encoding(relativeURL) <> nil then + theURLRef = CFURLCreateWithBytes(kCFAllocatorDefault, relativeURL, LenB(relativeURL), Encoding(relativeURL).Code, baseURLRef ) + Else + theURLRef = CFURLCreateWithBytes(kCFAllocatorDefault, relativeURL, LenB(relativeURL), kCFStringEncodingInvalidId, baseURLRef ) + End if + CoreFoundation.CheckCFTypeRef theURLRef, "CFURL", "Constructor", "CFURLCreateWithBytes" + Else + theURLRef = baseURL + End if + me.Constructor(theURLRef) + + Finally + CoreFoundation.Release theURLRef + + #endif + +End Sub + +CFURL.AbsoluteURL: +Function AbsoluteURL() As CFURL + #if targetMachO + Declare Function CFURLCopyAbsoluteURL Lib CarbonLib (relativeURL as Integer) as Integer + + Dim urlRef as Integer + dim newURL as CFURL + dim theRef as Integer + + theRef = me + urlRef = CFURLCopyAbsoluteURL(theRef) + If urlRef = 0 then + Return Nil + End if + newURL = new CFURL(urlRef) + + Finally + CoreFoundation.Release urlRef + Return newURL + + #endif + +End Function + +CFURL.BaseURL: +Function BaseURL() As CFURL + #if targetMachO + Declare Function CFURLGetBaseURL Lib CarbonLib (anURL as Integer) as Integer + + dim urlRef as Integer + dim theBaseURL as CFURL + + urlRef = CFURLGetBaseURL(me) + If urlRef <> 0 then + theBaseURL = new CFURL(urlRef) + Else + theBaseURL = nil + End if + + Finally + CoreFoundation.Release urlRef + Return theBaseURL + + #endif + +End Function + +CFURL.IsDecomposable: +Function IsDecomposable() As Boolean + #if targetMachO + Declare Function CFURLCanBeDecomposed Lib CarbonLib (anURL as Integer) as Boolean + + Return CFURLCanBeDecomposed(me) + #endif +End Function + +CFURL.Path: +Function Path() As String + #if targetMachO + Declare Function CFURLGetFileSystemRepresentation Lib CarbonLib (url as Integer, resolveAgainstBase as Boolean, buffer as Ptr, maxBufLen as Integer) as Boolean + + dim buffer as MemoryBlock + + buffer = new MemoryBlock(128) + Do + If CFURLGetFileSystemRepresentation(me, true, buffer, buffer.Size) then + Exit + Else + buffer.Size = 2*buffer.Size + End if + Loop Until buffer.Size >= 131072 + Return DefineEncoding(buffer.CString(0), Encodings.SystemDefault) + #endif +End Function + +CFURL.Item: +Function Item() As FolderItem + #if targetMachO + dim theItem as FolderItem + dim itemFSRef as FSRef + dim fileNameRef as Integer + dim fileName as CFString + dim parentURLRef as Integer + dim parentURL as CFURL + dim parentFSRef as FSRef + dim parentItem as FolderItem + + Declare Function CFURLGetFSRef Lib CarbonLib (url as Integer, fsRef as Ptr) as Boolean + Declare Function CFURLCopyLastPathComponent Lib CarbonLib (url as Integer) as Integer + Declare Function CFURLCreateCopyDeletingLastPathComponent Lib CarbonLib (allocator as Integer, url as Integer) as Integer + + itemFSRef = new FSRef + If CFURLGetFSRef(me, itemFSRef) then + theItem = itemFSRef + Else + fileNameRef = CFURLCopyLastPathComponent(me) + CoreFoundation.CheckCFTypeRef fileNameRef, "CFURL", "Item", "CFURLCopyLastPathComponent" + fileName = new CFString(fileNameRef) + parentURLRef = CFURLCreateCopyDeletingLastPathComponent(CoreFoundation.kCFAllocatorDefault, me) + CoreFoundation.CheckCFTypeRef parentURLRef , "CFURL", "Item", "CFURLCreateCopyDeletingLastPathComponent" + parentURL = new CFURL(parentURLRef) + parentFSRef = new FSRef + If CFURLGetFSRef(me, parentFSRef) then + parentItem = parentFSRef + If parentItem <> nil then + theItem = parentItem.Child(fileName) + Else + theItem = nil + End if + Else + theItem = Nil + End if + End if + + Exception oops as CFTypeRefException + theItem = Nil + + Finally + CoreFoundation.Release fileNameRef + CoreFoundation.Release parentURLRef + Return theItem + + #endif + +End Function + +CoreFoundation.UnescapeURL: +Function UnescapeURL(theURL as String, escapeList as String) As String + #if targetMachO + dim ref as Integer + dim theURLString as CFString + dim escapeRef as CFString + dim theResultRef as Integer + dim theResult as CFString + + Const kCFAllocatorDefault = 0 + + Declare Function CFURLCreateStringByReplacingPercentEscapes Lib CarbonLib (allocator as Integer, originalString as Integer, charactersToLeaveEscaped as Integer) as Integer + + If Encoding(theURL) Is Nil then + Raise new InvalidParameterException("theURL must have non-nil encoding.") + Else + theURL = ConvertEncoding(theURL, Encodings.UTF8) + End if + If Encoding(escapeList) Is Nil then + Raise new InvalidParameterException("escapeList must have non-nil encoding.") + Else + escapeList = ConvertEncoding(escapeList, Encodings.UTF8) + End if + + theURLString = new CFString(theURL) + escapeRef = new CFString(escapeList) + theResultRef = CFURLCreateStringByReplacingPercentEscapes(kCFAllocatorDefault, theURLString, escapeRef) + CoreFoundation.CheckCFTypeRef theResultRef, "CoreFoundation", "EscapeURL", "CFURLCreateStringByReplacingPercentEscapes" + theResult = new CFString(theResultRef) + + Exception oops as CFTypeRefException + theResult = new CFString("") + + Finally + CoreFoundation.Release theResultRef + Return theResult + + #endif + +End Function + +CoreFoundation.EscapeURL: +Function EscapeURL(theURL as String, unescapeList as String, escapeList as String) As String + #if targetMachO + dim urlRef as CFString + dim unescapeRef as CFString + dim escapeRef as CFString + dim escapedStringRef as Integer + dim escapedString as CFString + + Const kCFAllocatorDefault = 0 + + Declare Function CFURLCreateStringByAddingPercentEscapes Lib CarbonLib (allocator as Integer, originalString as Integer, unescape as Integer, escape as Integer, enc as Integer) as Integer + + If Encoding(theURL) Is Nil then + Raise new InvalidParameterException("theURL must have non-nil encoding.") + Else + theURL = ConvertEncoding(theURL, Encodings.UTF8) + End if + If Encoding(unescapeList) Is Nil then + Raise new InvalidParameterException("unescapeList must have non-nil encoding.") + Else + unescapeList = ConvertEncoding(unescapeList, Encodings.UTF8) + End if + If Encoding(escapeList) Is Nil then + Raise new InvalidParameterException("escapeList must have non-nil encoding.") + Else + escapeList = ConvertEncoding(escapeList, Encodings.UTF8) + End if + + urlRef = new CFString(theURL) + unescapeRef = new CFString(unescapeList) + escapeRef = new CFString(escapeList) + escapedStringRef = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, urlRef, unescapeRef, escapeRef, Encodings.UTF8.code) + CoreFoundation.CheckCFTypeRef escapedStringRef, "CoreFoundation", "EscapeURL", "CFURLCreateStringByAddingPercentEscapes" + escapedString = new CFString(escapedStringRef) + + Exception oops as CFTypeRefException + escapedString = new CFString("") + + Finally + CoreFoundation.Release escapedStringRef + Return escapedString + + #endif + +End Function + +CoreFoundation.XML: +Function XML(Extends theObj as CFPropertyList) As String + #if targetMachO + Declare Function CFPropertyListCreateXMLData Lib CarbonLib (allocator as Integer, propertyList as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim dataRef as Integer + dim theData as CFData + dim theXML as String + + Const kCFAllocatorDefault = 0 + + dataRef = CFPropertyListCreateXMLData(kCFAllocatorDefault, theObj) + If dataRef = 0 then + Return "" + End if + theData = new CFData(dataRef) + theXML = DefineEncoding(theData.Data, Encodings.UTF8) + + Finally + CoreFoundation.Release dataRef + Return theXML + + #endif + +End Function + +CoreFoundation.NewCFPropertyList: +Function NewCFPropertyList(theXML as String, mutability as Integer) As CFPropertyList + #if targetMachO + Declare Function CFPropertyListCreateFromXMLData Lib CarbonLib (allocator as Integer, xmlData as Integer, mutabilityOptions as Integer, errorString as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim theData as CFData + dim theRef as Integer + dim pList as CFPropertyList + + Const kCFAllocatorDefault = 0 + Const Null = 0 + + theData = new CFData(theXML) + theRef = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, theData, mutability, Null) + If theRef = 0 then + Return nil + End if + pList = NewCFPropertyListObject(theRef, mutability) + + Finally + CoreFoundation.Release theRef + Return pList + + #endif + +End Function + +CoreFoundation.Clone: +Function Clone(Extends theObj as CFPropertyList, mutability as Integer) As CFPropertyList + #if targetMachO + Declare Function CFPropertyListCreateDeepCopy Lib CarbonLib (allocator as Integer, propertyList as Integer, mutabilityOption as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim theRef as Integer + dim pListTypeID as Integer + dim pList as CFPropertyList + + Const kCFAllocatorDefault = 0 + + theRef = CFPropertyListCreateDeepCopy(kCFAllocatorDefault, theObj, mutability) + If theRef <> 0 then + pList = NewCFPropertyListObject(theRef, mutability) + Else + pList = nil + End if + + Finally + Release theRef + Return pList + + #endif + +End Function + +CoreFoundation.IsValid: +Function IsValid(Extends theObj as CFPropertyList, listFormat as Integer) As Boolean + #if targetMachO + Declare Function CFPropertyListIsValid Lib CarbonLib (cf as Integer, fmt as Integer) as Boolean + + Return CFPropertyListIsValid(theObj, listFormat) + #endif +End Function + +CoreFoundation.NewCFPropertyListObject: +Function NewCFPropertyListObject(theRef as Integer, mutability as Integer) As CFPropertyList + #if targetMachO + Declare Function CFGetTypeID Lib CarbonLib (cf as Integer) as Integer + Declare Function CFStringGetTypeID Lib CarbonLib () as Integer + Declare Function CFNumberGetTypeID Lib CarbonLib () as Integer + Declare Function CFBooleanGetTypeID Lib CarbonLib () as Integer + Declare Function CFDateGetTypeID Lib CarbonLib () as Integer + Declare Function CFDataGetTypeID Lib CarbonLib () as Integer + Declare Function CFArrayGetTypeID Lib CarbonLib () as Integer + Declare Function CFDictionaryGetTypeID Lib CarbonLib () as Integer + Declare Function CFRetain Lib CarbonLib (cf as Integer) as Integer + + dim pListTypeID as Integer + dim pList as CFPropertyList + + Const kCFPropertyListImmutable = 0 + Const kCFPropertyListMutableContainers = 1 + Const kCFPropertyListMutableContainersAndLeaves = 2 + + If theRef = 0 then + Return nil + End if + + theRef = CFRetain(theRef) + pListTypeID = CFGetTypeID(theRef) + If pListTypeID = CFStringGetTypeID then + If mutability = kCFPropertyListMutableContainersAndLeaves then + pList = new CFMutableString(theRef) + Else + pList = new CFString(theRef) + End if + ElseIf pListTypeID = CFNumberGetTypeID then + pList = new CFNumber(theRef) + ElseIf pListTypeID = CFBooleanGetTypeID then + pList = new CFBoolean(theRef) + ElseIf pListTypeID = CFDateGetTypeID then + pList = new CFDate(theRef) + ElseIf pListTypeID = CFDataGetTypeID then + If mutability = kCFPropertyListMutableContainersAndLeaves then + pList = new CFMutableData(theRef) + Else + pList = new CFData(theRef) + End if + ElseIf pListTypeID = CFArrayGetTypeID then + If mutability = kCFPropertyListImmutable then + pList = new CFArray(theRef) + Else + pList = new CFMutableArray(theRef) + End if + ElseIf pListTypeID = CFDictionaryGetTypeID then + If mutability = kCFPropertyListImmutable then + pList = new CFDictionary(theRef) + Else + pList = new CFMutableDictionary(theRef) + End if + Else + pList = nil + End if + + Finally + CoreFoundation.Release theRef + Return pList + + #endif + +End Function + +CoreFoundation.NewCFNumber: +Function NewCFNumber(theValue as Integer) As CFNumber + #if targetMachO + Declare Function CFNumberCreate Lib CarbonLib (allocator as Integer, theType as Integer, ByRef valuePtr as Integer) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim theRef as Integer + dim theNumber as CFNumber + + Const kCFNumberSInt32Type = 3 + + theRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, theValue) + CoreFoundation.CheckCFTypeRef theRef, "CoreFoundation", "NewCFNumber", "CFNumberCreate" + theNumber = new CFNumber(theRef) + + Finally + Release theRef + Return theNumber + + #endif + +End Function + +CoreFoundation.NewCFNumber: +Function NewCFNumber(theValue as Double) As CFNumber + #if targetMachO + Declare Function CFNumberCreate Lib CarbonLib (allocator as Integer, theType as Integer, ByRef valuePtr as Double) as Integer + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + dim theRef as Integer + dim theValueCopy as Double + dim theNumber as CFNumber + + Const kCFNumberDoubleType = 13 + + theRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, theValueCopy) + CoreFoundation.CheckCFTypeRef theRef, "CoreFoundation", "NewCFNumber", "CFNumberCreate" + theNumber = new CFNumber(theRef) + + Finally + Release theRef + Return theNumber + + #endif + +End Function + +CoreFoundation.CopyContents: +Sub CopyContents(sourceParent as FolderItem, destinationParent as FolderItem) + dim i as Integer + dim theItem as FolderItem + + If NOT sourceParent.Exists then + Return + End if + If Not sourceParent.Directory then + Return + End if + If destinationParent Is Nil then + Return + End if + If NOT destinationParent.Exists then + Return + End if + If NOT destinationParent.Directory then + Return + End if + + For i = 1 to sourceParent.Count + theItem = sourceParent.TrueItem(i) + If theItem <> nil then + If theItem.Directory then + destinationParent.Child(theItem.Name).CreateAsFolder + CopyContents theItem, destinationParent.Child(theItem.Name) + Else + theItem.CopyFileTo destinationParent.Child(theItem.Name) + if theItem.LastErrorCode <> 0 then + //handle error + End if + End if + Else + //a problem occurred + End if + Next +End Sub + +CoreFoundation.CurrentVersion: +Function CurrentVersion() As Double + #if targetMachO + dim frameworkBundle as CFBundle + dim p as MemoryBlock + + Const CarbonFramework = "com.apple.Carbon" + Const kCFCoreFoundationVersionNumber = "kCFCoreFoundationVersionNumber" + + frameworkBundle = new CFBundle(CarbonFramework) + p = frameworkBundle.DataPointer(kCFCoreFoundationVersionNumber) + + Exception oops as CFTypeRefException + p = new MemoryBlock(8) + + Finally + Return p.DoubleValue(0) + + #endif + +End Function + +CoreFoundation.TextEncodingList: +Protected Function TextEncodingList() As TextEncoding() + #if targetMachO + dim m as MemoryBlock + dim i as Integer + dim encodingList(-1) as TextEncoding + + Const kCFStringEncodingInvalidId = &hffffffff + + Declare Function CFStringGetListOfAvailableEncodings Lib CarbonLib () as Ptr + + m = CFStringGetListOfAvailableEncodings + If m <> Nil then + i = 0 + While m.Long(i) <> kCFStringEncodingInvalidId + encodingList.Append Encodings.GetFromCode(m.Long(i)) + i = i + 4 + Wend + Else + // + End if + Return encodingList + #endif + +End Function + +CoreFoundation.TimeZoneNameList: +Protected Function TimeZoneNameList() As String() + #if targetMachO + Declare Function CFTimeZoneCopyKnownNames Lib CarbonLib () as Integer + Declare Function CFGetRetainCount Lib CarbonLib (cf as Integer) as Integer + + dim theRef as Integer + dim theArray as CFArray + dim i, N as Integer + dim theList(-1) as String + + theRef = CFTimeZoneCopyKnownNames() + If theRef = 0 then + Return theList + End if + theArray = new CFArray(theRef) + N = theArray.Count - 1 + For i = 0 to N + If theArray.Value(i) <> 0 then + theList.Append new CFString(theArray.Value(i)) + End if + Next + + Finally + Release theRef + Return theList + + #endif + +End Function + +CoreFoundation.Release: +Protected Sub Release(theRef as Integer) + #if targetMachO + Declare Sub CFRelease Lib CarbonLib (cf as Integer) + + If theRef <> 0 then + CFRelease theRef + Else + //passing 0 to CFRelease is ver' bad + End if + #endif +End Sub + +CoreFoundation.SystemTimeZone: +Protected Function SystemTimeZone() As CFTimeZone + #if targetMachO + dim theRef as Integer + dim theTimeZone as CFTimeZone + + Declare Function CFTimeZoneCopySystem Lib CarbonLib () as Integer + + theRef = CFTimeZoneCopySystem() + CoreFoundation.CheckCFTypeRef theRef, "CoreFoundation", "SystemTimeZone", "CFTimeZoneCopySystem" + theTimeZone = new CFTimeZone(theRef) + + Finally + Release theRef + Return theTimeZone + + #endif + +End Function + +CoreFoundation.CheckCFTypeRef: +Protected Sub CheckCFTypeRef(theRef as Integer, theClass as String, theMethod as String, theFunction as String) + If theRef = 0 then + Raise new CFTypeRefException(theClass, theMethod, theFunction) + End if +End Sub + +FileManager.GetUserPrivileges: +Protected Function GetUserPrivileges(theFSRef as MemoryBlock) As Integer + #if targetMacOS + dim OSErr as Integer + dim catalogBitmap as Integer + dim catalogInfo as FSCatalogInfo + + Const kFSCatInfoUserPrivs = &h00020000 + Const Null = 0 + + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Ptr, outName as Integer, fsSpec as Integer, parentRef as Integer) as Short + + If theFSRef Is Nil then + Raise new NilObjectException + End if + + catalogBitmap = Bitwise.BitOr(0, kFSCatInfoUserPrivs) + catalogInfo = new FSCatalogInfo + OSErr = FSGetCatalogInfo(theFSRef, catalogBitmap, catalogInfo, Null, Null, Null) + If OSErr = 0 then + Return catalogInfo.Byte(13) + Else + Return 0 + End if + #endif +End Function + +FileManager.Swap: +Protected Sub Swap(f as FolderItem, g as FolderItem) + + #if TargetMacOS + dim OSError as Integer + dim fRef, gRef as FSRef + dim temp as FolderItem + dim fCatalogInfo, gCatalogInfo as FSCatalogInfo + dim catalogInfoFlags as Integer + dim error as RuntimeException + dim i as Integer + + Const kFSCatInfoContentMod = &h00000040 + Const kFSCatInfoAttrMod = &h00000080 + Const kFSCatInfoSettableInfo = &h00001FE3 + Const Null = 0 + + If f Is Nil or g Is Nil then + Raise new NilObjectException + End if + + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Ptr, outName as Integer, fsSpec as Integer, parentRef as Integer) as Short + Declare Function FSSetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Ptr) as Short + + fRef = new FSRef(f) + gRef = new FSRef(g) + catalogInfoFlags = kFSCatInfoSettableInfo + catalogInfoFlags = Bitwise.BitAnd(kFSCatInfoSettableInfo, Bitwise.OnesComplement(Bitwise.BitOr(kFSCatInfoAttrMod, kFSCatInfoContentMod))) + fCatalogInfo = new FSCatalogInfo + OSError = FSGetCatalogInfo(fRef, catalogInfoFlags, fCatalogInfo, Null, Null, Null) + If OSError <> 0 then + Raise new MacOSException("FSGetCatalogInfo", OSError) + End if + gCatalogInfo = new FSCatalogInfo + OSError = FSGetCatalogInfo(gRef, catalogInfoFlags, gCatalogInfo, Null, Null, Null) + If OSError <> 0 then + Raise new MacOSException("FSGetCatalogInfo", OSError) + End if + + For i = 1 to 10 + temp = GetTempFile(f.Parent) + If temp <> nil and NOT temp.Exists then + Exit + End if + Next + If temp Is Nil or temp.Exists then + error = new RuntimeException + error.Message = "Unable to create temp file." + Raise error + End if + f.MoveFileTo temp + If f.LastErrorCode <> 0 or f.Exists or NOT temp.Exists then + error = new RuntimeException + error.Message = "FolderItem.MoveFileTo failed." + Raise error + End if + g.MoveFileTo f + If g.LastErrorCode <> 0 or g.Exists or NOT f.Exists then + error = new RuntimeException + error.Message = "FolderItem.MoveFileTo failed." + Raise error + End if + temp.MoveFileTo g + If temp.LastErrorCode <> 0 or temp.Exists or NOT g.Exists then + error = new RuntimeException + error.Message = "FolderItem.MoveFileTo failed." + Raise error + End if + + //we need to recreate the FSRefs + fRef = new FSRef(f) + gRef = new FSRef(g) + OSError = FSSetCatalogInfo(fRef, catalogInfoFlags , fCatalogInfo) + If OSError <> 0 then + Raise new MacOSException("FSSetCatalogInfo", OSError) + End if + OSError = FSSetCatalogInfo(gRef, catalogInfoFlags , gCatalogInfo) + If OSError <> 0 then + Raise new MacOSException("FSSetCatalogInfo", OSError) + End if + #endif + +End Sub + +FileManager.GetTempFile: +Protected Function GetTempFile(parentFolder as FolderItem) As FolderItem + #if targetMacOS + dim tempFile as FolderItem + + If parentFolder Is Nil or NOT parentFolder.Directory then + Return nil + End if + + tempFile = parentFolder.Child("Temp" + Format(Rnd, "000000000000")) + Return tempFile + #endif +End Function + +FileManager.VolumeSupportsFSExchangeObjects: +Protected Function VolumeSupportsFSExchangeObjects(f as FolderItem) As Boolean + #if TargetMacOS + Declare Function PBHGetVolParmsSync Lib InterfaceLib (paramBlock as Ptr) as Short + + dim OSError as Integer + dim paramBlock as HIOParam + dim infoBuffer as GetVolParmsBuffer + + Const bSupportsFSExchangeObjects = 8 + + If f Is Nil then + Raise new NilObjectException + End if + + paramBlock = new HIOParam + paramBlock.Short(22) = f.MacVRefNum + infoBuffer = new GetVolParmsBuffer + paramBlock.Ptr(32) = infoBuffer + paramBlock.Long(36) = infoBuffer.Size + OSError = PBHGetVolParmsSync(paramBlock) + If OSError <> 0 then + Return False //? + End if + Return Bitwise.BitAnd(infoBuffer.Long(20), bSupportsFSExchangeObjects) <> 0 + #endif +End Function + +FileManager.ExchangeObjects: +Protected Sub ExchangeObjects(f as FolderItem, g as FolderItem) + #if TargetMacOS + dim OSError as Integer + dim fRef, gRef as MemoryBlock + dim error as RuntimeException + + If f Is Nil or g Is Nil then + Raise new NilObjectException + End if + + Declare Function FSExchangeObjects Lib InterfaceLib (f1 as Ptr, f2 as Ptr) as Integer + + fRef = new FSRef(f) + gRef = new FSRef(g) + OSError= FSExchangeObjects(fRef, gRef) + If OSError <> 0 then + Raise new MacOSException("FSExchangeObjects", OSError) + End if + #endif +End Sub + +FileManager.GetVolumeRef: +Function GetVolumeRef(index as Integer) As Integer + #if targetMacOS + dim volInfo as INteger//MemoryBlock + dim OSError as Integer + + Declare Function FSGetVolumeInfo Lib InterfaceLib (volume as Short, volumeIndex as Integer, ByRef actualVolume as Integer, whichInfo as Integer, info as Integer, volumeName as Integer, rootDirectory as Integer) as Short + + 'volInfo = new MemoryBlock(2) + OSError = FSGetVolumeInfo(0, index, volInfo, 0, 0, 0, 0) + Return volInfo\65536 + #endif +End Function + +FileManager.VolumeHasOpenFiles: +Protected Function VolumeHasOpenFiles(f as FolderItem) As Boolean + #if targetMacOS + dim OSError as Integer + dim info as FSVolumeInfo + dim flags as Integer + + Const kFSVolInfoFlags = &h2000 + Const kFSVolFlagFilesOpenMask = &h0040 + Const Null = 0 + + Declare Function FSGetVolumeInfo Lib InterfaceLib (volume as Short, volumeIndex as Integer, actualVolume as Integer, whichInfo as Integer, info as Ptr, volumeName as Integer, rootDirectory as Integer) as Short + + If f Is Nil then + Return False + End if + + info = new FSVolumeInfo + OSError = FSGetVolumeInfo(f.MacVRefNum, 0, Null, kFSVolInfoFlags, info, Null, Null) + If OSError <> 0 then + // + End if + flags = info.UShort(116) + Return (Bitwise.BitAnd(flags, kFSVolFlagFilesOpenMask) = kFSVolFlagFilesOpenMask) + #endif +End Function + +FileManager.IsNetworkVolume: +Protected Function IsNetworkVolume(f as FolderItem) As Boolean + #if TargetMacOS + dim OSError as Integer + dim paramBlock as HIOParam + dim infoBuffer as GetVolParmsBuffer + dim theResult as Boolean + + Declare Function PBHGetVolParmsSync Lib InterfaceLib (paramBlock as Ptr) as Short + + If f Is Nil then + Raise new NilObjectException + End if + + paramBlock = new HIOParam + paramBlock.Short(22) = f.MacVRefNum + infoBuffer = new GetVolParmsBuffer + paramBlock.Ptr(32) = infoBuffer + paramBlock.Long(36) = infoBuffer.Size + + OSError = PBHGetVolParmsSync(paramBlock) + If OSError <> 0 then + Return False + End if + theResult = (infoBuffer.Long(10) <> 0) + Return theResult + #endif + +End Function + +FileManager.Compare: +Protected Function Compare(ref1 as MemoryBlock, ref2 as MemoryBlock) As Boolean + #if targetMacOS + dim OSErr as Integer + + Declare Function FSCompareFSRefs Lib InterfaceLib (ref1 as Ptr, ref2 as Ptr) as Short + + if ref1 Is Nil or ref2 Is Nil then + Raise new NilObjectException + End if + + OSErr = FSCompareFSRefs(ref1, ref2) + Return OSErr = 0 + #endif +End Function + +FileManager.AddFolderModificationReceiver: +Sub AddFolderModificationReceiver(theReceiver as FolderModificationReceiver) + #if targetMacOS + If theReceiver Is Nil then + Return + End if + + If FolderModificationReceivers Is Nil then + FolderModificationReceivers = new Dictionary + End if + #endif +End Sub + +FileManager.RemoveFolderModificationReceiver: +Sub RemoveFolderModificationReceiver(theReceiver as FolderModificationReceiver) + +End Sub + +FileManager.FolderModificationEventDispatcher: +Sub FolderModificationEventDispatcher(message as Integer, flags as Integer, refcon as Integer, subscription as Integer) + +End Sub + +FileManager.ExchangeFiles: +Protected Sub ExchangeFiles(f as FolderItem, g as FolderItem) + #if TargetMacOS + dim OSError as Integer + dim fRef, gRef as MemoryBlock + + If f Is Nil or g Is Nil then + Raise new NilObjectException + End if + + Declare Function FSpExchangeFiles Lib InterfaceLib (f1 as Ptr, f2 as Ptr) as Integer + + fRef = new FSSpec(f) + gRef = new FSSpec(g) + OSError = FSpExchangeFiles(fRef, gRef) + If OSError <> 0 then + Raise new MacOSException("FSpExchangeFiles", OSError) + End if + #endif +End Sub + +FileManager.VolumeSupportsFSpExchangeFiles: +Protected Function VolumeSupportsFSpExchangeFiles(f as FolderItem) As Boolean + #if TargetMacOS + Declare Function PBHGetVolParmsSync Lib InterfaceLib (paramBlock as Ptr) as Short + + dim OSError as Integer + dim paramBlock as HIOParam + dim infoBuffer as GetVolParmsBuffer + + Const bHasFileIDs = 64 + + If f Is Nil then + Raise new NilObjectException + End if + + paramBlock = new HIOParam + paramBlock.Short(22) = f.MacVRefNum + infoBuffer = new GetVolParmsBuffer + paramBlock.Ptr(32) = infoBuffer + paramBlock.Long(36) = infoBuffer.Size + OSError = PBHGetVolParmsSync(paramBlock) + If OSError <> 0 then + Return false + End if + Return Bitwise.BitAnd(infoBuffer.Long(2), bHasFileIDs) <> 0 + #endif +End Function + +FileManager.Exchange: +Protected Sub Exchange(f as FolderItem, g as FolderItem) + #if targetMacOS + If f Is Nil then + Raise new InvalidParameterException("FileManager", "Exchange", "f cannot be nil.") + End if + If NOT f.Exists then + Raise new InvalidParameterException("FileManager", "Exchange", "f must exist.") + End if + If g Is Nil then + Raise new InvalidParameterException("FileManager", "Exchange", "g cannot be nil.") + End if + If NOT g.Exists then + Raise new InvalidParameterException("FileManager", "Exchange", "g must exist.") + End if + If f.MacVRefNum <> g.MacVRefNum then + Raise new InvalidParameterException("FileManager", "Exchange", "f and g must be on same volume.") + End if + + If VolumeSupportsFSExchangeObjects(f) then + ExchangeObjects f, g + ElseIf VolumeSupportsFSpExchangeFiles(f) then + ExchangeFiles f, g + Else + Swap f, g + End if + #endif +End Sub + +FolderModificationReceiver.Key: +Function Key() As Integer + #if targetMacOS + dim v as Variant + + v = me + Return v.Hash + #endif +End Function + +FSCatalogInfo.Constructor: +Sub Constructor() + #if targetMacOS + Super.MemoryBlock(144) + #endif +End Sub + +FSRef.Constructor: +Sub Constructor() + #if targetMacOS + Super.MemoryBlock 80 + #endif +End Sub + +FSRef.Constructor: +Sub Constructor(f as FolderItem) + #if TargetMacOS + Declare Function FSMakeFSRefUnicode Lib InterfaceLib (parentPtr as Ptr, nameLength as Integer, name as CString, enc as Integer, outRef as Ptr) as Short + Declare Function FSGetVolumeInfo Lib InterfaceLib (volume as Short, volumeIndex as Integer, actualVolume as Integer, whichInfo as Integer, info as Integer, volumeName as Integer, rootDirectory as Ptr) as Short + + dim parentFSRef as MemoryBlock + dim theFSRef as MemoryBlock + dim OSErr as Integer + dim itemName as String + + Const Null = 0 + Const kTextEncodingUnknown = &hffff + + If f Is Nil then + Raise new InvalidParameterException("f <> nil") + End if + If NOT f.Exists then + Raise new InvalidParameterException("f.Exists = true") + End if + + me.Constructor + + If f.Parent Is nil then //f is the root directory of the volume + OSErr = FSGetVolumeInfo(f.MacVRefNum, 0, Null, Null, Null, Null, me) + Else + parentFSRef = new FSRef(f.Parent) + itemName = ConvertEncoding(f.Name, Encodings.UTF16) + OSErr = FSMakeFSRefUnicode(parentFSRef, Len(itemName), itemName, kTextEncodingUnknown, me) + End if + If OSErr <> 0 then + Raise new MacOSException("FSMakeFSRefUnicode", OSErr) + End if + #endif +End Sub + +FSRef.Path: +Function Path() As String + + #if targetMacOS + dim pathBuffer as MemoryBlock + dim OSError as Integer + + Declare Function FSRefMakePath Lib InterfaceLib (ref as Ptr, path as Ptr, maxPathSize as Integer) as Integer + + pathBuffer = new MemoryBlock(256) + OSError = FSRefMakePath(me, pathBuffer, pathBuffer.Size) + If OSError <> 0 then + Return "" + End if + Return Trim(DefineEncoding(pathBuffer.StringValue(0, pathBuffer.Size), Encodings.ASCII)) + #endif + +End Function + +FSRef.Item: +Private Function Item(theFSRef as FSRef) As FolderItem + + #if targetMacOS + dim OSError as Integer + dim parentRef as FSRef + dim catalogInfo as MemoryBlock + dim f as FolderItem + dim i as Integer + dim parentDirectoryID as Integer + dim volumeID as Integer + dim itemName as MemoryBlock + + Const fsRtParID = 1 + Const kFSCatInfoNone = &h0000000 + Const kFSCatInfoVolume = &h00000004 + Const kFSCatInfoParentDirID = &h00000008 + Const Null = 0 + + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Integer, outName as Ptr, fsSpec as Integer, parentRef as Integer) as Short + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Ptr, outName as Integer, fsSpec as Integer, parentRef as Ptr) as Short + + If theFSRef Is Nil then + Return nil + End if + + parentRef = new FSRef + catalogInfo = new MemoryBlock(144) + OSError = FSGetCatalogInfo(theFSRef, kFSCatInfoVolume + kFSCatInfoParentDirID, catalogInfo, Null, Null, parentRef) + If OSError <> 0 then + Return nil + End if + parentDirectoryID = catalogInfo.Long(4) + If parentDirectoryID = fsRtParID then //is root directory, and parentRef is invalid + volumeID = catalogInfo.Short(2) + For i = 0 to VolumeCount - 1 + If Volume(i).MacVRefNum = volumeID then + f = Volume(i) + Exit + End if + Next + Return f + Else + f = me.Item(parentRef) + If f Is nil then + Return nil + End if + itemName = new MemoryBlock(512) + OSError = FSGetCatalogInfo(theFSRef, kFSCatInfoNone, Null, itemName, Null, Null) + If OSError <> 0 then + Return nil + End if + Return f.Child(DefineEncoding(itemName.StringValue(2, 2*itemName.UShort(0)), Encodings.UTF16)) + End if + #endif + +End Function + +FSRef.Operator_Convert: +Function Operator_Convert() As FolderItem + #if TargetMacOS + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Integer, outName as Ptr, fsSpec as Integer, parentRef as Integer) as Short + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Ptr, outName as Integer, fsSpec as Integer, parentRef as Ptr) as Short + + dim OSError as Integer + dim parentRef as FSRef + dim catalogInfo as FSCatalogInfo + dim f as FolderItem + dim i as Integer + dim parentDirectoryID as Integer + dim volumeID as Integer + dim itemName as HFSUniStr255 + + Const fsRtParID = 1 + Const kFSCatInfoNone = &h0000000 + Const kFSCatInfoVolume = &h00000004 + Const kFSCatInfoParentDirID = &h00000008 + Const Null = 0 + + parentRef = new FSRef + catalogInfo = new FSCatalogInfo + OSError = FSGetCatalogInfo(me, kFSCatInfoVolume + kFSCatInfoParentDirID, catalogInfo, Null, Null, parentRef) + If OSError <> 0 then + Return nil + End if + parentDirectoryID = catalogInfo.Long(4) + If parentDirectoryID = fsRtParID then //is root directory, and parentRef is invalid + volumeID = catalogInfo.Short(2) + For i = 0 to VolumeCount - 1 + If Volume(i).MacVRefNum = volumeID then + f = Volume(i) + Exit + End if + Next + Return f + Else + f = parentRef //calls Operator_Convert recursively + If f Is nil then + Return nil + End if + itemName = new HFSUniStr255 + OSError = FSGetCatalogInfo(me, kFSCatInfoNone, Null, itemName, Null, Null) + If OSError <> 0 then + Return nil + End if + Return f.TrueChild(itemName.RbString) + End if + #endif +End Function + +FSRef.Constructor: +Sub Constructor(theFSSpec as FSSpec) + #if TargetMacOS + Declare Function FSpMakeFSRef Lib InterfaceLib (source as Ptr, newRef as Ptr) as Short + + dim OSError as Integer + + If theFSSpec Is Nil then + Raise new InvalidParameterException("FSRef", "Constructor", "theFSSpec cannot be nil.") + End if + + me.Constructor() + OSError = FSpMakeFSRef(theFSSpec, me) + If OSError <> 0 then + Raise new MacOSException("FSpMakeFSRef", OSError) + End if + #endif +End Sub + +FSRef.IsValid: +Function IsValid() As Boolean + + #if targetMacOS + dim OSError as Integer + + Const kFSCatInfoNone = 0 + Const Null = 0 + + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Integer, outName as Integer, fsSpec as Integer, parentRef as Integer) as Short + + OSError = FSGetCatalogInfo(me, kFSCatInfoNone, Null, Null, Null, Null) + Return (OSError = 0) + #endif + +End Function + +FSRef.Name: +Function Name() As String + + #if targetMacOS + dim OSErr as Integer + dim itemName as HFSUniStr255 + + Const kFSCatInfoNone = 0 + Const Null = 0 + + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Integer, outName as Ptr, fsSpec as Integer, parentRef as Integer) as Short + + itemName = new HFSUniStr255 + OSErr = FSGetCatalogInfo(me, kFSCatInfoNone, Null, itemName, Null, Null) + If OSErr = 0 then + Return itemName.RBString + Else + Return "" + End if + #endif + +End Function + +FSRef.AlternateConstructor: +Sub AlternateConstructor(f as FolderItem) + #if TargetMacOS + Declare Function FSGetVolumeInfo Lib InterfaceLib (volume as Short, volumeIndex as Integer, actualVolume as Integer, whichInfo as Integer, info as Integer, volumeName as Integer, rootDirectory as Ptr) as Short + Declare Function FSMakeFSRefUnicode Lib InterfaceLib (parentPtr as Ptr, nameLength as Integer, name as CString, enc as Integer, outRef as Ptr) as Short + + dim parentRef as MemoryBlock + dim fileName as String + dim OSError as Integer + + Const kTextEncodingUnknown = &hffff + Const fsRtParID = 1 + Const Null = 0 + + If f Is Nil then + Raise new InvalidParameterException("FSRef.Constructor: f cannot be nil") + End if + If NOT f.Exists then + Raise new InvalidParameterException("FSRef.Constructor: f must exist.") + End if + + me.Constructor() + If f.MacDirID = fsRtParID then //f is a volume, so get root directory directly + OSError = FSGetVolumeInfo(f.MacVRefNum, 0, Null, Null, Null, Null, me) + Else + parentRef = new FSRef(new FSSpec(f.Parent)) + fileName = ConvertEncoding(f.name, Encodings.UTF16) + OSError = FSMakeFSRefUnicode(parentRef, Len(fileName), fileName, kTextEncodingUnknown, me) + If OSError <> 0 then + Raise new MacOSException("FSMakeFSRefUnicode", OSError) + End if + End if + #endif +End Sub + +FSSpec.Constructor: +Sub Constructor() + #if TargetMacOS + Super.MemoryBlock 70 + #endif +End Sub + +FSSpec.Constructor: +Sub Constructor(f as FolderItem) + #if TargetMacOS + Declare Function FSMakeFSSpec Lib InterfaceLib (vRefNum as Short, dirID as Integer, filename as Pstring, spec as Ptr) as Short + + dim OSError as Integer + dim fileName as String + + Const noError = 0 + Const fileNotFound = -43 + + If f Is Nil then + Raise new InvalidParameterException("FSSpec", "Constructor", "f cannot be nil.") + End if + + me.Constructor + + filename = ConvertEncoding(f.Name, Encodings.SystemDefault) + OSError = FSMakeFSSpec(f.MacVRefNum, f.MacDirID, fileName, me) + If OSError = noError or OSError = fileNotFound then + //success + Else + Raise new MacOSException("FSMakeFSSpec", OSError) + End if + #endif +End Sub + +FSSpec.Operator_Convert: +Function Operator_Convert() As FolderItem + #if TargetMacOS + Declare Function FSMakeFSSpec Lib InterfaceLib (vRefNum as Short, dirID as Integer, filename as Pstring, spec as Ptr) as Short + + dim f as FolderItem + dim i as Integer + dim parentSpec as FSSpec + dim OSError as Integer + + Const fsRtParID = 1 //directoryID of parent of root directory + + If me.parID = fsRtParID then //I am the root directory + For i = 0 to VolumeCount - 1 + If Volume(i).MacVRefNum = me.vRefNum then + f = Volume(i) + Exit + End if + Next + Return f + Else + parentSpec = new FSSpec + OSError = FSMakeFSSpec(me.vRefNum, me.parID, "", parentSpec) + If OSError <> 0 then + Return nil + End if + f = parentSpec + If f <> nil then + Return f.TrueChild(me.Name) + Else + Return nil + End if + End if + #endif +End Function + +FSSpec.Constructor: +Sub Constructor(theFSRef as FSRef) + #if targetMacOS + Declare Function FSGetCatalogInfo Lib InterfaceLib (ref as Ptr, whichInfo as Integer, catalogInfo as Integer, outName as Integer, fsSpec as Ptr, parentRef as Integer) as Short + + dim OSError as Integer + + Const kFSCatInfoNone = 0 + Const Null = 0 + + If theFSRef Is Nil then + Raise new InvalidParameterException("FSSpec", "Constructor", "theFSRef cannot be nil.") + End if + + me.Constructor + OSError = FSGetCatalogInfo(theFSRef, kFSCatInfoNone, Null, Null, me, Null) + If OSError <> 0 then + Raise new MacOSException("FSGetCatalogInfo", OSError) + End if + #endif +End Sub + +FSSpec.vRefNum: +Function vRefNum() As Integer + #if targetMacOS + Return me.Short(0) + #endif +End Function + +FSSpec.parID: +Function parID() As Integer + #if targetMacOS + Return me.Long(2) + #endif +End Function + +FSSpec.Name: +Function Name() As String + #if targetMacOS + Return DefineEncoding(me.PString(6), Encodings.SystemDefault) + #endif +End Function + +FSVolumeInfo.Constructor: +Sub Constructor() + #if targetMacOS + Super.MemoryBlock 126 + #endif +End Sub + +GetVolParmsBuffer.Constructor: +Sub Constructor() + + #if targetMacOS + Super.MemoryBlock(32) + #endif + +End Sub + +HFSUniStr255.Constructor: +Sub Constructor() + #if targetMacOS + Super.MemoryBlock(512) + #endif +End Sub + +HFSUniStr255.RBString: +Function RBString() As String + #if targetMacOS + Return DefineEncoding(me.StringValue(2, 2*me.UShort(0)), Encodings.UTF16) + #endif +End Function + +HIOParam.Constructor: +Sub Constructor() + #if targetMacOS + Super.MemoryBlock(50) + #endif +End Sub + +MacIcon.Constructor: +Sub Constructor(theIconRef as Integer) + #if targetMachO + Declare Function AcquireIconRef Lib kCarbon (theIconRef as Integer) as Short + + dim OSError as Integer + + me.Constructor() + OSError = AcquireIconRef(theIconRef) + me.IconRef = theIconRef + #endif +End Sub + +MacIcon.Destructor: +Sub Destructor() + #if targetMachO + me.Release me.IconRef + me.IconRef = 0 + #endif +End Sub + +MacIcon.Release: +Protected Sub Release(theIconRef as integer) + #if targetMachO + Declare Function ReleaseIconRef Lib kCarbon (theIconRef as Integer) as Short + + dim OSError as Integer + + OSError = ReleaseIconRef(theIconRef) + #endif +End Sub + +MacIcon.Constructor: +Sub Constructor(f as folderItem, size as integer) + #if targetMachO + + me.pSize = size + + dim OSError as Integer + dim theFileSpec as FSSpec + dim theIconRef as MemoryBlock + dim theLabel as MemoryBlock + + Const NULL = 0 + Const kSystemIconsCreator = "macs" + Const kUnknownFileType = "????" + Const kOnSystemDisk = -32768 + + Declare Function GetIconRef Lib kCarbon (vRefNum as Short, creator as OSType, icnType as OSType, theIconRef as Ptr) as Short + Declare Function GetIconRefFromFile Lib kCarbon (theFile as Ptr, theIconRef as Ptr, theLabel as Ptr) as Short + + If f <> Nil and f.Exists then + theFileSpec = new FSSpec(f) + theIconRef = new MemoryBlock(4) + theLabel = NewMemoryBlock(2) + OSError = GetIconRefFromFile(theFileSpec, theIconRef, theLabel) + Else + OSError = GetIconRef(kOnSystemDisk, kSystemIconsCreator, kUnknownFileType, theIconRef) + End if + me.Constructor(theIconRef.Long(0)) + + Finally + me.Release theIconRef.Long(0) + #endif + +End Sub + +MacIcon.Draw: +Protected Sub Draw(g as graphics, left as integer, top as integer) + #if targetMachO + Declare Function PlotIconRef Lib kCarbon (theRect as Ptr, align as Short, transform as Short, theIconServicesUsageFlags as Integer, iconRef as Integer) as Short + + dim OSError as Integer + dim rect as MemoryBlock + + const kAlignNone = 0 + const kIconServicesNormalUsageFlag = 0 + + g.FillRect 0, 0, 0, 0 //sets graphics port + rect = new Rect(Top, Left, Top + me.pSize - 1, Left + me.pSize - 1) + OSError = PlotIconRef(rect, kAlignNone, me.pTransform, kIconServicesNormalUsageFlag, me.IconRef) + + #endif +End Sub + +MacIcon.Operator_Convert: +Function Operator_Convert() As Picture + #if targetMachO + dim OSError as Integer + + Const depth = 32 + + Declare Function SetThemeBackground Lib kCarbon (inBrush as Integer, inDepth as Integer, inIsColorDevice as Boolean) as Integer + + If me.icon <> nil Then + Return me.icon + + Else + me.icon = new Picture(me.pSize, me.pSize, 32) + me.icon.transparent = 1 + + //* 32bit color *// + + me.icon.Graphics.ClearRect 0, 0, 1, 1 + OSError = SetThemeBackground(me.pBackground, depth, true) + me.icon.Graphics.ClearRect 0, 0, me.icon.Width, me.icon.Height + me.Draw me.icon.Graphics, 0, 0 + + //* 8bit Mask *// + + 'me.pTransform = BitWise.bitOr(&h4000, &h03) + ' + 'me.icon.mask.Graphics.ClearRect 0, 0, 1, 1 + 'OSError = SetThemeBackground(me.pBackground, depth, true) + 'me.icon.mask.Graphics.ClearRect 0, 0, me.icon.Width, me.icon.Height + 'me.Draw me.icon.mask.Graphics, 0, 0 + + Return me.icon + + End if + + #endif +End Function + +MacIcon.Constructor: +Sub Constructor() + #if targetMachO + Const kTransformNone = 0 + Const kThemeBrushListViewBackground = 10 + + me.pTransform = kTransformNone + me.pBackground = kThemeBrushListViewBackground + #endif +End Sub + +Rect.Constructor: +Sub Constructor(left as integer, top as integer, right as integer, bottom as integer) + #if targetMachO + + super.MemoryBlock(8) + super.short(0) = left + super.short(2) = top + super.short(4) = right + super.short(6) = bottom + + #endif +End Sub + +plist.plist: +Sub plist(f As FolderItem) + Load(f) +End Sub + +plist.Load: +Sub Load(f As folderItem) + dim t As textInputStream + dim s As string + + root=new plistDict + + savePath=f + + if f.exists then + t=f.OpenAsTextFile + while t.eof = false and s <> "<dict>" + s=t.ReadLine(Encodings.UTF8) + wend + if s="<dict>" then + root.Load(t,"root",false,nil,me,true) + else + error=true + errorMessage="Not a plist file" + end + t.close + else + error=true + errorMessage=f.AbsolutePath+" does not exist" + end + + if error then + root.load(t,"root",false,nil,me,false) + end + +End Sub + +plist.Save: +Sub Save() + dim o As TextOutputStream + + o=savePath.CreateTextFile + if o<>nil then + //header + o.WriteLine "<?xml version=""1.0"" encoding=""UTF-8""?>" + o.WriteLine "<!DOCTYPE plist PUBLIC ""-//Apple Computer//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">" + o.WriteLine "<plist version=""1.0"">" + o.WriteLine "<dict>" + + root.Write(o,1) + + //footer + o.WriteLine "</dict>" + o.WriteLine "</plist>" + else + error=true + errorMessage="Could not open file for saving" + end + o.close +End Sub + +plist.Find: +Function Find(searchText as string) As boolean + foundDict=nil + foundKey="" + foundValue="" + foundType="" + ClearSearch(root) + lastSearch=searchText + Return ReadStructure(root,searchText,"valueSearch") +End Function + +plist.ReadStructure: +Private Function ReadStructure(dict as plistDict,searchText as string,searchType as string) As boolean + Dim key,type,value as string + dim ok As Boolean + + dict.MoveFirst + While not dict.eof + key=dict.CurrentKey + type=dict.GetType(key) + If type="dict" or type="array" then + if ReadStructure(dict.child(key),searchText,searchType) then + return true + end + else + value=dict.GetValue(key) + if (instr(value,searchText)>0 and searchType="valueSearch") or (instr(key,searchText)>0 and searchType="keySearch") then + if not dict.searched.HasKey(key) then + dict.searched.Value(key)=false + end + if not dict.searched.Value(key) then + foundDict=dict + foundKey=key + foundType=type + foundValue=value + dict.searched.Value(key)=true + Return true + end + end + end + dict.MoveNext + Wend + return false + +End Function + +plist.FindNext: +Function FindNext(searchText as string) As boolean + if searchText<>lastSearch then + ClearSearch(root) + end + Return ReadStructure(root,searchText,"valueSearch") +End Function + +plist.ClearSearch: +Sub ClearSearch(dict as plistDict) + Dim key,type,value as string + dim ok As Boolean + + dict.MoveFirst + While not dict.eof + key=dict.CurrentKey + type=dict.GetType(key) + If type="dict" or type="array" then + ClearSearch(dict.child(key)) + else + dict.searched.Value(key)=false + end + dict.MoveNext + Wend + +End Sub + +plistDict.Load: +Sub Load(t As TextInputStream,n As string,ia As boolean,pr As plistDict,rt As plist,loadDict As boolean) + dim s,key,type,value,tag,endTag,tagValue,line As string + dim f,count,i As integer + dim inTag,placeHolder As boolean + + + values=new dictionary + types=new dictionary + name=n + parent=pr + rootClass=rt + indexOf=-1 + + isArray=ia + if isArray then + endTag="</array>" + else + endTag="</dict>" + end + if loadDict then + while not t.eof and s<>endTag and s<>"<dict/>" + if isArray and not inTag then + indexOf=indexOf+1 + key=str(indexOf) + end + line=StripAll(t.ReadLine) + line=replaceAll(line,"><",">"+chr(13)+"<") + line=ReplaceAll(line,">"+chr(13)+"</","></") + for i=1 to CountFields(line,chr(13)) + s=NthField(line,chr(13),i) + if left(s,5)="<key>" then + s=right(s,len(s)-5) + if right(s,6)="</key>" then + s=left(s,len(s)-6) + end + key=s + elseif s<>endTag then + if inTag and s<>"</"+tag+">" then + f=instr(s,"</"+tag+">") + if f>0 then + s=left(s,f-1) + inTag=false + end + value=value+CodeToBrackets(s) + if tag<>"data" then + value=value+chr(13) + end + if not inTag then + values.value(key)=CodeToBrackets(value) + end + else + f=instr(s,">") + if f>0 then + tag=left(s,f-1) + if left(tag,1)="<" then + tag=right(tag,len(tag)-1) + end + if tag="false/" then + types.value(key)="boolean" + values.value(key)="false" + type="boolean" + elseif tag="true/" then + types.value(key)="boolean" + values.value(key)="true" + type="boolean" + elseif tag="/"+type or tag="/key" then + inTag=false + values.value(key)=CodeToBrackets(value) + value="" + else + type=tag + if right(type,1)="/" then + type=left(type,len(type)-1) + placeHolder=true + else + placeHolder=false + end + types.value(key)=type + if type<>"array" and type<>"dict" and type<>"dict/" then + s=right(s,len(s)-f) + f=instr(s,"</"+type) + if f>0 then + value=left(s,f-1) + values.value(key)=CodeToBrackets(value) + else + inTag=true + f=instr(s,">") + if f=0 then + value=ReplaceAll(s,"&lt;","<") + value=ReplaceAll(value,"&gt;",">") + if type<>"data" then + value=value+chr(13) + end + else + value="" + end + end + end + end + if type="dict" then + children.append new plistDict + childrenNames.append key + children(ubound(children)).Load(t,key,false,me,rootClass,not placeHolder) + if placeHolder then + s="" + end + elseif type="array" then + children.append new plistDict + childrenNames.append key + children(ubound(children)).Load(t,key,true,me,rootClass,not placeHolder) + end + end + end + end + next + wend + end +End Sub + +plistDict.StripAll: +Protected Function StripAll(s As string) As string + dim temp As string + + if s<>"" then + temp=s + while asc(left(temp,1))<32 + temp=right(temp,len(temp)-1) + wend + end + return temp +End Function + +plistDict.child: +Function child(name As string) As plistDict + dim count As integer + + for count=1 to ubound(children) + if childrenNames(count)=name then + return children(count) + end + next + AddChild(name) + return child(name) + +End Function + +plistDict.GetValue: +Function GetValue(key As string,default As string) As string + dim result As string + + if not Exists(key) then + SetString(key,default) + end + if rootClass<>nil then + SetError(false,"") + end + if values.HasKey(key) then + if TypeOK(key) then + result=values.value(key) + end + else + SetError(true,"Key "+key+" does not exist") + end + return result +End Function + +plistDict.GetType: +Function GetType(key As string) As string + return types.value(key) +End Function + +plistDict.index: +Function index(index As integer) As plistDict + dim count As integer + + for count=1 to ubound(children) + if childrenNames(count)=str(index) then + return children(count) + end + next + return nil +End Function + +plistDict.Write: +Sub Write(o As TextOutputStream,level As integer) + dim count,count2 As integer + dim key,type,value,tabs As string + + for count=1 to level + tabs=tabs+chr(9) + next + for count=0 to types.count-1 + key=types.key(count) + type=types.value(key) + if type<>"dict" and type<>"array" then + value=BracketsToCode(values.value(key)) + end + if not isArray then + o.WriteLine tabs+"<key>"+key+"</key>" + end + if type="data" then + o.WriteLine tabs+"<data>" + o.WriteLine tabs+value + o.WriteLine tabs+"</data>" + elseif type="dict" then + for count2=1 to ubound(childrenNames) + if childrenNames(count2)=key then + if children(count2).count>0 then + o.WriteLine tabs+"<dict>" + children(count2).Write(o,level+1) + o.WriteLine tabs+"</dict>" + else + o.WriteLine tabs+"<dict/>" + end + end + next + elseif type="array" then + for count2=1 to ubound(childrenNames) + if childrenNames(count2)=key then + if children(count2).count>0 then + o.WriteLine tabs+"<array>" + children(count2).Write(o,level+1) + o.WriteLine tabs+"</array>" + else + o.WriteLine tabs+"<array/>" + end + end + next + elseif type="boolean" then + if value="true" then + o.WriteLine tabs+"<true/>" + else + o.WriteLine tabs+"<false/>" + end + else + o.WriteLine tabs+"<"+type+">"+value+"</"+type+">" + end + next +End Sub + +plistDict.GetString: +Function GetString(key As string,default As string) As string + return GetValue(key,default) +End Function + +plistDict.TypeOK: +Protected Function TypeOK(key As string) As boolean + dim type As string + + type=types.value(key) + if type="dict" or type="array" then + if rootClass<>nil then + SetError(true,"Illegal Type: "+key+" is a "+type) + end + return false + else + return true + end +End Function + +plistDict.GetInteger: +Function GetInteger(key As string,default As integer) As integer + dim value As integer + + if not Exists(key) then + SetInteger(key,default) + end + if TypeOK(key) then + if types.value(key)="date" then + SetError(true,"Type Mismatch: "+key+" is a date") + value=-1 + else + value=cdbl(GetValue(key)) + end + end + return value +End Function + +plistDict.GetBoolean: +Function GetBoolean(key As string,default As boolean) As boolean + dim value As boolean + + if not Exists(key) then + SetBoolean(key,default) + end + if types.value(key)<>"boolean" then + SetError(true,"Type Mismatch: "+key+" is a "+types.value(key)) + elseif values.value(key)="true" then + value=true + end + return value +End Function + +plistDict.GetDate: +Function GetDate(key As string,default As date) As date + dim dt As Date + dim value,datePart,timePart,month,day,year As string + dim f As integer + + if not Exists(key) then + SetDate(key,default) + end + if TypeOK(key) then + dt=new Date + value=GetValue(key) + f=instr(value,"T") + if f>0 then + datePart=left(value,f-1) + timePart=right(value,len(value)-f) + if right(timePart,1)="Z" then + timePart=left(timePart,len(timePart)-1) + end + else + datePart=value + end + year=NthField(datePart,"-",1) + month=NthField(datePart,"-",2) + day=NthField(datePart,"-",3) + datePart=month+"/"+day+"/"+year + if ParseDate(datePart,dt) then + if timePart<>"" then + dt.hour=cdbl(NthField(timePart,":",1)) + dt.minute=cdbl(NthField(timePart,":",2)) + dt.second=cdbl(NthField(timePart,":",3)) + end + else + SetError(true,"Could not create date object from "+key+"("+value+")") + end + end + return dt +End Function + +plistDict.GetData: +Function GetData(key As string,default As string) As string + return GetValue(key,default) +End Function + +plistDict.SetBoolean: +Sub SetBoolean(key As string,v As boolean) + dim result As integer + dim value As string + + result=CheckType(key,"boolean") + if result<>0 then + if v then + value="true" + else + value="false" + end + values.value(key)=value + types.value(key)="boolean" + searched.Value(key)=false + end + indexOf=-1 +End Sub + +plistDict.CheckType: +Protected Function CheckType(key As string,type As string) As integer + dim result As integer + + SetError(false,"") + // Check for correct type 0=incorrect type, 1=correct type, 2=does not exist + if types.HasKey(key) then + if types.value(key)=type then + result=1 + end + else + result=2 + end + if result=0 then + SetError(true,"Type Mismatch: "+key+" is a "+types.value(key)) + end + return result +End Function + +plistDict.SetString: +Sub SetString(key As string,v As string) + dim result As integer + + result=CheckType(key,"string") + if result<>0 then + values.value(key)=v + types.value(key)="string" + searched.Value(key)=false + end +End Sub + +plistDict.SetInteger: +Sub SetInteger(key As string,v As double) + dim result As integer + dim value As string + + result=CheckType(key,"integer") + if result<>0 then + values.value(key)=format(v,"-#") + types.value(key)="integer" + searched.Value(key)=false + end +End Sub + +plistDict.GetDouble: +Function GetDouble(key As string,default As double) As double + dim value As double + + if not Exists(key) then + SetDouble(key,default) + end + if TypeOK(key) then + if types.value(key)="date" then + SetError(true,"Type Mismatch: "+key+" is a date") + value=-1 + else + value=cdbl(GetValue(key)) + end + end + return value +End Function + +plistDict.SetDouble: +Sub SetDouble(key As string,v As double) + dim result As integer + dim value As string + + result=CheckType(key,"real") + if result<>0 then + values.value(key)=str(v) + types.value(key)="real" + searched.Value(key)=false + end +End Sub + +plistDict.SetData: +Sub SetData(key As string,v As string) + values.value(key)=v + types.value(key)="data" + searched.Value(key)=false +End Sub + +plistDict.SetDate: +Sub SetDate(key As string,dt As date) + dim result As integer + dim value As string + + result=CheckType(key,"date") + if result<>0 then + value=str(dt.year)+"-" + value=value+MakeTwo(dt.month)+"-" + value=value+MakeTwo(dt.day)+"T" + value=value+MakeTwo(dt.hour)+":" + value=value+MakeTwo(dt.minute)+":" + value=value+MakeTwo(dt.second)+"Z" + values.value(key)=value + types.value(key)="date" + searched.Value(key)=false + end +End Sub + +plistDict.MakeTwo: +Protected Function MakeTwo(value As integer) As string + if value>9 then + return str(value) + else + return "0"+str(value) + end +End Function + +plistDict.AddChild: +Sub AddChild(name As string) + dim index As integer + + SetError(false,"") + if types.HasKey(name) then + SetError(true,"Child exists: "+name+" already exists") + else + types.value(name)="dict" + childrenNames.append name + children.append new plistDict + index=ubound(children) + children(index).name=name + children(index).isArray=false + children(index).parent=me + children(index).rootClass=rootClass + searched.Value(name)=false + end +End Sub + +plistDict.plistDict: +Sub plistDict() + values=new dictionary + types=new dictionary + searched=new Dictionary + indexOf=-1 +End Sub + +plistDict.AddArray: +Function AddArray(name As string) As boolean + dim index As integer + + SetError(false,"") + if types.HasKey(name) then + SetError(true,"Array exists: "+name+" already exists") + return false + end + types.value(name)="array" + childrenNames.append name + children.append new plistDict + index=ubound(children) + children(index).name=name + children(index).isArray=true + children(index).parent=me + children(index).rootClass=rootClass + searched.Value(name)=false + return true +End Function + +plistDict.AppendInteger: +Sub AppendInteger(value As integer) + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="integer" + values.value(str(indexOf))=str(value) + end +End Sub + +plistDict.AppendDict: +Sub AppendDict() + dim index as integer + + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="dict" + childrenNames.append str(indexOf) + children.append new plistDict + index=ubound(children) + children(index).isArray=false + children(index).parent=me + children(index).rootClass=rootClass + end +End Sub + +plistDict.AppendArray: +Sub AppendArray() + dim index as integer + + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="array" + childrenNames.append str(indexOf) + children.append new plistDict + index=ubound(children) + children(index).name=str(indexOf) + children(index).isArray=true + children(index).parent=me + children(index).rootClass=rootClass + end +End Sub + +plistDict.AppendBoolean: +Sub AppendBoolean(value As boolean) + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="boolean" + if value then + values.value(str(indexOf))="true" + else + values.value(str(indexOf))="false" + end + end +End Sub + +plistDict.AppendDouble: +Sub AppendDouble(value As double) + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="double" + values.value(str(indexOf))=str(value) + end +End Sub + +plistDict.AppendString: +Sub AppendString(value As string) + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="string" + values.value(str(indexOf))=value + end +End Sub + +plistDict.AppendData: +Sub AppendData(value As string) + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="data" + values.value(str(indexOf))=value + end +End Sub + +plistDict.AppendDate: +Sub AppendDate(dt As date) + dim value As string + + if CheckArray then + indexOf=types.count + types.value(str(indexOf))="date" + + value=str(dt.year)+"-" + value=value+MakeTwo(dt.month)+"-" + value=value+MakeTwo(dt.day)+"T" + value=value+MakeTwo(dt.hour)+":" + value=value+MakeTwo(dt.minute)+":" + value=value+MakeTwo(dt.second)+"Z" + values.value(str(indexOf))=value + end +End Sub + +plistDict.CheckArray: +Function CheckArray() As boolean + SetError(false,"") + if isArray then + return true + else + SetError(true, name+" is not an array") + end +End Function + +plistDict.Remove: +Sub Remove(toRemove As variant) + dim i,index,which,cnt As integer + dim value,key,type As string + + if toRemove.isNumeric then + index=toRemove.IntegerValue + if CheckArray then + cnt=types.count-1 + if index>count-1 or index<0 then + SetError(true,"Subscript out of range") + end + key=str(index) + type=types.value(key) + if type="dict" or type="array" then + childrenNames.Remove(index+1) + children.Remove(index+1) + end + if values.hasKey(key) then + values.Remove(key) + end + types.Remove(key) + for i=index+1 to cnt + key=str(i) + if types.HasKey(key) then + type=types.value(key) + if values.hasKey(key) then + value=values.value(key) + end + key=str(i-1) + types.value(key)=type + if type<>"dict" and type<>"array" then + values.value(key)=value + end + end + next + key=str(cnt) + if types.hasKey(key) then + types.remove(key) + if values.hasKey(key) then + values.Remove(key) + end + end + end + else + key=toRemove.StringValue + if values.HasKey(key) then + values.Remove(key) + end + types.Remove(key) + for i=1 to ubound(childrenNames) + if key=childrenNames(i) then + which=i + end + next + if which>0 then + childrenNames.Remove(which) + children.Remove(which) + end + end +End Sub + +plistDict.count: +Function count() As integer + return types.count +End Function + +plistDict.MoveNext: +Sub MoveNext() + currentIndex=currentIndex+1 + if currentIndex>types.count-1 then + currentIndex=0 + eof=true + end +End Sub + +plistDict.MoveFirst: +Sub MoveFirst() + currentIndex=0 + eof=false +End Sub + +plistDict.MoveLast: +Sub MoveLast() + currentIndex=types.count-1 +End Sub + +plistDict.CurrentKey: +Function CurrentKey() As string + if currentIndex<=types.count-1 then + return types.key(currentIndex) + else + eof=true + currentIndex=0 + return "" + end +End Function + +plistDict.SetReal: +Sub SetReal(key As string,v As double) + dim result As integer + dim value As string + + result=CheckType(key,"double") + if result<>0 then + values.value(key)=str(v) + types.value(key)="real" + searched.Value(key)=false + end +End Sub + +plistDict.GetReal: +Function GetReal(key As string,default As double) As double + dim value As double + + if not Exists(key) then + SetReal(key,default) + end + if TypeOK(key) then + if types.value(key)="date" then + SetError(true,"Type Mismatch: "+key+" is a date") + value=-1 + else + value=cdbl(GetValue(key)) + end + end + return value +End Function + +plistDict.GetBoolean: +Function GetBoolean(key As string) As boolean + return GetBoolean(key,true) +End Function + +plistDict.Exists: +Function Exists(key As string) As boolean + return types.HasKey(key) +End Function + +plistDict.GetData: +Function GetData(key As string) As string + return GetData(key,"") +End Function + +plistDict.GetDate: +Function GetDate(key As string) As date + dim dt As date + + dt=new date + return GetDate(key,dt) +End Function + +plistDict.GetDouble: +Function GetDouble(key As string) As double + return GetDouble(key,0) +End Function + +plistDict.GetInteger: +Function GetInteger(key As string) As integer + return GetInteger(key,0) +End Function + +plistDict.GetReal: +Function GetReal(key As string) As double + return GetReal(key,0) +End Function + +plistDict.GetString: +Function GetString(key As string) As string + return GetString(key,"") +End Function + +plistDict.GetValue: +Function GetValue(key As string) As string + return GetValue(key,"") +End Function + +plistDict.BracketsToCode: +Function BracketsToCode(s As string) As string + dim temp As string + + temp=s + temp=ReplaceAll(temp,"<","&lt;") + temp=ReplaceAll(temp,">","&gt;") + return temp +End Function + +plistDict.CodeToBrackets: +Function CodeToBrackets(s As string) As string + dim temp As string + + temp=s + temp=ReplaceAll(temp,"&lt;","<") + temp=ReplaceAll(temp,"&gt;",">") + return temp +End Function + +plistDict.SetError: +Sub SetError(value As boolean,msg As string) + if rootClass<>nil then + rootClass.error=value + rootClass.errorMessage=msg + if value and rootClass.debug then + MsgBox msg + end + end +End Sub + +plistDict.Dump: +Sub Dump(level As integer) + dim count,count2 As integer + dim key,type,value,tabs As string + dim s,cr As string + dim c As clipboard + + cr=chr(13) + for count=1 to level + tabs=tabs+chr(9) + next + for count=0 to types.count-1 + key=types.key(count) + type=types.value(key) + if type<>"dict" and type<>"array" then + value=BracketsToCode(values.value(key)) + end + if not isArray then + s=s+tabs+"<key>"+key+"</key>"+cr + if searched.HasKey(key) then + s=s+tabs+"<search/>"+cr + else + s=s+tabs+"<nosearch/>"+cr + end + end + if type="data" then + s=s+tabs+"<data>"+cr + s=s+tabs+value+cr + s=s+tabs+"</data>"+cr + elseif type="dict" then + for count2=1 to ubound(childrenNames) + if childrenNames(count2)=key then + if children(count2).count>0 then + s=s+tabs+"<dict>"+cr + children(count2).Dump(level+1) + s=s+tabs+"</dict>"+cr + else + s=s+tabs+"<dict/>"+cr + end + end + next + elseif type="array" then + for count2=1 to ubound(childrenNames) + if childrenNames(count2)=key then + if children(count2).count>0 then + s=s+tabs+"<array>"+cr + children(count2).Dump(level+1) + s=s+tabs+"</array>"+cr + else + s=s+tabs+"<array/>"+cr + end + end + next + elseif type="boolean" then + if value="true" then + s=s+tabs+"<true/>"+cr + else + s=s+tabs+"<false/>"+cr + end + else + s=s+tabs+"<"+type+">"+value+"</"+type+">"+cr + end + next + c=new clipboard + c.text=c.text+s + c.close +End Sub + +plistDict.SetColor: +Sub SetColor(key as string,v as color) + dim result As integer + dim value As string + + result=CheckType(key,"string") + if result<>0 then + value=hex(v.red)+hex(v.green)+hex(v.blue) + values.value(key)=value + types.value(key)="string" + searched.Value(key)=false + indexOf=-1 + end +End Sub + +plistDict.GetColor: +Function GetColor(key As string) As color + return GetColor(key,RGB(0,0,0)) +End Function + +plistDict.GetColor: +Function GetColor(key As string,default As color) As color + dim c As color + dim value As string + + if not Exists(key) then + SetColor(key,default) + end + if types.value(key)<>"string" then + SetError(true,"Type Mismatch: "+key+" is a "+types.value(key)) + else + value=GetValue(key) + c=RGB(cdbl("&h"+left(value,2)),cdbl("&h"+mid(value,3,2)),cdbl("&h"+right(value,2))) + return c + end +End Function + +plistDict.AppendColor: +Sub AppendColor(v as color) + dim value as string + + if CheckArray then + indexOf=types.count + value=hex(v.red)+hex(v.green)+hex(v.blue) + types.value(str(indexOf))="string" + values.value(str(indexOf))=value + end +End Sub + +plistDict.SetList: +Sub SetList(key as string,items() as string,startIndex as integer,endIndex as integer) + dim count,si,ei as Integer + + if exists(key) then + Remove(key) + end + si=startIndex + ei=endIndex + if si>UBound(items) then + si=0 + end + if ei>UBound(items) then + ei=UBound(items) + end + if AddArray(key) then + searched.Value(key)=false + for count=si to ei + child(key).AppendString items(count) + next + end +End Sub + +plistDict.GetList: +Sub GetList(key as string,byref items() as string,indexStart as integer) + dim count As integer + dim newArray(0) as string + + if indexStart=0 then + redim newArray(-1) + end + for count=0 to child(key).count-1 + newArray.Append child(key).GetString(str(count)) + next + items=newArray +End Sub + +plistDict.AppendList: +Sub AppendList(items() as string,startIndex as integer,endIndex as integer) + dim count,si,ei,idx as Integer + + if CheckArray then + si=startIndex + ei=endIndex + if si>UBound(items) then + si=0 + end + if ei>UBound(items) then + ei=UBound(items) + end + AppendArray + idx=count-1 + for count=si to ei + child(str(idx)).AppendString items(count) + next + end +End Sub + +plistDict.AbsolutePath: +Function AbsolutePath() As string + path=":"+name + BuildPath(parent,path) + return path +End Function + +plistDict.BuildPath: +Private Sub BuildPath(parent as plistDict,p as string) + if parent.name<>"root" then + path=":"+parent.name+path + BuildPath(parent.parent,path) + else + path=":root"+path + end +End Sub + +plistDict.Move: +Sub Move(key as string,dest as plistDict,deleteSrc as boolean,newName as string) + dim value as Variant + dim type,nm,ck,targetName As string + dim dst as plistDict + + SetError(false,"") + if dest<>nil then + if Exists(key) then + type=types.Value(key) + if newName="" then + targetName=key + else + targetName=newName + end + select case type + case "array" + if dest.isArray then + dest.AppendDict + nm=str(dest.count) + dst=dest.child(nm) + else + nm=key + dest.AddChild(targetName) + dst=dest.child(targetName) + end + child(key).MoveFirst + while not child(key).eof + ck=child(key).CurrentKey + child(key).Move(ck,dst,false,"") + child(key).MoveNext + wend + case "dict" + if dest.isArray then + dest.AppendDict + nm=str(dest.count) + dst=dest.child(nm) + else + nm=key + dest.AddChild(targetName) + dst=dest.child(targetName) + end + child(key).MoveFirst + while not child(key).eof + ck=child(key).CurrentKey + child(key).Move(ck,dst,false,"") + child(key).MoveNext + wend + + case "string" + value=GetString(key) + if dest.isArray then + dest.AppendString value + else + dest.SetString(targetName,value) + end + + case "boolean" + value=GetBoolean(key) + if dest.isArray then + dest.AppendBoolean value + else + dest.SetBoolean(targetName,value) + end + + case "real" + value=GetDouble(key) + if dest.isArray then + dest.AppendDouble value + else + dest.SetDouble(targetName,value) + end + + case "integer" + value=GetInteger(key) + if dest.isArray then + dest.AppendInteger value + else + dest.SetInteger(targetName,value) + end + + case "data" + value=GetString(key) + if dest.isArray then + dest.AppendData value + else + dest.SetData(targetName,value) + end + + case "date" + value=GetDate(key) + if dest.isArray then + dest.AppendDate value + else + dest.SetDate(targetName,value) + end + end + + if deleteSrc then + Remove(key) + end + + else + SetError(true,"Source does not exist.") + end + else + SetError(true,"Destination is nil") + end +End Sub + +plistDict.Move: +Sub Move(key as string,dest as plistDict) + Move(key,dest,true,"") +End Sub + +plistDict.Copy: +Sub Copy(key as string,dest as plistDict) + Move(key,dest,false,"") +End Sub + +plistDict.Rename: +Sub Rename(key as string,newName as string) + SetError(false,"") + if Exists(newName) then + SetError(true,"Key "+newName+" already exists.") + else + Move(key,me,true,newName) + end +End Sub + +plistDict.GetList: +Sub GetList(key as string,byref items() as integer,indexStart as integer) + dim count As integer + dim newArray(0) as integer + + if indexStart=0 then + redim newArray(-1) + end + for count=0 to child(key).count-1 + newArray.Append child(key).GetInteger(str(count)) + next + items=newArray +End Sub + +plistDict.SetList: +Sub SetList(key as string,items() as integer,startIndex as integer,endIndex as integer) + dim count,si,ei as Integer + + if exists(key) then + Remove(key) + end + si=startIndex + ei=endIndex + if si>UBound(items) then + si=0 + end + if ei>UBound(items) then + ei=UBound(items) + end + if AddArray(key) then + searched.Value(key)=false + for count=si to ei + child(key).AppendInteger items(count) + next + end +End Sub + +plistDict.SetList: +Sub SetList(key as string,items() as boolean,startIndex as integer,endIndex as integer) + dim count,si,ei as Integer + + if exists(key) then + Remove(key) + end + si=startIndex + ei=endIndex + if si>UBound(items) then + si=0 + end + if ei>UBound(items) then + ei=UBound(items) + end + if AddArray(key) then + searched.Value(key)=false + for count=si to ei + child(key).AppendBoolean items(count) + next + end +End Sub + +plistDict.GetList: +Sub GetList(key as string,byref items() as boolean,indexStart as integer) + dim count As integer + dim newArray(0) as boolean + + if indexStart=0 then + redim newArray(-1) + end + for count=0 to child(key).count-1 + newArray.Append child(key).GetBoolean(str(count)) + next + items=newArray +End Sub + +CDownloadModel.getStateAsString: +Protected Function getStateAsString() As string + + dim status(-1) as string + + #if targetPPC or kOldJava + //* old core before bittorrent integration *// + + select case me.state + case 0 'QUEUED + return getLocalizedString("Queued", "Misc") + + case 1 'CONNECTING + return getLocalizedString("Connecting...", "Misc") + + case 2 'DOWNLOADING + + case 3 'BUSY + + case 4 'COMPLETE + return getLocalizedString("Complete", "Misc") + + case 5 'ABORTED + return getLocalizedString("Aborted", "Misc") + + case 6 'GAVE_UP + return getLocalizedString("Gave up", "Misc") + + case 7 'DISK_PROBLEM + return getLocalizedString("Disk error occurred", "Misc") + + case 8 'WAITING_FOR_RESULTS + return getLocalizedString("Gathering sources...", "Misc") + + case 9 'CORRUPT_FILE + return getLocalizedString("Possibly corrupt", "Misc") + + case 10 'REMOTE_QUEUED + + case 11 'HASHING + return getLocalizedString("Verifying...", "Misc") + + case 12 'SAVING + return getLocalizedString("Saving...", "Misc") + + case 13 'WAITING_FOR_USER + + case 14 'WAITING_FOR_CONNECTIONS + return getLocalizedString("Connecting...", "Misc") + + case 15 'ITERATIVE_GUESSING + return getLocalizedString("Gathering sources...", "Misc") + + case 16 'IDENTIFY_CORRUPTION + + case 17 'RECOVERY_FAILED + + case 18 'PAUSED + return getLocalizedString("Paused", "Misc") + + case 19 'INVALID + return getLocalizedString("Invalid license", "Misc") + + end + + #else //* new core *// + select case me.state + case 1 'QUEUED + return getLocalizedString("Queued", "Misc") + + case 2 'CONNECTING + return getLocalizedString("Connecting...", "Misc") + + case 5 'COMPLETE + return getLocalizedString("Complete", "Misc") + + case 6 'ABORTED + return getLocalizedString("Aborted", "Misc") + + case 7 'GAVE_UP + return getLocalizedString("Gave up", "Misc") + + case 8 'DISK_PROBLEM + return getLocalizedString("Disk error occurred", "Misc") + + case 9 'WAITING_FOR_RESULTS + return getLocalizedString("Gathering sources...", "Misc") + + case 10 'CORRUPT_FILE + return getLocalizedString("Possibly corrupt", "Misc") + + case 12 'HASHING + return getLocalizedString("Verifying...", "Misc") + + case 13 'SAVING + return getLocalizedString("Saving...", "Misc") + + case 20 'PAUSED + return getLocalizedString("Paused", "Misc") + + case 21 'INVALID + return getLocalizedString("Invalid license", "Misc") + + end + + #endif + + if me.active <> 0 then status.append _ + getLocalizedStringWithIntegerData("%i active", "Misc", me.active) + + if me.queued <> 0 then status.append _ + getLocalizedStringWithIntegerData("%i queued", "Misc", me.queued) + + if me.busy <> 0 then status.append _ + getLocalizedStringWithIntegerData("%i busy", "Misc", me.busy) + + if ubound(status) = -1 then + return getLocalizedString("No active sources", "Misc") + + else + return status.join(getLocalizedString(", ", "Misc")) + + end + +End Function + +CDownloadModel.isActive: +Function isActive() As boolean + + #if targetPPC or kOldJava + return me.isComplete = false and (me.state = 2 or me.measuredBandwidth <> 0) + #else + return me.isComplete = false and (me.state = 3 or me.measuredBandwidth <> 0) + #endif + +End Function + +CDownloadModel.Constructor: +Sub Constructor(args() as string) + + me.hashCode = args(1).val + me.filename = args(2) + me.state = args(3).val + me.amountRequested = args(4).val + me.amountTransfered = args(5).val + me.sha1 = args(6) + + me.extension = me.fileName.getExtension + me.progress = me.amountTransfered / me.amountRequested + +End Sub + +CDownloadModel.updateStats: +Sub updateStats(args() as string) + + me.state = args(2).val + me.amountRequested = args(3).val + me.amountTransfered = args(4).val + me.measuredBandwidth = args(5).val + me.averageBandwidth = args(6).val + me.active = args(7) + me.busy = args(8) + me.files = args(9) + me.queued = args(10) + me.path = args(11) + me.hosts = args(12) + + if me.measuredBandwidth <> 0 then + me.timeRemaining = (me.amountRequested - me.amountTransfered) / me.averageBandwidth + + else + me.timeRemaining = 0 + + end + + me.progress = me.amountTransfered / me.amountRequested + +End Sub + +CDownloadModel.invalidateValues: +Sub invalidateValues() + + me.sName = nil + + me.pTransfer = nil + me.sTransfer = nil + + me.pTime = nil + me.sTime = nil + +End Sub + +CDownloadModel.getSName: +Function getSName() As Variant + + if me.sName = nil then me.sName = me.getStateAsString + + return me.sName + +End Function + +CDownloadModel.canRemove: +Function canRemove() As boolean + + return me.isCanceled = false + +End Function + +CDownloadModel.getSTransfer: +Function getSTransfer() As Variant + + if me.sTransfer = nil then + if me.isComplete then + me.sTransfer = me.amountTransfered.getShortSize + + elseif me.amountTransfered = 0 then + me.sTransfer = "~/" + me.amountRequested.getShortSize + + else + me.sTransfer = me.amountTransfered.getShortSize + "/" + me.amountRequested.getShortSize + + end + + end + + return me.sTransfer + +End Function + +CFilterModel.Constructor: +Sub Constructor() + + me.enabled = false + me.sortColumn = -1 + me.sortDirection = ListBox.sortAscending + me.columnWidths = "18, 15%, 15%, 15%, 10%, 10%, 10%, 10%, 10%, 600" + +End Sub + +CFilterModel.Constructor: +Sub Constructor(keyword as string, enabled as boolean, media as integer, bitrate as integer, size as integer,sources as integer, speed as integer, sortColumn as integer, sortDirection as integer, columnWidths as string) + + me.keyword = keyword + me.enabled = enabled + me.media = media + me.bitrate = bitrate + me.size = size + me.sources = sources + me.speed = speed + me.sortColumn = sortColumn + me.sortDirection = sortDirection + me.columnWidths = columnWidths + +End Sub + +CFilterModel.Constructor: +Sub Constructor(filter as CFilterModel) + + me.bitrate = filter.bitrate + me.enabled = filter.enabled + me.keyword = filter.keyword + me.media = filter.media + me.size = filter.size + me.sortColumn = filter.sortColumn + me.sortDirection = filter.sortDirection + me.columnWidths = filter.columnWidths + me.sources = filter.sources + me.speed = filter.speed + me.scrollPosition = filter.scrollPosition + +End Sub + +CNetworkModel.Constructor: +Sub Constructor(args() as string) + + me.address = args(1) + me.agent = args(2) + me.language = args(3) + me.type = args(4) + me.uptime = ticks + +End Sub + +CNetworkModel.getPTime: +Function getPTime() As Variant + + if me.pTime = nil then me.pTime = getUptime(ticks - me.uptime) + + return me.pTime + +End Function + +CNetworkModel.invalidateValues: +Sub invalidateValues() + + me.pTime = nil + +End Sub + +CNetworkModel.getRepresentation: +Function getRepresentation() As variant + + return me.address + +End Function + +CQueryModel.Constructor: +Sub Constructor(queryIndex as integer, queryString as string, queryFilter as CFilterModel, keepInSidebar as boolean) + + dim arg, args(-1) as string + + me.response = new CResponseController + me.queryIndex = queryIndex + me.queryString = queryString + me.queryFilter = queryFilter + me.keepInSidebar = keepInSidebar + args = queryString.split(":") + + if queryString = getLocalizedString("What's New?", "Misc") then + me.queryType = 0 //* what's new query *// + + elseif ubound(args) = 1 and isNumeric(args(1)) then + me.queryType = 1 //* browse query *// + + elseif queryString.getExtension <> "" then + me.queryType = 2 //* find more sources query *// + + else + me.queryType = 3 //* normal query *// + args = queryString.lowercase.trim.split + + for each arg in args + if arg.leftb(1) = "-" then + me.negativeFilterKeywords.append arg.midb(2) + + else + me.positiveFilterKeywords.append arg + + end + + next + + end + +End Sub + +CQueryModel.clearAllResults: +Sub clearAllResults() + + redim me.response.representedObjects(-1) + me.response.representedInfos.clear + +End Sub + +CQueryModel.Constructor: +Sub Constructor(responses() as CResponseModel, hashTable as Dictionary) + + me.response = new CResponseController + me.response.representedObjects = responses + me.response.representedInfos = hashTable + +End Sub + +CQueryModel.Constructor: +Sub Constructor(queryString as string) + + me.response = new CResponseController + me.queryString = queryString + +End Sub + +CQueryModel.Constructor: +Sub Constructor() + + me.response = new CResponseController + +End Sub + +CResponseModel.addResponse: +Sub addResponse(args() as string) + + me.queryIndexes.append args(1).val + me.localIndexes.append args(2).val + + if me.address.indexOf(args(4)) = -1 then + + me.sources = me.sources + args(3).val + 1 + me.address.append args(4) + me.isBrowseHostEnabled.append (args(5).val = 1) + me.speed = me.speed + args(8).val + + end + +End Sub + +CResponseModel.Constructor: +Sub Constructor(args() as string) + + me.queryIndexes(0) = args(1).val + me.localIndexes(0) = args(2).val + + me.sources = args(3).val + 1 + me.address(0) = args(4) + me.isBrowseHostEnabled(0) = (args(5).val = 1) + + me.sha1 = args(6) + me.fileName = args(7) + me.extension = me.fileName.getExtension + me.mediaType = me.extension.getMediaType + me.speed = args(8).val + me.fileSize = args(9).val + me.bitrate = args(10).val + me.seconds = args(11).val + me.artist = args(12) + me.album = args(13) + me.title = args(14) + me.spam = (args(15).val = 1) + + if kAqID3Title and me.title.lenb <> 0 then + me.displayName = me.title + + else + me.displayName = me.fileName + + end + +End Sub + +CResponseModel.getPIcon: +Function getPIcon() As Variant + + if me.pIcon = nil then + if me.marked then + me.pIcon = getControlPicture(3) + + else + me.pIcon = getSmallMediaPicture(me) + + end + + end + + return me.pIcon + +End Function + +CResponseModel.getPSize: +Function getPSize() As Variant + + if me.pSize = nil then me.pSize = me.fileSize.getShortSize + + return me.pSize + +End Function + +CResponseModel.getPBitrate: +Function getPBitrate() As Variant + + if me.pBitrate = nil then me.pBitrate = me.bitrate.getKbps + + return me.pBitrate + +End Function + +CResponseModel.getPLength: +Function getPLength() As Variant + + if me.pLength = nil then me.pLength = me.seconds.getLength + + return me.pLength + +End Function + +CResponseModel.getPSources: +Function getPSources() As Variant + + if me.pSources = nil then me.pSources = me.sources.getQuality + + return me.pSources + +End Function + +CResponseModel.getPSpeed: +Function getPSpeed() As Variant + + if me.pSpeed = nil then me.pSpeed = me.speed.getKb + + return me.pSpeed + +End Function + +CResponseModel.invalidateValues: +Sub invalidateValues() + + me.pIcon = nil + me.pSources = nil + me.pSpeed = nil + +End Sub + +CResponseModel.convertEncoding: +Sub convertEncoding(type as integer) + + select case type + + case 0 + if me.displayName.canNonLossyConversation(Encodings.ISOLatin1) then _ + me.displayName = me.displayName.convertEncoding(Encodings.ISOLatin1).defineEncoding(Encodings.systemDefault) + if me.artist.canNonLossyConversation(Encodings.ISOLatin1) then _ + me.artist = me.artist.convertEncoding(Encodings.ISOLatin1).defineEncoding(Encodings.systemDefault) + if me.album.canNonLossyConversation(Encodings.ISOLatin1) then _ + me.album = me.album.convertEncoding(Encodings.ISOLatin1).defineEncoding(Encodings.systemDefault) + + case 1 + if me.displayName.canNonLossyConversation(Encodings.ASCII) then _ + me.displayName = me.displayName.convertEncoding(Encodings.ASCII).defineEncoding(Encodings.systemDefault) + if me.artist.canNonLossyConversation(Encodings.ASCII) then _ + me.artist = me.artist.convertEncoding(Encodings.ASCII).defineEncoding(Encodings.systemDefault) + if me.album.canNonLossyConversation(Encodings.ASCII) then _ + me.album = me.album.convertEncoding(Encodings.ASCII).defineEncoding(Encodings.systemDefault) + + 'case 2 + 'if me.displayName.canNonLossyConversation(Encodings.ASCII) then _ + 'me.displayName = me.displayName.convertEncoding(Encodings.ASCII).convertPSString.defineEncoding(Encodings.systemDefault) + 'if me.artist.canNonLossyConversation(Encodings.ASCII) then _ + 'me.artist = me.artist.convertEncoding(Encodings.ASCII).convertPSString.defineEncoding(Encodings.systemDefault) + 'if me.album.canNonLossyConversation(Encodings.ASCII) then _ + 'me.album = me.album.convertEncoding(Encodings.ASCII).convertPSString.defineEncoding(Encodings.systemDefault) + + end + +End Sub + +CResponseModel.getRepresentation: +Function getRepresentation() As variant + + return me.sha1 + +End Function + +CSidebarModel.Constructor: +Sub Constructor(caption as string) + + me.caption = caption + me.primary = 0 + me.secondary = 0 + me.index = 0 + me.interval = -1 + me.highlighted = true + +End Sub + +CSidebarModel.getRepresentation: +Function getRepresentation() As variant + + return me.index + +End Function + +CSidebarModel.Constructor: +Sub Constructor(caption as string, index as integer, interval as integer) + + me.caption = caption + me.primary = 0 + me.secondary = 0 + me.index = index + me.interval = interval + +End Sub + +CSidebarModel.incrementStats: +Sub incrementStats(selected as boolean, increaseSecondary as boolean) + + me.highlighted = not selected + me.primary = me.primary + 1 + + if increaseSecondary then me.secondary = me.secondary + 1 + +End Sub + +CSidebarModel.overwriteStats: +Sub overwriteStats(index as integer, interval as integer) + + me.index = index + me.interval = interval + +End Sub + +CSidebarModel.getPState: +Function getPState() As variant + + if me.pState = nil then + if me.primary = 0 then + me.pState = nil + + elseif me.primary = me.secondary then + me.pState = me.primary + + else + me.pState = me.secondary + "/" + me.primary + + end + + end + + return me.pState + +End Function + +CSidebarModel.invalidateValues: +Sub invalidateValues() + + me.pState = nil + +End Sub + +CSidebarModel.updateStats: +Sub updateStats(primary as variant, secondary as variant) + + me.primary = primary + me.secondary = secondary + +End Sub + +CStatsModel.getRepresentation: +Function getRepresentation() As variant + + //* Overide *// + +End Function + +CToolbarModel.Constructor: +Sub Constructor(caption as string, helptag as string, width as integer) + + me.caption = caption + me.helpTag = helpTag + me.width = width + +End Sub + +CTransferModel.getMediaType: +Function getMediaType() As Integer + + return me.extension.getMediaType + +End Function + +CTransferModel.getPName: +Function getPName() As Variant + + if me.pName = nil then me.pName = me.fileName + + return me.pName + +End Function + +CTransferModel.isActive: +Function isActive() As boolean + + //* Overrides *// + +End Function + +CTransferModel.canRemove: +Function canRemove() As Boolean + + //* Override *// + +End Function + +CTransferModel.getSTime: +Function getSTime() As Variant + + if me.sTime = nil and me.isComplete = false and me.timeRemaining <> 0 then me.sTime = getLocalizedString("remaining", "Misc") + + return me.sTime + +End Function + +CTransferModel.getPTime: +Function getPTime() As Variant + + if me.pTime = nil and me.isComplete = false and me.timeRemaining <> 0 then me.pTime = me.timeRemaining.getTimeRemaining + + return me.pTime + +End Function + +CTransferModel.getPTransfer: +Function getPTransfer() As Variant + + if me.pTransfer = nil and me.isComplete = false and me.measuredBandwidth <> 0 then me.pTransfer = me.measuredBandwidth.getKbs + + return me.pTransfer + +End Function + +CTransferModel.getSName: +Function getSName() As Variant + + //* Override *// + +End Function + +CTransferModel.getSTransfer: +Function getSTransfer() As Variant + + //* Override *// + +End Function + +CTransferModel.getPIcon: +Function getPIcon() As Variant + + if me.pIcon = nil then me.pIcon = getLargeMediaPicture(me.getMediaType, me.extension) + + return me.pIcon + +End Function + +CTransferModel.getRepresentation: +Function getRepresentation() As variant + + return me.hashCode + +End Function + +CUploadModel.isActive: +Function isActive() As boolean + + return me.isComplete = false and (me.state = 3 or me.measuredBandwidth <> 0) + +End Function + +CUploadModel.Constructor: +Sub Constructor(args() as string) + + me.hashCode = args(1).val + me.fileName = args(2) + me.ip = args(3) + me.port = args(4) + me.userAgent = args(5) + me.state = args(6).val + me.amountRequested = args(7).val + me.amountTransfered = args(8).val + me.path = args(9) + me.isBrowseHostEnabled = (args(10).val = 1) + + me.extension = me.fileName.getExtension + me.progress = me.amountTransfered / me.amountRequested + me.startingPoint = me.amountTransfered + +End Sub + +CUploadModel.canRemove: +Function canRemove() As boolean + + return true + +End Function + +CUploadModel.updateStats: +Sub updateStats(args() as string) + + me.state = args(2).val + me.amountRequested = args(3).val + me.amountTransfered = args(4).val + me.measuredBandwidth = args(5).val + me.averageBandwidth = args(6).val + + if me.measuredBandwidth <> 0 then + me.timeRemaining = (me.amountRequested - me.amountTransfered) / me.averageBandwidth + + else + me.timeRemaining = 0 + + end + + me.progress = me.amountTransfered / me.amountRequested + +End Sub + +CUploadModel.invalidateValues: +Sub invalidateValues() + + me.pTransfer = nil + me.sTransfer = nil + + me.pTime = nil + me.sTime = nil + +End Sub + +CUploadModel.getSName: +Function getSName() As Variant + + if me.sName = nil then + if me.isBrowseHostEnabled then + me.sName = me.ip + ":" + me.port + getLocalizedString(", ", "Misc") + me.userAgent + + else + me.sName = me.ip + getLocalizedString(", ", "Misc") + me.userAgent + + end + + end + + return me.sName + +End Function + +CUploadModel.getSTransfer: +Function getSTransfer() As Variant + + if me.sTransfer = nil then + if me.isComplete then + me.sTransfer = getLocalizedStringWithStringData("%@ sent", "Misc", me.amountTransfered.getShortSize) + + elseif me.amountTransfered = 0 then + me.sTransfer = "~/" + me.amountRequested.getShortSize + + else + me.sTransfer = me.amountTransfered.getShortSize + "/" + me.amountRequested.getShortSize + + end + + end + + return me.sTransfer + +End Function + +MApplicationExtension.notifyStart: +Sub notifyStart(w as window) + + #if targetMacOS + Declare Function NMInstall Lib kCarbon (nmReqPtr as Ptr) As Integer + Declare Function GetResource lib kCarbon (resType as integer, resID as integer) as integer + + dim resourceType as memoryBlock + dim flashIconHandle as integer + + const kResourceIDFinder = 3 + + if notify = nil then + resourceType = newMemoryBlock(5) + resourceType.pString(0) = "SICN" + flashIconHandle = GetResource(resourceType.long(1), kResourceIDFinder) + notify = newMemoryBlock(36) + notify.short(4) = 8 + notify.short(14) = 1 + notify.long(16) = flashIconHandle + + call NMInstall(notify) + + end + + #elseif targetWin32 + Dim FlashInfo As memoryblock + + Const FLASHW_STOP = 0 'Stop flashing. The system restores the window to its original state. + Const FLASHW_CAPTION = &H1 'Flash the window caption. + Const FLASHW_TRAY = &H2 'Flash the taskbar button. + Const FLASHW_TIMER = &H4 'Flash continuously, until the FLASHW_STOP flag is set. + Const FLASHW_TIMERNOFG = &HC 'Flash continuously until the window comes to the foreground. + + if targetNT then + Declare Function FlashWindowEx Lib "user32" (pfwi As ptr) As integer + flashinfo = newmemoryBlock(20) + 'Specifies the size of the structure. + flashinfo.Long(0) = 20 + 'Specifies the flash status + flashinfo.long(8) = FLASHW_CAPTION + FLASHW_TRAY + FLASHW_TIMERNOFG + 'Specifies the rate, in milliseconds, at which the window will be flashed. If dwTimeout is zero, the function uses the default cursor blink rate. + FlashInfo.long(16) = 0 + 'Handle to the window to be flashed. The window can be either opened or minimized. + FlashInfo.long(4) = w.winhWND + 'Specifies the number of times to flash the window. + FlashInfo.long(12) = 0 + call FlashWindowEx(FlashInfo) + + else + Declare Function FlashWindow Lib "user32" (hwnd As integer, bInvert As integer) As integer + call FlashWindow(w.winhwnd, 1) + + end + + #elseif targetLinux + 'todo + + #endif + +End Sub + +MApplicationExtension.notifyStop: +Sub notifyStop(w as window) + + #if targetMacOS + Declare Function NMRemove Lib kCarbon (nmReqPtr as Ptr) As Integer + + if notify <> nil then + call NMRemove(notify) + notify = nil + + end + + #elseif targetWin32 + Dim FlashInfo As memoryblock + + Const FLASHW_STOP = 0 'Stop flashing. The system restores the window to its original state. + Const FLASHW_CAPTION = &H1 'Flash the window caption. + Const FLASHW_TRAY = &H2 'Flash the taskbar button. + Const FLASHW_TIMER = &H4 'Flash continuously, until the FLASHW_STOP flag is set. + Const FLASHW_TIMERNOFG = &HC 'Flash continuously until the window comes to the foreground. + + if targetNT then + Declare Function FlashWindowEx Lib "user32" (pfwi As ptr) As integer + flashinfo = newmemoryBlock(20) + 'Specifies the size of the structure. + flashinfo.Long(0) = 20 + 'Specifies the flash status + flashinfo.long(8) = FLASHW_STOP + 'Specifies the rate, in milliseconds, at which the window will be flashed. If dwTimeout is zero, the function uses the default cursor blink rate. + FlashInfo.long(16) = 0 + 'Handle to the window to be flashed. The window can be either opened or minimized. + FlashInfo.long(4) = w.winhWND + 'Specifies the number of times to flash the window. + FlashInfo.long(12) = 0 + call FlashWindowEx(FlashInfo) + + end + + #elseif targetLinux + 'todo + + #endif + +End Sub + +MApplicationExtension.targetNT: +Function targetNT() As Boolean + + #if targetWin32 + Declare Sub GetVersionExA lib "Kernel32" ( info as Ptr ) + + dim info as new MemoryBlock( 148 ) + + info.Long( 0 ) = info.Size + GetVersionExA( info ) + + return info.Long( 4 ) >= 5 'Windows 2000/XP/2003 + + #endif + +End Function + +MApplicationExtension.hideApplication: +Function hideApplication(appName as string) As boolean + + #if targetMacOS + Dim ae as appleevent + Dim obj as AppleEventObjectSpecifier + + ae = NewAppleEvent( "core", "setd", "MACS" ) + + obj = GetNamedObjectDescriptor( "prcs", Nil, AppName.convertEncoding(Encodings.systemDefault) ) + obj = GetPropertyObjectDescriptor( obj, "pvis" ) + ae.ObjectSpecifierParam( "----" ) = obj + + ae.BooleanParam( "data" ) = false + + return ae.send + + #endif + +End Function + +MApplicationExtension.resizeAllListBoxes: +Sub resizeAllListBoxes() + + dim i, j as integer + dim w as Window + dim c as ListBox + + for i = windowCount - 1 downto 0 + + if window(i) isa CWindow then + w = window(i) + + for j = w.controlCount - 1 downto 0 + + if w.control(j) isa ListBox then + c = ListBox(w.control(j)) + + if c.hasHeading then + c.textFont = kAqStandardTextFont + c.textSize = kAqStandardTextSize + + else + c.textFont = kAqSidebarTextFont + c.textSize = kAqSidebarTextSize + + end + + end + + next + + end + + next + +End Sub + +MApplicationExtension.getDialog: +Function getDialog(primary as string, secondary as string, ok as string, cancel as string) As messageDialog + + dim m as new messageDialog + + m.icon = 0 + m.message = primary + m.explanation = secondary + + #if targetMachO or targetWin32 or targetLinux + m.actionButton.caption = ok + m.cancelButton.caption = cancel + + #elseif targetCarbon + m.actionButton.caption = ok.convertEncoding(Encodings.systemDefault) + m.cancelButton.caption = cancel.convertEncoding(Encodings.systemDefault) + + #endif + + m.cancelButton.visible = true + + return m + +End Function + +MApplicationExtension.getMenuHandle: +Function getMenuHandle(hWnd as integer) As integer + + #if targetWin32 + Declare Function GetMenu Lib "user32" (hWnd As integer) As integer + return GetMenu(hWnd) + + #endif + +End Function + +MApplicationExtension.getSubMenuHandle: +Function getSubMenuHandle(hMenu as integer, nPos as integer) As integer + + #if targetWin32 + Declare Function GetSubMenu Lib "user32" (hMenu As integer, nPos As integer) As integer + return GetSubMenu(hMenu, nPos) + + #endif + +End Function + +MApplicationExtension.localizeSubMenus: +Sub localizeSubMenus(hMenu as integer, m as menuItem) + + #if targetMachO + dim i, j as integer + + j = m.count - 1 + + for i = 0 to j + + if m.item(i).text <> "-" then + m.item(i).text = getLocalizedString(m.item(i).text, "MenuItem") + m.item(i).commandKey = getLocalizedString(m.item(i).commandKey, "MenuItem") + + if m.item(i).count <> 0 then localizeSubMenus 0, m.item(i) + + end + + next + + #elseif targetCarbon + dim i, j as integer + + j = m.count - 1 + + for i = 0 to j + + //* fix rb bug *// + + if m.item(i).text <> "-" then + if m.item(i).count = 0 then + m.item(i).text = getLocalizedString(m.item(i).text, "MenuItem") + m.item(i).commandKey = getLocalizedString(m.item(i).commandKey, "MenuItem") + + else + localizeSubMenus 0, m.item(i) + + end + + end + + next + + #elseif targetWin32 + Declare Function ModifyMenuA Lib "user32" (hMenu As integer, nPosition As integer, wFlags As integer, wIDNewItem As integer, lpString As ptr) As integer + Declare Function ModifyMenuW Lib "user32" (hMenu As integer, nPosition As integer, wFlags As integer, wIDNewItem As integer, lpString As ptr) As integer + + Const MF_BYPOSITION = &H400 + Const MF_POPUP = &H10 + Const MF_HELP = &H4000 + + dim lpString as new MemoryBlock(255) + dim i, j as integer + + //* fix rb bug *// + + j = m.count - 1 + + for i = 0 to j + + if m.item(i).text <> "-" then + + if m.item(i).count = 0 then + m.item(i).text = getLocalizedString(m.item(i).text, "MenuItem") + m.item(i).commandKey = getLocalizedString(m.item(i).commandKey, "MenuItem") + + else + if targetNT then + lpString.stringValue(0, 255) = getLocalizedString(m.item(i).text, "MenuItem").convertEncoding(Encodings.UTF16) + call ModifyMenuW(hMenu, i, MF_BYPOSITION, getSubMenuHandle(hMenu, i), lpString) + + else + lpString.CString(0) = getLocalizedString(m.item(i).text, "MenuItem").convertEncoding(Encodings.systemDefault) + call ModifyMenuA(hMenu, i, MF_BYPOSITION, getSubMenuHandle(hMenu, i), lpString) + + end + + localizeSubMenus getSubMenuHandle(hMenu, i), m.item(i) + + end + + end + + next + + #elseif targetLinux + 'todo + + #endif + +End Sub + +MApplicationExtension.drawMenuItems: +Sub drawMenuItems(hWnd as integer) + + #if targetWin32 + Declare Function DrawMenuBar Lib "user32" (hwnd As Integer) As Integer + call DrawMenuBar(hWnd) + + #endif + +End Sub + +MApplicationExtension.initializeColors: +Sub initializeColors() + + #if targetMacOS or targetLinux + kBackColor = &cFFFFFF + kTextColor = &c000000 + + #elseif targetWin32 + dim res as memoryblock + dim c as color + + Const COLOR_WINDOW = 5 + Const COLOR_WINDOWTEXT = 8 + + Declare Function GetSysColor Lib "user32" (nIndex As integer) As integer + res = newmemoryBlock(4) + + res.long(0) = GetSysColor(COLOR_WINDOW) + kBackColor = rgb(res.byte(0),res.byte(1),res.byte(2)) + res.long(0) = GetSysColor(COLOR_WINDOWTEXT) + kTextColor = rgb(res.byte(0),res.byte(1),res.byte(2)) + + #endif + + 'kRowColor = &cEBF5FF + kRowColor = rgb(bitwise.bitXor(kBackColor.red, &h14), _ + bitwise.bitXor(kBackColor.green, &h0A), _ + bitwise.bitXor(kBackColor.blue, &h00)) + + 'kGrayTextColor = &c808080 + kGrayTextColor = rgb(bitwise.bitXor(kTextColor.red, &h80), _ + bitwise.bitXor(kTextColor.green, &h80), _ + bitwise.bitXor(kTextColor.blue, &h80)) + + 'kLightGrayTextColor = &c949494 + kLightGrayTextColor = rgb(bitwise.bitXor(kTextColor.red, &h94), _ + bitwise.bitXor(kTextColor.green, &h94), _ + bitwise.bitXor(kTextColor.blue, &h94)) + + 'kLightRedTextColor = &cF03934 + kLightRedTextColor = rgb(bitwise.bitXor(kTextColor.red, &hF0), _ + bitwise.bitXor(kTextColor.green, &h39), _ + bitwise.bitXor(kTextColor.blue, &h34)) + +End Sub + +MApplicationExtension.setApplicationPriority: +Sub setApplicationPriority(processName as string, level as integer) + 'typedef struct tagPROCESSENTRY32 + '{ + 'DWORD 4 dwSize; + 'DWORD 4 cntUsage; + 'DWORD 4 th32ProcessID; // this process + 'ULONG_PTR 4 th32DefaultHeapID; + 'DWORD 4 th32ModuleID; // associated exe + 'DWORD 4 cntThreads; + 'DWORD 4 th32ParentProcessID; // this process's parent process + 'LONG 4 pcPriClassBase; // Base priority of process's threads + 'DWORD 4 dwFlags; + 'CHAR 260 szExeFile[MAX_PATH]; // Path + '} PROCESSENTRY32; + + #if TargetWin32 + Declare Function GetLastError Lib "Kernel32" () as Integer + + Declare Function CreateToolhelp32Snapshot Lib "Kernel32" (flags as Integer, id as Integer ) as Integer + Declare Sub CloseHandle Lib "Kernel32" ( handle as Integer ) + Declare Sub Process32First Lib "Kernel32" ( handle as Integer, entry as Ptr ) + Declare Function Process32Next Lib "Kernel32" ( handle as Integer, entry as Ptr ) as Boolean + + Declare Function OpenProcess Lib "Kernel32" ( access as Integer, inherit as Boolean, procID as Integer ) as Integer + Declare Sub SetPriorityClass Lib "Kernel32" ( handle as Integer, priority as Integer ) + + dim snapHandle as Integer + snapHandle = CreateToolhelp32Snapshot( 2, 0 ) + + dim mb as new MemoryBlock( 260 + 36 ) + dim file as String + + mb.Long( 0 ) = mb.Size + Process32First( snapHandle, mb ) + + dim err as Integer = GetLastError + dim pid as integer = -1 + + do + file = mb.CString( 36 ) + + if file = processName then + pid = mb.long( 8 ) + exit + end + + Call Process32Next( snapHandle, mb ) + loop until GetLastError() = 18 + + CloseHandle( snapHandle ) + if pid = -1 then return + + ' Get a handle to the current process + dim processHandle as Integer + const PROCESS_SET_INFORMATION = &h200 + processHandle = OpenProcess( PROCESS_SET_INFORMATION, false, pid ) + + ' And set the priority + SetPriorityClass( processHandle, level ) + + ' And close the handle to the module + CloseHandle( processHandle ) + + #endif + +End Sub + +MApplicationExtension.targetLeopard: +Function targetLeopard() As boolean + + #if targetMachO + dim ver as integer + if System.gestalt("sysv", ver) and ver >= &h1050 then return true + + #endif + +End Function + +MDataExtension.getTimeRemaining: +Function getTimeRemaining(Extends seconds as double) As String + + if seconds = 0 then return "" + + dim value as variant + + value = seconds / 86400 mod 24 + + if value = 1 then return getLocalizedString("1 day", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i days", "Misc", value) + + value = seconds / 3600 mod 60 + + if value = 1 then return getLocalizedString("1 hour", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i hours", "Misc", value) + + value = seconds / 60 mod 60 + + if value = 1 then return getLocalizedString("1 minute", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i minutes", "Misc", value) + + value = seconds mod 60 + + if value = 1 then return getLocalizedString("1 second", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i seconds", "Misc", value) + +End Function + +MDataExtension.getShortSize: +Function getShortSize(Extends bytes as double) As String + + if kAqKbFileSize then + return format(bytes, "#,#,#,#,#") + + else + if bytes < 1048576 then + return format(bytes / 1024, getLocalizedString("#.0\ \k\B", "Misc")) + + elseif bytes < 1073741824 then + return format(bytes / 1048576, getLocalizedString("#.0\ \M\B", "Misc")) + + else + return format(bytes / 1073741824, getLocalizedString("#.0\ \G\B", "Misc")) + + end + + end + +End Function + +MDataExtension.getUptime: +Function getUptime(millseconds as double) As String + + dim seconds as double = millseconds \ 60 + + if seconds = 0 then return "" + + dim value as variant + + value = seconds \ 86400 mod 24 + + if value = 1 then return getLocalizedString("1 day", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i days", "Misc", value) + + value = seconds \ 3600 mod 60 + + if value = 1 then return getLocalizedString("1 hour", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i hours", "Misc", value) + + value = seconds \ 60 mod 60 + + if value = 1 then return getLocalizedString("1 minute", "Misc") + if value <> 0 then return getLocalizedStringWithIntegerData("%i minutes", "Misc", value) + +End Function + +MDataExtension.getMediaType: +Function getMediaType(Extends extension as string) As integer + + dim position as integer = kExtensions.instrb(extension) + + //* File *// + if position = 0 then + return 5 + + //* Music *// + elseif position < 43 then + return 1 + + //* Picture *// + elseif position < 86 then + return 2 + + //* Movie *// + elseif position < 147 then + return 3 + + //* Text *// + else + return 4 + + end + +End Function + +MDataExtension.getQuality: +Function getQuality(Extends sources as variant) As string + + if sources > 19 then + return kFourStars + sources + + elseif sources > 6 then + return kThreeStars + sources + + elseif sources > 2 then + return kTwoStars + sources + + elseif sources = 2 then + return kOneStar + sources + + end + + +End Function + +MDataExtension.getKb: +Function getKb(Extends kbps as integer) As string + + //* kbps / 8 = kb/s + //* down 350kbps / 7 = up 50kbps + //* bandwidth limit 50% + + if kbps < 1048576 then + return format(kbps / 1024, getLocalizedString("#.0\ \k\B", "Misc")) + + elseif kbps < 1073741824 then + return format(kbps / 1048576, getLocalizedString("#.0\ \M\B", "Misc")) + + else + return format(kbps / 1073741824, getLocalizedString("#.0\ \G\B", "Misc")) + + end + +End Function + +MDataExtension.getKbps: +Function getKbps(Extends kbps as variant) As string + + if kbps <> 0 then return getLocalizedStringWithIntegerData("%i kbps", "Misc", kbps) + +End Function + +MDataExtension.getKbs: +Function getKbs(Extends bs as double) As string + + if bs <> 0 then return format(bs / 1024, getLocalizedString("#.0\ \k\B\/\s", "Misc")) + +End Function + +MDataExtension.getBoolAsString: +Function getBoolAsString(Extends b as boolean) As string + + if b then + return "1" + else + return "0" + end + +End Function + +MDataExtension.join: +Function join(Extends s() as string, separator as string = " ") As string + + return join(s, separator) + +End Function + +MDataExtension.stringValue: +Function stringValue(Extends value as double) As string + + //* Returns unsigned string value *// + + return format(value, "-#") + +End Function + +MDataExtension.removeExtension: +Function removeExtension(Extends fileName as string) As string + + dim s(-1) as string = fileName.split(".") + + if ubound(s) = -1 then return fileName + + dim position as integer = kExtensions.instrb(s(ubound(s)).lowercase) + + if position <> 0 then + s.remove ubound(s) + return s.join(".") + + else + return fileName + + end + +End Function + +MDataExtension.reverseEndian: +Function reverseEndian(Extends s as string) As string + + dim i, j, byte as integer + + j = s.lenb + + if j = 0 then return "" + + dim m as MemoryBlock = newMemoryBlock(j) + + m.stringValue(0,j) = s + j = j - 1 + + for i = 0 to j step 2 + + byte = m.Byte(i) + m.Byte(i) = m.Byte(i + 1) + m.Byte(i + 1) = byte + + next + + return m.StringValue(0, j + 1).defineEncoding(Encodings.UTF16) + +End Function + +MDataExtension.canNonLossyConversation: +Function canNonLossyConversation(Extends s as string, e as textEncoding) As boolean + + return s.lenb = s.convertEncoding(e).convertEncoding(Encoding(s)).lenb + +End Function + +MDataExtension.getExtension: +Function getExtension(Extends fileName as string) As string + + dim s(-1) as string = fileName.split(".") + + if ubound(s) < 1 then return "" + + dim i as integer = s(ubound(s)).lenb + + if i > 0 and i <= 12 then return s(ubound(s)).lowercase + +End Function + +MDataExtension.join: +Function join(Extends integers() as integer, separator as string) As string + + dim i as integer + dim results(-1) as string + + for i = ubound(integers) downto 0 + + results.append integers(i).stringValue + + next + + return results.join(separator) + +End Function + +MDataExtension.getLength: +Function getLength(Extends seconds as integer) As String + + if seconds = 0 then + return "" + + elseif seconds < 3600 then //minutes : seconds + return format(seconds \ 60, "#") + ":" + format(seconds mod 60, "00") + + else // hours : minutes : seconds + return format(seconds \ 3600, "#,###") + ":" + format(seconds mod 3600 \ 60, "00") + ":" + format(seconds mod 60, "00") + + end + +End Function + +MDataExtension.smartLeftB: +Function smartLeftB(Extends arg as string, length as integer) As string + + dim i as integer = arg.len + + while arg.left(i).lenb > length + + i = i - 1 + + wend + + return arg.left(i) + +End Function + +MDataExtension.equals: +Function equals(Extends args() as string, phase() as string) As Boolean + + if ubound(args) <> ubound(phase) then return false + + dim i as integer + + for i = ubound(args) downto 0 + + if strcomp(args(i), phase(i), 0) <> 0 then return false + + next + + return true + +End Function + +MDataExtension.nullStrcomp: +Function nullStrcomp(av as string, bv as string, option as integer) As integer + + if av.lenb = 0 or bv.lenb = 0 then + return strcomp(bv, av, option) + + else + return strcomp(av, bv, option) + + end + +End Function + +MDataExtension.completeMatches: +Function completeMatches(extends A as string, B() as string) As boolean + + dim i, j, matches as integer + + matches = -1 + j = ubound(B) + + for i = 0 to j + + if A.instrb(B(i)) <> 0 then matches = matches + 1 + + next + + return matches = j + +End Function + +MDataExtension.trim: +Function trim(extends A() as string) As String() + + dim i as integer + + for i = ubound(A) downto 0 + + A(i) = A(i).trim + + if A(i).lenb = 0 then A.remove i + + next + + return A + +End Function + +MDataExtension.stringSort: +Sub stringSort(Extends byref temp() as string) + + dim i as integer + dim temp2(-1) as string + + for i = ubound(temp) downto 0 + + if temp(i).lenb = 0 then + temp2.append temp(i) + temp.remove i + + end + + next + + temp.sort + + for i = ubound(temp2) downto 0 + + temp.append temp2(i) + + next + +End Sub + +MDataExtension.matches: +Function matches(extends A as string, B() as string) As boolean + + dim i, j as integer + + j = ubound(B) + + for i = 0 to j + + if A.instrb(B(i)) <> 0 then return true + + next + + return false + +End Function + +MDataExtension.top: +Function top(Extends theArray() as string) As string + if ubound(theArray) >= 0 then return theArray(0) +End Function + +MDataExtension.convertPSString: +Function convertPSString(extends s as string) As string + + dim i, bytes as integer + dim phase, result as string + + while i <= s.lenb + + phase = s.midb(i, 1) + + if phase.ascb = 92 then + phase = s.midb(i + 1, 1) + + if isNumeric(phase) then + bytes = val("&o" + s.midB(i + 1, 3)) + result = result + chrb(bytes) + i = i + 4 + + else + result = result + phase + i = i + 2 + + end + + else + result = result + phase + i = i + 1 + + end + + wend + + return result + +End Function + +MDefautsController.initializeDefaults: +Sub initializeDefaults() + + CDefaultsController1 = new CDefaultsController + +End Sub + +MDefautsController.defaultsWrite: +Sub defaultsWrite(key as string, value as variant) + + CDefaultsController1.Write(key, value) + +End Sub + +MDefautsController.finalizeDefaults: +Sub finalizeDefaults() + + CDefaultsController1 = nil + +End Sub + +MDefautsController.defaultsReadArrayString: +Function defaultsReadArrayString(key as string, values() as string) As String() + + return CDefaultsController1.ReadArrayString(key, values) + +End Function + +MDefautsController.defaultsRead: +Function defaultsRead(key as string, value as variant) As variant + + return CDefaultsController1.Read(key, value) + +End Function + +MDefautsController.defaultsWriteArrayString: +Sub defaultsWriteArrayString(key as string, values() as string) + + CDefaultsController1.WriteArrayString(key, values) + +End Sub + +MDefautsController.defaultsReadArrayInteger: +Function defaultsReadArrayInteger(key as string, values() as integer) As Integer() + + return CDefaultsController1.ReadArrayInteger(key, values) + +End Function + +MDefautsController.defaultsReadArrayBoolean: +Function defaultsReadArrayBoolean(key as string, values() as boolean) As Boolean() + + return CDefaultsController1.ReadArrayBoolean(key, values) + +End Function + +MDefautsController.defaultsWriteArrayInteger: +Sub defaultsWriteArrayInteger(key as string, values() as integer) + + CDefaultsController1.WriteArrayInteger(key, values) + +End Sub + +MDefautsController.defaultsWriteArrayBoolean: +Sub defaultsWriteArrayBoolean(key as string, values() as boolean) + + CDefaultsController1.WriteArrayBoolean(key, values) + +End Sub + +MFolderItemExtension.revealInFinder: +Sub revealInFinder(Extends f as folderitem) + + #if targetMacOS + dim a as AppleEvent = NewAppleEvent("misc", "mvis", "MACS") + + a.FolderItemParam("----") = f + + if a.send = false then return + + a = NewAppleEvent("misc", "actv", "MACS") + call a.send + + #elseif targetWin32 + + dim l as new Shell + + if targetNT then + l.execute "explorer /select, """ + f.posixPath + """" + + else + l.execute convertEncoding("explorer /select, """ + f.posixPath + """", Encodings.systemDefault) + + end + + #elseif targetLinux + f.parent.launch + + #endif + +End Sub + +MFolderItemExtension.openWith: +Sub openWith(Extends document as folderItem, application as folderItem) + + #if targetMacOS + dim ae as AppleEvent + dim obj As AppleEventObjectSpecifier + + ae = NewAppleEvent("aevt", "odoc", "MACS") + obj = GetNamedObjectDescriptor("file", nil, document.absolutePath) + ae.ObjectSpecifierParam("----") = obj + obj = GetNamedObjectDescriptor("appf", nil, application.absolutePath) + ae.ObjectSpecifierParam("usin") = obj + call ae.send + + #elseif targetWin32 + dim l as new Shell + + if targetNT then + l.execute """" + application.posixPath + """ """ + document.posixPath + """" + + else + l.execute convertEncoding("""" + application.posixPath + """ """ + document.posixPath + """", Encodings.systemDefault) + + end + + #elseif targetLinux + dim l as new Shell + + l.execute """" + application.posixPath + """ """ + document.posixPath + """" + + #endif + +End Sub + +MFolderItemExtension.openAsMaskedPicture: +Function openAsMaskedPicture(Extends f as folderItem) As picture + + dim p as Picture = f.openAsPicture + dim result as new Picture(p.width, p.height, 32) + + result.graphics.drawPicture p, 0, 0 + result.mask.graphics.drawPicture f.parent.child("Mask").child(f.name).openAsPicture, 0, 0 + + return result + +End Function + +MFolderItemExtension.posixPath: +Function posixPath(Extends f as folderItem) As string + + #if targetMachO + if f <> nil then _ + return f.shellPath.convertPSString.defineEncoding(Encodings.UTF8) + + #elseif targetCarbon + dim s(0) as string + + while f <> nil + s.insert 1, f.name + f = f.parent + + wend + + return s.join("/") + + #elseif targetWin32 + if f <> nil then + if targetNT then + if f.absolutePath.encoding = Encodings.UTF8 then + return f.absolutePath.replaceall("¥", "\") + else + return f.absolutePath.convertEncoding(Encodings.UTF8).replaceall("¥", "\") + + end + + else + return f.shellPath.convertEncoding(Encodings.UTF8).replaceall("¥", "\") + + end + + end + + #elseif targetLinux + if f <> nil then _ + return f.shellPath.convertEncoding(Encodings.UTF8) + + #endif + +End Function + +MFolderItemExtension.getPath2FolderItem: +Function getPath2FolderItem(s as string) As folderItem + + if s.lenb = 0 then return nil + + #if targetMachO or targetLinux + try + return getFolderItem(s, FolderItem.pathTypeShell) + + catch + + end + + #elseif targetCarbon + dim f, f2 as folderItem + + s = s.midb(2).replaceAllb("/", ":") + + try + f = getFolderItem(s, FolderItem.pathTypeAbsolute) + + if f <> nil and f.exists then return f + + //* fix rb bug *// + + f2 = getFolderItem(s.convertEncoding(Encodings.systemDefault), FolderItem.pathTypeAbsolute) + + if f2 <> nil and f2.exists then return f2 + + return f + + catch + + end + + #elseif targetWin32 + try + if targetNT then + return getFolderItem(s, FolderItem.pathTypeAbsolute) + + else + return getFolderItem(s, FolderItem.pathTypeShell) + + end + + catch + + end + + #endif + +End Function + +MFolderItemExtension.fixRbBug: +Function fixRbBug(Extends f as folderItem) As folderitem + + #if targetWin32 + if f = nil or f.exists then return f + + dim f2 as folderItem + + f2 = getFolderItem( f.absolutePath.defineEncoding(Encodings.systemDefault).convertEncoding(Encodings.UTF8).replaceall("¥", "\"), FolderItem.pathTypeAbsolute ) + + if f2 <> nil and f2.exists then return f2 + + return f + + #elseif targetLinux + if f = nil or f.lastErrorCode <> 0 then return nil + + return f + + #endif + +End Function + +MFolderItemExtension.open: +Sub open(Extends path as string) + + if path.lenB = 0 then return + + dim fi as folderItem = getPath2FolderItem(path) + + if fi <> nil and fi.exists then fi.launch + +End Sub + +MFolderItemExtension.revealInFinder: +Sub revealInFinder(Extends path as string) + + if path.lenB = 0 then return + + dim fi as folderItem = getPath2FolderItem(path) + + if fi <> nil then + if fi.exists then + fi.revealInFinder + + elseif fi.parent.exists and fi.parent.directory then + fi.parent.launch + + end + + end + +End Sub + +MiTunesController.isiTunesAudio: +Function isiTunesAudio(Extends fileName as string) As boolean + + dim extension as string = fileName.getExtension + + return kITunesAudioExtensions.instrb(extension) <> 0 + +End Function + +MLocalizationController.initializeLocalization: +Sub initializeLocalization() + + CLocalizationController1 = new CLocalizationController + +End Sub + +MLocalizationController.getLocalizedString: +Function getLocalizedString(key as string, table as string) As string + + return CLocalizationController1.getLocalizedStringFromTable(key, table) + +End Function + +MLocalizationController.finalizeLocalization: +Sub finalizeLocalization() + + CLocalizationController1 = nil + +End Sub + +MLocalizationController.getLocalizedStringWithStringData: +Function getLocalizedStringWithStringData(key as string, table as string, replaced as string) As string + + return CLocalizationController1.getLocalizedStringFromTable(key, table).replaceb("%@", replaced) + +End Function + +MLocalizationController.getLocalizedStringWithIntegerData: +Function getLocalizedStringWithIntegerData(key as string, table as string, replaced as string) As string + + return CLocalizationController1.getLocalizedStringFromTable(key, table).replaceb("%i", replaced) + +End Function + +MPreferencesController.initializePreferences: +Sub initializePreferences() + + CPreferencesController1 = new CPreferencesController + +End Sub + +MPreferencesController.finalizePreferences: +Sub finalizePreferences() + + CPreferencesController1 = nil + +End Sub + +MResourcesController.initializeResources: +Sub initializeResources() + + CResourceController1 = new CResourceController + +End Sub + +MResourcesController.getLargeMediaPicture: +Function getLargeMediaPicture(type as integer, extension as string) As picture + + return CResourceController1.getLargeMediaPicture(type, extension) + +End Function + +MResourcesController.getMaskedPicture: +Function getMaskedPicture(pictureName as string) As picture + + return CResourceController1.getMaskedPicture(pictureName) + +End Function + +MResourcesController.getControlPicture: +Function getControlPicture(type as integer) As picture + + return CResourceController1.getControlPicture(type) + +End Function + +MResourcesController.getChasingArrows: +Function getChasingArrows(type as integer) As picture + + return CResourceController1.getChasingArrows(type) + +End Function + +MResourcesController.getSmallMediaPicture: +Function getSmallMediaPicture(c as CResponseModel) As picture + + return CResourceController1.getSmallMediaPicture(c) + +End Function + +MResourcesController.finalizeResources: +Sub finalizeResources() + + CResourceController1 = nil + +End Sub + +CEditField.Localize: +Protected Sub Localize() + + me.helpTag = getLocalizedString(me.helpTag, "EditField") + +End Sub + +CEditField.LostFocus: +Sub LostFocus() + + if me.text.lenb = 0 then + me.textColor = kGrayTextColor + me.text = me.helpTag + + end + +End Sub + +CEditField.GotFocus: +Sub GotFocus() + + if me.textColor = kGrayTextColor then + me.textColor = kTextColor + me.text = "" + + end + +End Sub + +CEditField.KeyDown: +Function KeyDown(Key As String) As Boolean + + #if targetMacOS + dim i as integer + if ascb(key) = 8 then + i = me.selStart + me.text = me.text.left(me.selStart - 1) + me.text.right(me.text.len - me.selStart) + me.selStart = i - 1 + return true + end + #endif + + return KeyDown(Key) + +End Function + +CEditField.Open: +Sub Open() + + me.backColor = kBackColor + me.textColor = kTextColor + Localize + Open + +End Sub + +CHierarchicalListBox.addRow: +Sub addRow(rowName as string, defaults as string, value as variant) + + me.addrow rowName + + dim index as integer = me.lastIndex + + select case value.Type + + case 2 //* integer *// + me.cellType(index, 1) = ListBox.TypeEditable + me.cell(index, 1) = value + + case 8 //* string *// + me.cellType(index, 1) = ListBox.TypeEditable + me.cell(index, 1) = value + + case 9 //* object *// + if value isa Dictionary and Dictionary(value).hasKey("currentKey") then _ + me.cell(index, 1) = Dictionary(value).value(Dictionary(value).value("currentKey")) + + case 11 //* boolean *// + me.cellType(index, 0) = ListBox.TypeCheckbox + me.cellCheck(index, 0) = value + + end + + me.cellTag(index, 0) = defaults + me.cellTag(index, 1) = value + +End Sub + +CHierarchicalListBox.valueChanged: +Sub valueChanged(row as integer, column as integer) + + CellAction(row, column) + +End Sub + +CHierarchicalListBox.addIndentRow: +Sub addIndentRow(rowName as string, defaults as string, value as variant) + + me.addRow rowName, defaults, value + me.cellAlignmentOffset(me.lastIndex, 0) = 20 + +End Sub + +CHierarchicalListBox.addRow: +Sub addRow(rowName as string, defaults as string, value1 as boolean, value2 as variant) + + me.addrow rowName + + dim index as integer = me.lastIndex + + me.cellType(index, 0) = 2 + me.cellCheck(index, 0) = value1 + + select case value2.Type + + case 2 //* integer *// + me.cellType(index, 1) = 3 + me.cell(index, 1) = value2 + + case 8 //* string *// + me.cellType(index, 1) = 3 + me.cell(index, 1) = value2 + + case 9 //* object *// + if value2 isa Dictionary and Dictionary(value2).hasKey("currentKey") then _ + me.cell(index, 1) = Dictionary(value2).value(Dictionary(value2).value("currentKey")) + + end + + me.cellTag(index, 0) = defaults + me.cellTag(index, 1) = value2 + +End Sub + +CHierarchicalListBox.collapseAll: +Sub collapseAll() + + dim i as integer + + for i = me.listCount - 1 downto 0 + if me.expanded(i) then me.expanded(i) = false + next + +End Sub + +CHierarchicalListBox.MouseMove: +Sub MouseMove(row as integer, column as integer, x as integer, y as integer) + + try + if row = -1 or column = -1 then + me.mouseCursor = arrowCursor + + elseif me.cellTag(row, column) isa Dictionary then + me.mouseCursor = handCursor + + elseif me.cellType(row, column) = ListBox.TypeEditable then + me.mouseCursor = IBeamCursor + + else + me.mouseCursor = arrowCursor + + end + + catch + me.mouseCursor = arrowCursor + + end + +End Sub + +CHierarchicalListBox.CellTextPaint: +Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean + + #if targetMachO + if g.width <= me.cellAlignmentOffset(row, column) then + return false + else + 'g.drawStringInCell me.cell(row, column), x, y) + g.drawString me.cell(row, column), x, y + return true + end + + #endif + +End Function + +CHierarchicalListBox.DoubleClick: +Sub DoubleClick() + + if me.listIndex <> -1 then _ + me.expanded(me.listIndex) = not me.expanded(me.listIndex) + +End Sub + +CHierarchicalListBox.CellAction: +Sub CellAction(row As Integer, column As Integer) + + CellAction(row, column) + +End Sub + +CHierarchicalListBox.CollapseRow: +Sub CollapseRow(row As Integer) + + me.scrollposition = 0 + +End Sub + +CHierarchicalListBox.CellBackgroundPaint: +Function CellBackgroundPaint(g As Graphics, row As Integer, column As Integer) As Boolean + + #if targetMachO + if me.selected(row) = false and (row mod 2) = 0 then + g.foreColor = kRowColor + g.fillRect 0, 0, g.width, g.height + return true + end + + #elseif targetWin32 or targetLinux + if (row mod 2) = 0 then + g.foreColor = kRowColor + g.fillRect 0, 0, g.width, g.height + return true + end + + #endif + +End Function + +CListBox.Localize: +Protected Sub Localize() + + if me.hasHeading = false then return + + dim i as integer + + for i = me.columnCount - 1 downto 0 + + me.heading(i) = getLocalizedString(me.heading(i), "ListBox") + + next + +End Sub + +CListBox.getInitialColumnWidths: +Function getInitialColumnWidths() As string + + return me.initialColumnWidths + +End Function + +CListBox.setColumnWidths: +Sub setColumnWidths(value as string) + + if value.countFields(",") = me.columnCount then me.columnWidths = value + + dim i as integer + + for i = me.columnCount - 1 downto 0 + + if isNumeric(me.column(i).widthExpression) then + me.column(i).userResizable = false + me.column(i).minWidthExpression = me.column(i).widthExpression + me.column(i).maxWidthExpression = me.column(i).widthExpression + + else + me.column(i).userResizable = (me.column(i).widthExpression <> "0%") + me.column(i).minWidthExpression = "0%" + me.column(i).maxWidthExpression = "100%" + + end + + next + +End Sub + +CListBox.getCellText: +Protected Function getCellText(row as integer, column as integer) As string + + return me.Cell(row, column) + +End Function + +CListBox.selectAll: +Sub selectAll() + + dim i as integer + + try + for i = me.listCount - 1 downto 0 + me.selected(i) = true + next + + catch + + end + +End Sub + +CListBox.setHelpTag: +Protected Sub setHelpTag(x as integer, y as integer, byref theRow as integer, byref theColumn as integer) + + dim i, j, theRowHeight, theColumnWidth as integer + + try + if x < 0 or x > me.width or y < 0 or y > me.height then + if me.HelpTag.lenb <> 0 then me.HelpTag = "" + return + end + + theRow = -1 + theColumn = -1 + + if me.hasHeading then + theRowHeight = kHeadingHeight + else + theRowHeight = 0 + end + + j = me.listCount - 1 + + for i = 0 to j + + if theRowHeight < y and theRowHeight + me.defaultRowHeight > y then + theRow = me.scrollPosition + i + exit + else + theRowHeight = theRowHeight + me.defaultRowHeight + end + + next + + j = me.columnCount - 1 + + for i = 0 to j + + if theColumnWidth < x and theColumnWidth + me.column(i).widthActual > x then + theColumn = i + exit + else + theColumnWidth = theColumnWidth + me.column(i).widthActual + end + + next + + if theRow > -1 and theRow < me.listCount and _ + theColumn > -1 and theColumn < me.columnCount then + + if me.HelpTag <> me.getCellText(theRow, theColumn) then _ + me.HelpTag = me.getCellText(theRow, theColumn) + + return + + else + if me.HelpTag.lenb <> 0 then me.HelpTag = "" + return + + end + + catch + + end + +End Sub + +CListBox.MouseMove: +Sub MouseMove(X As Integer, Y As Integer) + + dim theRow, theColumn as integer + + setHelpTag x, y, theRow, theColumn + MouseMove theRow, theColumn, x, y + +End Sub + +CListBox.MouseExit: +Sub MouseExit() + + MouseExit + + if me.HelpTag.lenb <> 0 then me.HelpTag = "" + +End Sub + +CListBox.EnableMenuItems: +Sub EnableMenuItems() + + EditSelectAll.enabled = (me.selectionType <> 0) + EditCopy.enabled = (me.helpTag.lenb <> 0) + +End Sub + +CListBox.MouseDown: +Function MouseDown(x As Integer, y As Integer) As Boolean + + dim theRow, theColumn as integer + + setHelpTag x, y, theRow, theColumn + + if isCMMClick = false then return false + + if me.hasHeading and y < 18 then + HeaderCMMClicked + return true + + else + try + if me.selectionType = 1 and me.selected(theRow) = false then + if Keyboard.asyncControlKey then + me.selected(theRow) = true + else + me.listIndex = theRow + end + end + catch + end + + CMMClicked + return true + + end + +End Function + +CListBox.Open: +Sub Open() + + me.initialColumnWidths = me.columnWidths + Localize + Open + +End Sub + +CNetworkListBox.getCellText: +Protected Function getCellText(row as integer, column as integer) As string + + dim c as CNetworkModel = CNetworkModel(me.dataSource(row)) + + if column = 0 then + return c.address + + elseif column = 1 then + return c.agent + + elseif column = 2 then + return c.language + + elseif column = 3 then + return c.type + + elseif column = 4 then + return c.getPTime + + else + return "" + + end + +End Function + +CNetworkListBox.CellTextPaint: +Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean + + dim c as CNetworkModel + + try + c = CNetworkModel(me.dataSource(row)) + + if column = 0 then + 'g.drawStringInCell c.address, x, y + g.drawString c.address, x, y + return true + + elseif column = 1 then + 'g.drawStringInCell c.agent, x, y + g.drawString c.agent, x, y + return true + + elseif column = 2 then + g.drawString c.language, (g.width - g.stringWidth(c.language)) / 2, y + return true + + elseif column = 3 then + g.drawString c.type, (g.width - g.stringWidth(c.type)) / 2, y + return true + + elseif column = 4 then + g.drawString c.getPTime, (g.width - g.stringWidth(c.getPTime)) / 2, y + return true + + end + + catch + + end + +End Function + +CNetworkListBox.CellBackgroundPaint: +Function CellBackgroundPaint(g As Graphics, row As Integer, column As Integer) As Boolean + + if me.selected(row) = false and (row mod 2) = 0 then + g.foreColor = kRowColor + g.fillRect 0, 0, g.width, g.height + + end + + return true + +End Function + +CResponseListBox.getCellText: +Protected Function getCellText(row as integer, column as integer) As string + + dim c as CResponseModel = CResponseModel(me.dataSource(row)) + + if column = 0 then + return "" + + elseif column = 1 then + return c.displayName' + EndOfLine + c.getRepresentation + + elseif column = 2 then + return c.artist + + elseif column = 3 then + return c.album + + elseif column = 4 then + return c.getPSize + + elseif column = 5 then + return c.getPBitrate + + elseif column = 6 then + return c.getPLength + + elseif column = 7 then + return c.address.join(EndOfLine) + + elseif column = 8 then + return c.getPSpeed + + else + return "" + + end + +End Function + +CResponseListBox.CellTextPaint: +Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean + + dim c as CResponseModel + + try + c = CResponseModel(me.dataSource(row)) + + //* gray out existing or red out spam *// + + if (c.exists and me.selected(row) = false) then + g.foreColor = kLightGrayTextColor + + elseif (c.spam and me.selected(row) = false) then + g.foreColor = kLightRedTextColor + + end + + if column = 0 then + return true + + elseif column = 1 then + 'g.drawStringInCell c.displayName, x, y + g.drawString c.displayName, x, y + return true + + elseif column = 2 then + 'g.drawStringInCell c.artist, x, y + g.drawString c.artist, x, y + return true + + elseif column = 3 then + 'g.drawStringInCell c.album, x, y + g.drawString c.album, x, y + return true + + elseif column = 4 then + if kAqKbFileSize = false then + g.drawString c.getPSize, (g.width - g.stringWidth(c.getPSize)) / 2, y + else + g.drawString c.getPSize, (g.width - g.stringWidth(c.getPSize)), y + end + + return true + + elseif column = 5 then + g.drawString c.getPBitrate, (g.width - g.stringWidth(c.getPBitrate)) / 2, y + return true + + elseif column = 6 then + g.drawString c.getPLength, (g.width - g.stringWidth(c.getPLength)) / 2, y + return true + + elseif column = 7 then + g.drawString c.getPSources, (g.width - g.stringWidth(c.getPSources)) / 2, y + return true + + elseif column = 8 then + g.drawString c.getPSpeed, (g.width - g.stringWidth(c.getPSpeed)) / 2, y + return true + + else + return true + + end + + catch + + end + +End Function + +CResponseListBox.CellBackgroundPaint: +Function CellBackgroundPaint(g As Graphics, row As Integer, column As Integer) As Boolean + + if me.selected(row) = false and (row mod 2) = 0 then + g.foreColor = kRowColor + g.fillRect 0, 0, g.width, g.height + + end + + try + if column = 0 then _ + g.drawPicture CResponseModel(me.dataSource(row)).getPIcon, 1, 1 + + catch + + end + + return true + +End Function + +CSidebarListBox.getCellText: +Protected Function getCellText(row as integer, column as integer) As string + + dim c as CSidebarModel = CSidebarModel(me.dataSource(row)) + + return c.caption + +End Function + +CSidebarListBox.CellTextPaint: +Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean + + dim c as CSidebarModel + dim i as integer + + try + c = CSidebarModel(me.dataSource(row)) + + g.drawString c.caption, 18, y + + if c.getPState <> nil then + g.bold = true + i = g.stringWidth(c.getPState) + x = g.width - i - 12 + + if c.highlighted = false then + g.foreColor = &cFFFFFF + g.fillRoundRect x, 4, i + 8, y, 8, 8 + g.foreColor = &cE2E2E2 + g.drawString c.getPState, x + 4, y + 1 + g.foreColor = &c383838 + g.drawString c.getPState, x + 4, y + + else + g.foreColor = &c909090 + g.fillRoundRect x, 4, i + 8, y, 8, 8 + g.foreColor = &c3F3F3F + g.drawString c.getPState, x + 4, y + 1 + g.foreColor = &cFFFFFF + g.drawString c.getPState, x + 4, y + + end + + end + + if c.interval > -1 then + if me.selected(row) = false then + g.drawPicture getChasingArrows(c.interval mod 6), 1, 4 + + else + g.drawPicture getChasingArrows(6 + (c.interval mod 6)), 1, 4 + + end + + return true + + elseif c.index < 0 then + if me.selected(row) = false then + g.drawPicture getControlPicture(1), 1, 4 + + else + g.drawPicture getControlPicture(5), 1, 4 + + end + + return true + + else + if row = 0 then + g.drawPicture getControlPicture(2), 0, 3 + + elseif row = 1 then + g.drawPicture getControlPicture(3), 0, 3 + + elseif row = 2 then + g.drawPicture getControlPicture(4), 0, 3 + + end + + return true + + end + + catch + + end + +End Function + +CStaticText.Localize: +Protected Sub Localize() + + me.text = getLocalizedString(me.text, "StaticText") + 'me.helpTag = getLocalizedString(me.helpTag, "StaticText") + +End Sub + +CStaticText.Open: +Sub Open() + + Localize + Open + +End Sub + +CStatsListBox.dataSourceChanged: +Sub dataSourceChanged(c() as CStatsModel) + + me.dataSource = c + + me.setRowCount ubound(c) + 1 + me.invalidateAllCells + +End Sub + +CStatsListBox.invalidateAllCells: +Protected Sub invalidateAllCells() + + dim i, j as integer + dim startPosition as integer = me.scrollPosition + dim displayRows as integer = (me.height \ me.defaultRowHeight) + displayRows = min(me.listCount - 1, startPosition + displayRows) + + try + + for i = displayRows downto startPosition + + for j = me.columnCount - 1 downto 0 + + me.cell(i, j) = "" + + next + + next + + catch + + end + +End Sub + +CStatsListBox.saveSelectedItems: +Sub saveSelectedItems() + + dim i as integer + + try + for i = ubound(me.dataSource) downto 0 + + if me.selected(i) then selectedItems.value(me.dataSource(i).getRepresentation) = true + + next + + catch + + end + +End Sub + +CStatsListBox.Constructor: +Sub Constructor() + + me.selectedItems = new Dictionary + +End Sub + +CStatsListBox.getSelectedRows: +Function getSelectedRows() As integer() + + dim i, j, results(-1) as integer + + try + j = me.listCount - 1 + + for i = 0 to j + + if me.selected(i) then results.append i + + next + + catch + + end + + return results + +End Function + +CStatsListBox.addOrRemoveScrollbar: +Sub addOrRemoveScrollbar() + + dim count as integer = me.listCount - 1 + dim displayRows as integer = (me.height \ me.defaultRowHeight) + dim needsScrollbar as boolean = (displayRows <= count) + + if me.scrollBarVertical <> needsScrollbar then + me.scrollBarVertical = needsScrollbar + + if me.scrollPosition > count - displayRows then _ + me.scrollPosition = count - displayRows + + end + +End Sub + +CStatsListBox.setRowCount: +Protected Sub setRowCount(rowCount as integer) + + while me.listCount > rowCount + + me.removeRow me.listCount - 1 + + Wend + + dim i as integer + + while me.listCount < rowCount + + me.addrow "" + + for i = me.columnCount - 1 downto 0 + + me.cell(me.lastIndex, i) = "" + + next + + Wend + +End Sub + +CStatsListBox.restoreSelectedItems: +Sub restoreSelectedItems() + + dim i as integer + + try + for i = me.listCount - 1 downto 0 + + if me.selected(i) <> me.selectedItems.hasKey(me.dataSource(i).getRepresentation) then _ + me.selected(i) = not me.selected(i) + + next + + catch + + end + + me.selectedItems.clear + +End Sub + +CStatsListBox.getSelectedItems: +Function getSelectedItems() As Dictionary + + return me.selectedItems + +End Function + +CToolbar.appendMenu: +Sub appendMenu(caption as string, helpTag as string) + + me.graphics.textFont = kTextFont + me.graphics.textSize = kSmallTextSize + me.graphics.bold = true + + me.CToolbarModels.append new CToolbarModel(caption, helpTag, me.graphics.stringWidth(caption) + 16) + +End Sub + +CToolbar.clearMenu: +Sub clearMenu() + + redim me.CToolbarModels(-1) + +End Sub + +CToolbar.setKeepPressed: +Sub setKeepPressed(value as boolean) + + dim c as CToolbarModel + + try + c = me.CToolbarModels(ubound(me.CToolbarModels)) + if c.caption = getLocalizedString("Filter", "Toolbar") then + c.keepPressed = value + me.refresh + + end + + catch + + end +End Sub + +CToolbar.MouseExit: +Sub MouseExit() + + dim c as CToolbarModel + dim changed as boolean + + try + for each c in me.CToolbarModels + + if c.entered then + c.entered = false + changed = true + + end + + next + + if me.HelpTag.lenb <> 0 then me.HelpTag = "" + + if changed then me.refresh + + catch + + end + +End Sub + +CToolbar.MouseMove: +Sub MouseMove(X As Integer, Y As Integer) + + dim x2 as integer = me.width + dim c as CToolbarModel + dim changed as boolean + + try + for each c in me.CToolbarModels + + x2 = x2 - c.width + + if c.entered <> (x > x2 and x < x2 + c.width and y > 0 and y < 16) then + c.entered = not c.entered + changed = true + + if c.entered and me.helpTag <> c.helpTag then me.helpTag = c.helpTag + + end + + next + + if changed then me.refresh + + catch + + end + +End Sub + +CToolbar.MouseDrag: +Sub MouseDrag(X As Integer, Y As Integer) + + dim x2 as integer = me.width + dim c as CToolbarModel + + try + for each c in me.CToolbarModels + + x2 = x2 - c.width + + if c.pressed and c.entered <> (x > x2 and x < x2 + c.width and y > 0 and y < 16) then + c.entered = not c.entered + me.refresh + return + + end + + next + + catch + + end + +End Sub + +CToolbar.MouseUp: +Sub MouseUp(X As Integer, Y As Integer) + + dim c as CToolbarModel + + try + for each c in me.CToolbarModels + + if c.pressed then + c.pressed = false + me.refresh + + if c.entered and c.caption = getLocalizedString("Filter", "Toolbar") then _ + c.keepPressed = not c.KeepPressed + + if c.entered and c.caption <> getLocalizedString("Browse", "Toolbar") then _ + Action c.caption + + return + + end + + next + + catch + + end + +End Sub + +CToolbar.MouseDown: +Function MouseDown(X As Integer, Y As Integer) As Boolean + + dim c as CToolbarModel + + try + for each c in me.CToolbarModels + + if c.entered then + c.pressed = true + me.refresh + + if c.caption = getLocalizedString("Browse", "Toolbar") then _ + Action c.caption + + return true + + end + + next + + catch + + end + +End Function + +CToolbar.Paint: +Sub Paint(g As Graphics) + + dim x as integer = g.width + dim c as CToolbarModel + + g.textFont = kTextFont + g.textSize = kSmallTextSize + g.Bold = true + + try + for each c in me.CToolbarModels + + x = x - c.width + + if x < 0 then return + if c.pressed and c.entered then + g.foreColor = &c707070 + g.fillRoundRect x, 0, c.width, 16, 16, 16 + g.foreColor = &c3F3F3F + g.drawString c.caption, x + 8, 13 + g.foreColor = &cFFFFFF + g.drawString c.caption, x + 8, 12 + + elseif c.keepPressed then + g.foreColor = &c636363 + g.fillRoundRect x, 0, c.width, 16, 16, 16 + g.foreColor = &c3F3F3F + g.drawString c.caption, x + 8, 13 + g.foreColor = &cFFFFFF + g.drawString c.caption, x + 8, 12 + + elseif c.entered then + g.foreColor = &c808080 + g.fillRoundRect x, 0, c.width, 16, 16, 16 + g.foreColor = &c3F3F3F + g.drawString c.caption, x + 8, 13 + g.foreColor = &cFFFFFF + g.drawString c.caption, x + 8, 12 + + else + g.foreColor = &cE2E2E2 + g.drawString c.caption, x + 8, 13 + g.foreColor = &c383838 + g.drawString c.caption, x + 8, 12 + + end + + next + + catch + + end + +End Sub + +CTransferListBox.getCellText: +Protected Function getCellText(row as integer, column as integer) As string + + dim c as CTransferModel = CTransferModel(me.dataSource(row)) + + if column = 0 then + return "" + + elseif column = 1 then + return c.getPName + + elseif column = 2 then + return c.getSTransfer + + elseif column = 3 then + return "" + + elseif column = 4 then + return c.getPTime + + else + return "" + + end + +End Function + +CTransferListBox.CellBackgroundPaint: +Function CellBackgroundPaint(g As Graphics, row As Integer, column As Integer) As Boolean + + if me.selected(row) = false and (row mod 2) = 0 then + g.foreColor = kRowColor + g.fillRect 0, 0, g.width, g.height + + end + + try + if column = 0 then _ + g.drawPicture CTransferModel(me.dataSource(row)).getPIcon, 2, 2 + + catch + + end + + return true + +End Function + +CTransferListBox.CellTextPaint: +Function CellTextPaint(g As Graphics, row As Integer, column As Integer, x as Integer, y as Integer) As Boolean + + dim c as CTransferModel + dim p as picture + + try + c = CTransferModel(me.dataSource(row)) + + if column = 0 then + return true + + elseif column = 1 then + g.textSize = kMiddleTextSize + 'g.drawStringInCell c.getPName, x, y - 7 + g.drawString c.getPName, x, y - 7 + + if me.selected(row) = false then g.foreColor = kGrayTextColor + + g.textSize = kSmallTextSize + 'g.drawStringInCell c.getSName, x, y + 7 + g.drawString c.getSName, x, y + 7 + return true + + elseif column = 2 then + g.textSize = kMiddleTextSize + g.drawString c.getPTransfer, (g.width - g.stringWidth(c.getPTransfer)) / 2, y - 7 + + if me.selected(row) = false then g.foreColor = kGrayTextColor + + g.textSize = kSmallTextSize + g.drawString c.getSTransfer, (g.width - g.stringWidth(c.getSTransfer)) / 2, y + 7 + return true + + elseif column = 3 then + p = new Picture(g.width, g.height, 32) + + x = g.width - 12 + p.mask.graphics.foreColor = &cFFFFFF + p.mask.graphics.fillRect 0, 0, g.width, g.height + p.mask.graphics.foreColor = &c000000 + p.mask.graphics.fillRoundRect 6, 12, x, 12, 12, 12 + + if c.isActive then + p.graphics.foreColor = &cAAAAAA + p.graphics.fillRect 6, 12, x * c.progress, 12 + p.graphics.foreColor = &c808080 + p.graphics.drawRoundRect 6, 12, x, 12, 12, 12 + + else + p.graphics.foreColor = &cEEEEEE + p.graphics.fillRect 6, 12, x * c.progress, 12 + p.graphics.foreColor = &cE6E6E6 + p.graphics.drawRoundRect 6, 12, x, 12, 12, 12 + + end + + if c.isComplete then _ + p.graphics.drawPicture getControlPicture(0), (g.width - 14) / 2, 11 + + g.drawPicture p, 0, 0 + P = nil + return true + + elseif column = 4 then + g.textSize = kMiddleTextSize + g.drawString c.getPTime, (g.width - g.stringWidth(c.getPTime)) / 2, y - 7 + + if me.selected(row) = false then g.foreColor = kGrayTextColor + + g.textSize = kSmallTextSize + g.drawString c.getSTime, (g.width - g.stringWidth(c.getSTime)) / 2, y + 7 + return true + + else + return true + + end + + catch + + end + +End Function + +CWindow.Localize: +Protected Sub Localize() + + me.title = getLocalizedString(me.title, "Window") + +End Sub + +CWindow.setTitle: +Sub setTitle(title as string) + + me.title = title + me.menu.text = title + +End Sub + +CWindow.minimize: +Sub minimize() + + #if targetMacOS + Declare Function CollapseWindow Lib kCarbon (w as WindowPtr, b as Boolean) as Integer + + call CollapseWindow(me, true) + + #elseif targetWin32 + Const SW_MINIMIZE = 6 + Declare Sub ShowWindow Lib "user32" (wnd As Integer, nCmdShow As Integer) + + ShowWindow( me.WinHWND, SW_MINIMIZE ) + + #elseif targetLinux + 'todo + + #endif + +End Sub + +CWindow.isTextured: +Sub isTextured(Assigns b As Boolean) + + #if targetMachO then + Declare Function ChangeWindowAttributes Lib kCarbon _ + (window as WindowPtr, setTheseAttributes as Integer, clearTheseAttributes as Integer) as Integer + + const ATTRIB = 256 + + if b then + call ChangeWindowAttributes(me, ATTRIB, 0) + + else + call ChangeWindowAttributes(me, 0, ATTRIB) + + end + + #endif + +End Sub + +CWindow.maximize: +Sub maximize() + + #if targetMacOS + 'Declare Sub ZoomWindow Lib kCarbon (window as WindowPtr, partCode as Integer, front as Boolean) + 'Declare Function IsWindowInStandardState Lib kCarbon (window as WindowPtr, idealSize as Integer, idealStandardState as Integer) as Boolean + ' + 'if IsWindowInStandardState(me, 0, 0) then + 'ZoomWindow(me, 7, false) + ' + 'else + 'ZoomWindow(me, 8, false) + ' + 'end + ' + #elseif targetWin32 + Const SW_MAXIMIZE = 3 + Declare Sub ShowWindow Lib "user32" (wnd As Integer, nCmdShow As Integer) + + ShowWindow( me.WinHWND, SW_MAXIMIZE ) + + #elseif targetLinux + 'todo + + #endif + +End Sub + +CWindow.getState: +Protected Function getState() As Integer + + #if targetWin32 + Declare Function IsIconic Lib "user32" (ByVal hwnd As Integer) As Integer + Declare Function IsZoomed Lib "user32" (ByVal hwnd As Integer) As Integer + + Dim minflag, maxflag As Integer + + minflag = IsIconic(me.WinHWND) //is window minimized? + maxflag = IsZoomed(me.WinHWND) //is window maximized? + + If minflag <> 0 Then + return kWindowStateMinimized + + ElseIf maxflag <> 0 Then + return kWindowStateMaximized + + Else + return kWindowStateRestored + + End If + + #endif + +End Function + +CWindow.loadSizeAndState: +Sub loadSizeAndState(name as string) + + #if targetMacOS + me.isTextured = kAqTexturedWindow + + dim args(-1), result as string + + result = defaultsRead("CWindow " + name, result) + args = result.split + + if ubound(args) = 3 then + me.left = args(0).val + me.top = args(1).val + me.width = args(2).val + me.height = args(3).val + + end + + #elseif targetWin32 + dim args(-1), result as string + dim mode as integer + + mode = defaultsRead("CWindowState " + name, mode) + + select case mode + + case kWindowStateRestored + result = defaultsRead("CWindow " + name, result) + args = result.split + + if ubound(args) = 3 then + me.left = args(0).val + me.top = args(1).val + me.width = args(2).val + me.height = args(3).val + + end + + case kWindowStateMinimized + me.minimize + + case kWindowStateMaximized + me.maximize + + end + + #elseif targetLinux + dim args(-1), result as string + + result = defaultsRead("CWindow " + name, result) + args = result.split + + if ubound(args) = 3 then + me.left = args(0).val + me.top = args(1).val + me.width = args(2).val + me.height = args(3).val + + end + + #endif + +End Sub + +CWindow.saveSizeAndState: +Sub saveSizeAndState(name as string) + + #if targetMacOS or targetLinux + defaultsWrite "CWindow " + name, _ + str(me.left) + " " + str(me.top) + " " + str(me.width) + " " + str(me.height) + + #elseif targetWin32 + defaultsWrite "CWindow " + name, _ + str(me.left) + " " + str(me.top) + " " + str(me.width) + " " + str(me.height) + defaultsWrite "CWindowState " + name, me.getState + + #endif + +End Sub + +CWindow.Deactivate: +Sub Deactivate() + + if me.menu <> nil then me.menu.checked = false + +End Sub + +CWindow.Activate: +Sub Activate() + + if me.menu <> nil then me.menu.checked = true + +End Sub + +CWindow.Close: +Sub Close() + + if me.menu <> nil then me.menu.close + + Close + +End Sub + +CWindow.Open: +Sub Open() + + Localize + me.menu = new WindowMenus + me.menu.text = me.title + Open + +End Sub +
Show on old repository browser