Commits

Tomaz Curk committed 146f3d0

need this before Qt4 become trunk (main branch)

  • Participants
  • Parent commits 5e6834c

Comments (0)

Files changed (396)

install-scripts/OrangeInstall.ico

Added
New image

install-scripts/OrangeOWS.ico

Added
New image

install-scripts/buildinstfilelist.py

+import os, re, sys, md5
+import pysvn
+
+basedir = sys.argv[1]
+fileprefix = sys.argv[2]
+mac = len(sys.argv) > 3 and sys.argv[3] == "mac"
+
+if basedir[-1] != "\\":
+    basedir += "\\"
+#basedir = "c:\\janez\\orange\\"
+
+print "Constructing file lists for Orange in '%s', prefix is '%s'" % (basedir, fileprefix)
+
+snapshot = fileprefix[:8] == "snapshot"
+protoDir = "orange\\orangewidgets\\prototypes\\"
+
+exclude = [x.lower().replace("/", "\\")[:-1] for x in open(basedir+"orange\\exclude.lst", "rt").readlines()]
+file_re = re.compile(r'/(?P<fname>.*)/(?P<version>.*)/(?P<date>.*)/[^/]*/')
+
+def computeMD(filename):
+    existing = open(filename, "rb")
+    currmd = md5.new()
+    currmd.update(existing.read())
+    existing.close()
+    return currmd.hexdigest()
+
+def excluded(fname):
+    fname = fname.lower()
+    if not snapshot and fname[:len(protoDir)] == protoDir:
+        print "Excluded %s (prototype)" % fname
+        return 1
+
+    for ex in exclude:
+        if ex==fname[:len(ex)]:
+            print "Excluded %s (as %s)" % (fname, ex)
+            return 1
+
+outfs = ""
+hass = ""
+down = ""
+
+def buildListLow(root_dir, here_dir, there_dir, regexp, recursive):
+    global outfs, hass, down
+    
+    SVNclient = pysvn.Client()
+
+    if not os.path.exists(root_dir+here_dir):
+        return
+    
+    whatsDownEntries = None
+    directories = []
+    for fle in os.listdir(root_dir+here_dir):
+        tfle = root_dir+here_dir+fle
+        if fle == ".svn" or excluded("orange\\"+there_dir+fle):
+            continue
+        if os.path.isdir(tfle):
+            if recursive:
+                directories.append((here_dir, there_dir, fle))
+        else:
+            if not regexp or regexp.match(fle):
+                if not whatsDownEntries:
+                    if not mac:
+                        outfs += '\nSetOutPath "$INSTDIR\\%s"\n' % there_dir
+                    if there_dir[:14] == "orangeWidgets\\" and there_dir.count("\\")==2 and there_dir[14:-1]!="icons":
+                        if mac:
+                            down += there_dir[14:-1] + "\n" 
+                        else:
+                            hass += 'FileWrite $WhatsDownFile "+%s$\\r$\\n"\n' % there_dir[14:-1]
+
+                    whatsDownEntries = {}
+                    for ent in SVNclient.status(root_dir+here_dir, recurse=0):
+                        if ent.entry == None or ent.entry.kind <> pysvn.node_kind.file:
+                            continue
+                        fname, version = ent.entry.name, ent.entry.commit_revision.number
+                        whatsDownEntries[fname] = (there_dir+fname, version, computeMD(root_dir+here_dir+fname))
+
+                if whatsDownEntries.has_key(fle):
+                    if mac:
+                        outfs += tfle + "\n"
+                        down += '%s=%s:%s\n' % whatsDownEntries[fle]
+                    else:
+                        outfs += 'File "%s"\n' % tfle
+                        outfs += 'FileWrite $WhatsDownFile "%s=%s:%s$\\r$\\n"\n' % whatsDownEntries[fle]
+
+    for here_dir, there_dir, fle in directories:
+        buildListLow(root_dir, here_dir+fle+"\\", there_dir+fle+"\\", regexp, recursive)
+
+
+def buildList(root, here, there, regexp, fname, recursive=1):
+    global outfs, hass
+    outfs = hass = ""
+    buildListLow(root, here, there, regexp and re.compile(regexp, re.IGNORECASE), recursive)
+    open(fileprefix+"_"+fname+".inc", "wt").write(hass+outfs)
+    if mac:
+        open(fileprefix+"_"+fname+".down", "wt").write(down)
+
+def buildLists(rhter, fname):
+    global outfs, hass
+    outfs = hass = ""
+    for root, here, there, regexp, recursive in rhter:
+        buildListLow(root, here, there, regexp and re.compile(regexp, re.IGNORECASE), recursive)
+    open(fileprefix+"_"+fname+".inc", "wt").write(hass+outfs)
+
+
+#def buildPydList(root, here, there, fname, lookinver="25\\"):
+#    here = root + here
+#    outf = open(fileprefix+"_"+fname+".inc", "wt")
+#    outf.write('\nSetOutPath "$INSTDIR\\%s"\n' % there)
+#    for fle in os.listdir(here+lookinver):
+#        if fle[-4:] == ".pyd":
+#            outf.write('File "%s${PYVER}\\%s"\n' % (here, fle))
+#            outf.write('FileWrite $WhatsDownFile "%s=1.0:%s$\\r$\\n"\n' % (there+fle, computeMD(here+lookinver+fle)))
+
+buildList(basedir, "orange\\", "", "((.*[.]py)|(ensemble.c)|(COPYING)|(c45.dll))\\Z", "base", 0)
+#buildPydList(basedir, "", "", "binaries")
+
+buildList(basedir, "orange\\OrangeWidgets\\", "OrangeWidgets\\", ".*[.]((py)|(png))\\Z", "widgets")
+buildList(basedir, "orange\\OrangeCanvas\\", "OrangeCanvas\\", ".*[.]((py)|(pyw)|(png))\\Z", "canvas")
+
+# buildLists([(basedir, "genomics\\", "OrangeWidgets\\Genomics\\", ".*[.]py\\Z", 0),
+#            (basedir, "genomics\\GO\\", "OrangeWidgets\\Genomics\\GO\\", "", 0),
+#            (basedir, "genomics\\Annotation\\", "OrangeWidgets\\Genomics\\Annotation\\", "", 0),
+#            (basedir, "genomics\\Genome Map\\", "OrangeWidgets\\Genomics\\Genome Map\\", "", 0)], "genomics")
+
+buildLists([(basedir, "orange\\doc\\", "doc\\", "", 0), 
+            (basedir, "orange\\doc\\datasets\\", "doc\\datasets\\", "", 0),
+            (basedir, "orange\\doc\\reference\\", "doc\\reference\\", "", 0),
+            (basedir, "orange\\doc\\modules\\", "doc\\modules\\", "", 0),
+            (basedir, "orange\\doc\\widgets\\", "doc\\widgets\\", "", 0),
+            (basedir, "orange\\doc\\ofb\\", "doc\\ofb\\", "", 0)], "doc")
+

install-scripts/cakipol.py

+import time
+time.sleep(70)
+import os, popen2
+os.chdir(r"c:\inetpub\wwwusers\orange")
+##err_out, stdin = popen2.popen4('"c:\program files\wincvs 1.3\cvsnt\cvs.exe" -d :sspi:cvso@estelle.fri.uni-lj.si:/CVS update doc')
+##err_out.readlines()
+##err_out.close()
+##stdin.close()

install-scripts/cakipolpaupdejti.py

+import time
+time.sleep(5)
+import os
+os.chdir(r"c:\inetpub\wwwusers\orange")
+os.system('"c:\program files\wincvs 1.3\cvsnt\cvs.exe" -d :sspi:cvso@estelle.fri.uni-lj.si:/CVS update doc')

install-scripts/callRegression.btm

+call updateSetConstants__.btm
+
+pushd
+cd ..
+cvs -d :sspi;username=cvs;password=cvs;hostname=estelle.fri.uni-lj.si:/cvs checkout -P -- regressionTests
+cvs -d :sspi;username=cvs;password=cvs;hostname=estelle.fri.uni-lj.si:/cvs checkout -P -d doc -- orange/doc
+popd
+
+if exist regressionTests.log del regressionTests.log
+
+for %pyver in (%PYTHONVERSIONS) do (
+  echo Python %pyver
+  call regressionTests.btm %pyver >> regressionTests.log
+  flag_on_error
+)
+
+set REGRESDIR=%WEBDOWNLOAD\regressionResults
+if not exist %REGRESDIR mkdir %REGRESDIR
+
+for %d in (modules-output ofb-output reference-output) do (
+  for %res in (crash error new changed random1 random2) do (
+    rem remove old regression reports from web and copy new
+    del /s %REGRESDIR\regressionTests\%d\*.py.win32.?.?.%res.txt
+    copy /s ..\regressionTests\%d\*.py.*.?.?.%res.txt %REGRESDIR\regressionTests\%d
+  )
+)
+
+copy regressionTests.log %REGRESDIR\windows.regress.log
+
+iff %ERRORS != 0 then
+  set subj="Error in regression tests on Windows"
+else
+  set subj="Regression tests on Windows completed successfully"
+endiff
+
+sendmail %MAIL_TO %subj @regressionTests.log
+

install-scripts/callUpdateSnapshot.btm

+@echo off
+call updateSnapshot.btm >& updateSnapshot.log
+
+iff %ERRORS != 0 then
+  set subj="Error compiling Orange for Windows"
+else
+  set subj="Orange for Windows compiled successfully"
+endiff
+
+sendmail %MAIL_TO %subj @%LOGFILE
+
+set REGRESDIR=%WEBDOWNLOAD\regressionResults
+if not exist %REGRESDIR mkdir %REGRESDIR
+copy updateSnapshot.log %REGRESDIR\windows.compiling.log
+
+rem this is now called in a different VM
+rem plink -P 2222 -i "C:\Documents and Settings\cvso\george.ppk" orange@212.235.189.56 bash --login ~/install-scripts/linux/createSnapshot.sh stable %PLINK_SOURCE_SNAPSHOT normal %daystr SOURCE_SNAPSHOT 0;bash --login ~/install-scripts/linux/createSnapshot.sh stable %PLINK_SOURCE_GENOMICS_SNAPSHOT genomics %daystr SOURCE_GENOMICS_SNAPSHOT 0; bash --login ~/install-scripts/linux/createSnapshot.sh stable %PLINK_LINUX_SNAPSHOT normal %daystr LINUX_SNAPSHOT 1; bash --login ~/install-scripts/linux/createSnapshot.sh stable %PLINK_LINUX_GENOMICS_SNAPSHOT genomics %daystr LINUX_GENOMICS_SNAPSHOT 1
+rem start plink -i "C:\Documents and Settings\Administrator\morty.ppk" blaz@morty.fri.uni-lj.si bash --login ~/install-scripts/mac/callmacinstallation.sh stable %PLINK_MACINTOSH_SNAPSHOT MACINTOSH_SNAPSHOT 0 1;  bash --login ~/install-scripts/mac/callmacinstallation.sh stable %PLINK_MACINTOSH_GENOMICS_SNAPSHOT MACINTOSH_GENOMICS_SNAPSHOT 1 0

install-scripts/customInstall.cgi

+import cgi
+
+argflags = [("Python", " /DINCLUDEPYTHON", 1),
+            ("PyQt", " /DINCLUDEPYQT", 2),
+            ("PyQwt", " /DINCLUDEPYQWT", 4),
+            ("qt", " /DINCLUDEQT", 8),
+            ("numeric", " /DINCLUDENUMERIC", 16),
+            ("pythonwin", " /DINCLUDEPYTHONWIN", 32),
+            ("dot", " /DINCLUDEDOT", 64),
+            ("scriptingdoc", " /DINCLUDESCRIPTDOC", 128),
+            ("datasets", " /DINCLUDEDATASETS", 256),
+            ("source", " /DINCLUDESOURCE", 512),
+            ("genomicsdata", " /DINCLUDEGENOMICS", 1024)
+           ]
+
+args = ""
+flags = 0
+form = cgi.FieldStorage()
+for c, f, fl in argflags:
+    if form.getvalue(c, ""):
+        args += f
+        flags += fl
+
+print 'Content-type: text/html\n\n<html><HEAD><LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen></HEAD><BODY><CENTER>'
+print '<P>&nbsp;</P>' * 5
+print '<HR>'
+
+if flags == 0x1ff and 0:
+    print '<P>You have chosen the standard Orange installation with Python.</P>'
+    print '<P>Click <a href="../download2/Orange-complete.exe">here</a> to get it.'
+
+elif flags == 0x80:
+    print '<P>You have chosen the standard Orange installation.</P>'
+    print '<P>Click <a href="../download2/Orange-standard.exe">here</a> for download.'
+
+else:
+    import os, time
+    
+    os.chdir("C:\Inetpub\wwwUsers\orange\download\custom")
+    filedir = ("%i" + ("-%2.2i" * 5)) % time.localtime()[:6]
+    if os.path.exists(filedir):
+        app = 1
+        while os.path.exists(filedir + "-%i" % app):
+            app += 1
+        filedir += "%i" % app
+    filename = "Orange-custom.exe"
+
+    os.mkdir(filedir)
+
+    os.chdir("C:\Inetpub\wwwUsers\orange\scripts")
+    args += ' /DORANGEDIR=c:\\inetpub\\wwwusers\\orange\\download\\lastStable\\orange'
+    args += ' /DCWD=%s' % os.getcwd()
+    args += ' /DOUTFILENAME=c:\\inetpub\\wwwusers\\orange\\download\\custom\\%s\\%s' % (filedir, filename)
+    
+    args += ' install3.nsi'
+#    os.spawnv(os.P_WAIT, "C:\\Program Files\\NSIS\\makensis.exe", [args])
+    if os.system('"C:\Program Files\NSIS\makensis.exe"' + args):
+    	print "<P>Error generating installation program; system administrator will be notified.</P>"
+    else:
+    	print '<P>Your installation file is ready for <a href="//www.ailab.si/orange/download/custom/%s/%s">download</a>.</P><P>(The file will disappear in approximately two hours.)' % (filedir, filename)
+#    print flags, '<P>%s</P>' % args
+
+print '<P><HR></CENTER>'
+

install-scripts/customInstall.py

+import cgi
+
+print 'Content-type: text/html\n\n<html><HEAD><LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen></HEAD><BODY><CENTER>'
+print '<P>&nbsp;</P>' * 5
+print '<HR>'
+asdf
+
+ORANGEROOT = "c:\\inetpub\\wwwusers\\orange\\"
+
+argflags = [("Python", " /DINCLUDEPYTHON", 1),
+            ("PyQt", " /DINCLUDEPYQT", 2),
+            ("PyQwt", " /DINCLUDEPYQWT", 4),
+            ("qt", " /DINCLUDEQT", 8),
+            ("numeric", " /DINCLUDENUMERIC", 16),
+            ("pythonwin", " /DINCLUDEPYTHONWIN", 32),
+            ("dot", " /DINCLUDEDOT", 64),
+            ("scriptingdoc", " /DINCLUDESCRIPTDOC", 128),
+            ("datasets", " /DINCLUDEDATASETS", 256),
+            ("source", " /DINCLUDESOURCE", 512),
+            ("genomicsdata", " /DINCLUDEGENOMICS", 1024)
+           ]
+
+args = ""
+flags = 0
+form = cgi.FieldStorage()
+for c, f, fl in argflags:
+    if form.getvalue(c, ""):
+        args += f
+        flags += fl
+
+print 'Content-type: text/html\n\n<html><HEAD><LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen></HEAD><BODY><CENTER>'
+print '<P>&nbsp;</P>' * 5
+print '<HR>'
+
+if flags == 0x1ff and 0:
+    print '<P>You have chosen the standard Orange installation with Python.</P>'
+    print '<P>Click <a href="../download/Orange-complete.exe">here</a> to get it.'
+
+elif flags == 0x80:
+    print '<P>You have chosen the standard Orange installation.</P>'
+    print '<P>Click <a href="../download/Orange-standard.exe">here</a> for download.'
+
+else:
+    import os, time
+    
+    os.chdir(ORANGEROOT+"download\\custom")
+    filedir = ("%i" + ("-%2.2i" * 5)) % time.localtime()[:6]
+    if os.path.exists(filedir):
+        app = 1
+        while os.path.exists(filedir + "-%i" % app):
+            app += 1
+        filedir += "%i" % app
+    filename = "Orange-custom.exe"
+
+    os.mkdir(filedir)
+
+    os.chdir(ORANGEROOT + "scripts")
+    args += ' /DORANGEDIR='+ORANGEROOT+'download\\lastStable\\orange'
+    args += ' /DCWD=%s' % os.getcwd()
+    args += ' /DOUTFILENAME='+ORANGEROOT+'download\\custom\\%s\\%s' % (filedir, filename)
+    
+    args += ' install3.nsi'
+    os.spawnv(os.P_WAIT, "C:\\Program Files\\NSIS\\makensis.exe", [args])
+#    if os.system('"C:\Program Files\NSIS\makensis.exe"' + args):
+#    	print "<P>Error generating installation program; system administrator will be notified.</P>"
+#    else:
+#    	print '<P>Your installation file is ready for <a href="//www.ailab.si/orange/download/custom/%s/%s">download</a>.</P><P>(The file will disappear in approximately two hours.)' % (filedir, filename)
+#    print flags, '<P>%s</P>' % args
+
+print '<P><HR></CENTER>'
+

install-scripts/customInstall2.py

+f = file("c:\\xxx")
+f.close()
+import os
+os.chdir(ORANGEROOT + "scripts")
+os.spawn(os.P_WAIT, "C:\python23\python.exe", ["customInstall.py"])

install-scripts/doc/compileDocumentation.btm

+@echo off
+
+if not exist processed mkdir processed
+cd processed
+
+set PATH=%PATH;"c:\Program Files\HTML Help Workshop"
+alias hhc `*hhc %1.hhp >& tmp   %+   for %line in (@tmp) (iff "%@left[3,%line]" == "HHC" .and. "%@left[8,%line]" != "HHC3004:" .and. "%@left[8,%line]" != "HHC1000:" then %+ echo %line %+ endiff) %+ del /q tmp`
+alias compile `..\htmlparser.py %1 %+ hhc %1`
+
+for %dir in (modules ofb reference widgets) (
+  echo ^n=== %dir
+  mkdir %dir 2> nul
+  copy /q %WEBDOCDIR\%dir %WEBDOCDIR\style.css %dir
+  iff exist %dir\default-chm.htm then
+    move /q %dir\default-chm.htm %dir\default.htm
+  endiff
+  compile %dir
+)
+
+echo ^n=== catalog
+mkdir catalog 2> nul
+copy /qs %WEBDOCDIR\widgets\catalog catalog
+copy /q %WEBDOCDIR\style.css catalog
+move /q catalog\default-chm.htm catalog\default.htm
+
+pushd
+cdd %SNAPSHOTDIR\orange\orangeCanvas
+python orngRegistry.py
+popd
+
+..\widgetCatalogs.py html "C:\Documents and Settings\cvso\Application Data\Orange\OrangeCanvas\widgetRegistry.xml" catalog >> catalog/default.htm
+..\widgetCatalogs.py hh "C:\Documents and Settings\cvso\Application Data\Orange\OrangeCanvas\widgetRegistry.xml" catalog > catalog/hhstructure.txt
+compile catalog
+
+cd ..
+copy %WEBDOCDIR\style.css
+hhc scripting
+hhc orange
+del style.css
+
+del /fsykxq processed
+move /q *.chm %WEBDOCDIR
+
+echo ^s

install-scripts/doc/getWidgetContacts.py

+from xml.dom import minidom
+import re
+
+re_parenth = re.compile(r"\(.*\)")
+
+widgets = {}
+people = {}
+
+dom1 = minidom.parse(open("../../OrangeCanvas/widgetregistry.xml", "rt"))
+for categoryNode in dom1.getElementsByTagName("category"):
+    category = categoryNode.getAttribute("name")
+    for widgetNode in categoryNode.getElementsByTagName("widget"):
+        widget = widgetNode.getAttribute("name")
+        contact = re_parenth.sub("", widgetNode.getAttribute("contact")).strip()
+        people.setdefault(contact, {}).setdefault(category, []).append(widget)
+        widgets.setdefault(category, []).append((widget, contact))
+
+
+def sorted(d):
+    d.sort()
+    return d
+
+print "*** WIDGETS by AUTHORS\n"
+
+for contact in sorted(people.keys()):
+    print contact or "<no contact>"
+    work = people[contact]
+    for category in sorted(work.keys()):
+        print "    %s: %s" % (category, ", ".join(sorted(work[category])))
+    print
+
+    
+print "\n\n\n*** AUTHORS by WIDGETS\n"
+
+for category in sorted(widgets.keys()):
+    print category
+    categoryWidgets = widgets[category]
+    for widget in sorted(categoryWidgets):
+        print "    %s: %s" % widget
+    print

install-scripts/doc/htmlparser.py

+from operator import add
+from operator import add
+import re, sys, os, sets
+
+class TOCEntry:
+    def __init__(self, title, url):
+        self.title = title
+        self.url = url
+        self.subentries = []
+
+def copydir(src, target):
+    if os.path.isdir(src):
+        tryMk(target)
+        for f in os.listdir(src):
+            copydir(src+"/"+f, target+"/"+f)
+    else:
+        file(target, "wb").write(file(src, "rb").read())
+
+
+def tryMk(dir):
+    try:
+        os.mkdir(dir)
+    except:
+        pass
+
+
+class IndexStore:
+    def __init__(self, aname, entries = None):
+        self.name = aname
+        if entries:
+            self.entries = entries[:]
+        else:
+            self.entries = []
+        self.subentries = {}
+
+
+htags = [tg % i for tg in ["<h%i>", "<h%i "] for i in range(5)]
+
+def findLastTag(outp, tag, start = None):
+    ri = -1
+    if tag == "h":
+        tags = htags
+    else:
+        tags = "<%s>" % tag, "<%s " % tag
+        
+    for l in range(start or len(outp)-1, -1, -1):
+        ri = max([outp[l].lower().rfind(tg) for tg in tags])
+        if ri > -1:
+            return l, ri
+
+    return -1, -1        
+        
+    
+def addIndex(indexStoreList, name, title=None, filename=None, counter = None):
+    cateS = indexStoreList.get(name.lower(), None)
+    if not cateS:
+        cateS = IndexStore(name)
+        indexStoreList[name.lower()] = cateS
+    
+    if title:
+        cateS.entries.append((title, filename, counter))
+
+    return cateS
+
+
+def addAName(outp, aname, lasttag=None):
+    if not lasttag or lasttag == "here":
+        ri = -1
+    elif lasttag == "head":
+        l, ri = findLastTag(outp, "h")
+    elif lasttag == "phead":
+        l, ri = findLastTag(outp, "p")
+        lh, rih = findLastTag(outp, "h")
+        if rih > -1:
+            lp2, rip2 = findLastTag(outp, "p", l-1)
+            if ri == -1 or lp2 < lh:
+                l, ri = lh, rih
+    else:
+        l, ri = findLastTag(outp, lasttag)
+
+    if ri > -1:
+        outp[l] = outp[l][:ri] + aname + outp[l][ri:]
+    else:
+        outp.append(aname)
+
+        
+def findIndices(filename, title):
+    page = open(filename).read()
+    lowpage = page.lower()
+    outp = []
+    lastout = 0
+    counter = 0
+    lidx = 0
+    H2Entry = None
+    re_idx = re.compile(r'<index(?P<options>\s+[^>]+)?>', re.IGNORECASE + re.DOTALL)
+    re_h2 = re.compile(r'<h2(\s+toc\s*=\s*(?P<toc>("[^"]*"|0)))?>', re.IGNORECASE + re.DOTALL)
+    re_h3 = re.compile(r'<h3(\s+toc\s*=\s*(?P<toc>("[^"]*"|0)))?>', re.IGNORECASE + re.DOTALL)
+
+    re_opt_name = re.compile(r'\s*name\s*=\s*(?P<name>("[^"]*"|0))\s*', re.IGNORECASE + re.DOTALL)
+    re_opt_pos = re.compile(r'\s*pos\s*=\s*(?P<pos>("[^"]*"))\s*', re.IGNORECASE + re.DOTALL)
+
+    while 1:
+        idxm = re_idx.search(lowpage, lidx)
+        indx = idxm and idxm.start() or -1
+
+        if processHeaders:
+            h2m = re_h2.search(lowpage, lidx)
+            h2 = h2m and h2m.start() or -1
+            
+            h3m = re_h3.search(lowpage, lidx)
+            h3 = h3m and h3m.start() or -1
+        else:
+            h2 = h3 = -1
+
+        indices = filter(lambda x:x>=0, (indx, h2, h3))
+        if not indices:
+            break
+        
+        idx = min(indices)
+        if idx == indx:
+            optionsg = idxm.group("options")
+            posg = "phead"
+            name = ""
+            if optionsg:
+                mg = re_opt_name.match(optionsg)
+                if mg:
+                    nameg = mg.group("name")
+                    begopt = idxm.span("options")[0]
+                    b, e = mg.span("name")
+                    name = page[begopt+b+1:begopt+e-1]
+                
+                mg = re_opt_pos.match(optionsg)
+                if mg:
+                    posg = mg.group("posg")
+                    if posg == "here":
+                        posg = None
+                    
+            eidx = lowpage.find("</index>", idx)
+            
+            nextidxm = re_idx.search(lowpage, indx+5)
+            missingendtag = nextidxm and nextidxm.start() < eidx
+
+            if not name:
+                if missingendtag or eidx == -1:
+                    print "Warning: missing end of index in '%s'" % filename
+                    lidx = idxm.end()
+                    continue
+                if eidx - idxm.end() > 100:
+                    print "Warning: suspiciously long index in '%s'" % filename
+                    lidx = indxm.end()
+                    continue
+                name = page[idxm.end():eidx]
+
+            name = name.replace("\n", " ")
+            outp.append(page[lastout:idx])
+            addAName(outp, '<a name="HH%i">' % counter, posg)
+
+            if eidx > -1 and (not nextidxm or eidx < nextidxm.start()):
+                outp.append(page[idxm.end():eidx])
+                lastout = lidx = eidx+8
+            else:
+                lastout = lidx = idxm.end()
+
+            if "+" in name:
+                catename = name.split("+")
+                if len(catename) == 2:
+                    cate, name = catename
+                    cateS = addIndex(index, cate)
+                    addIndex(index, name, title, filename, counter)
+                    addIndex(cateS.subentries, name, title, filename, counter)
+                else:
+                    addIndex(index, name, title, filename, counter)
+            elif "/" in name:
+                cate, name = name.split("/")
+                cateS = addIndex(index, cate)
+                addIndex(cateS.subentries, name, title, filename, counter)
+            else:
+                addIndex(index, name, title, filename, counter)
+            counter += 1
+
+        else:
+            ht = idx==h2 and "h2" or "h3"
+            mo = idx==h2 and h2m or h3m
+
+            skip = 0
+            toc = mo.group("toc")
+            if toc:
+                if toc == "0":
+                    skip = 1
+                else:
+                    b, e = mo.span("toc")
+                    name = page[b+1:e-1]
+            else:
+                eidx = lowpage.find("</%s>" % ht, idx)
+                if eidx == -1:
+                    print "Warning: missing end of %s in '%s'" % (ht, filename)
+                    break
+                if eidx - idx > 100:
+                    print "Warning: suspiciously long %s in '%s'" % (ht, filename)
+                    lidx = idx + 4
+                    continue
+
+                name = page[idx+4:eidx]
+            
+            outp.append(page[lastout:idx])
+            if not skip:
+                outp.append('<a name="HH%i">' % counter)
+            outp.append("<%s>" % ht)
+            lastout = lidx = mo.end()
+
+            if not skip:
+                newEntry = TOCEntry(name, "%s#HH%i" % (filename, counter))
+                if ht == "h2":
+                    TOCStack[-1].subentries.append(newEntry)
+                    H2Entry = newEntry
+                else:
+                    (H2Entry or TOCStack[-1]).subentries.append(newEntry)
+                counter += 1
+
+    outp.append(page[lastout:])
+
+    return reduce(add, outp)    
+
+
+def writeIndexHH_store(hhk, indexStoreList):
+    hhk.write("\n<UL>")
+    for indexStore in indexStoreList.values():
+        if indexStore.entries or indexStore.subentries:
+            hhk.write(hhkentry % indexStore.name)
+            if indexStore.entries:
+                for entry in indexStore.entries:
+                    hhk.write(hhksubentry % entry)
+            else:
+                for substore in indexStore.subentries.values():
+                    for subentry in substore.entries:
+                        hhk.write(hhksubentry % subentry)
+            hhk.write(hhkendentry)
+            if indexStore.subentries:
+                writeIndexHH_store(hhk, indexStore.subentries)
+    hhk.write("\n</UL>")
+    
+def writeIndexHH(outputstub):
+    hhk = file("%s.hhk" % outputstub, "w")
+    hhk.write(hhkhead)
+    writeIndexHH_store(hhk, index)
+    hhk.close()
+
+
+def writeTocHHRec(hhc, node, l=0):
+    spaces = " "*(l*4)
+    hhc.write(hhcentry % {"spc": spaces, "name": node.title, "file": node.url})
+    if node.subentries:
+        hhc.write(spaces + "<UL>\n")
+        for s in node.subentries:
+            writeTocHHRec(hhc, s, l+1)
+        hhc.write(spaces + "</UL>\n\n")
+    
+def writeTocHH(outputstub):
+    hhc = file("%s.hhc" % outputstub, "w")
+    hhc.write(hhchead)
+    for s in TOCRoot.subentries:
+        writeTocHHRec(hhc, s, 0)
+    hhc.write(hhcfoot)
+
+    
+def writeHHP(outputstub, title):
+    hhp = file("%s.hhp" % outputstub, "w")
+    hhp.write(hhphead % {"stub": outputstub, "title": title})
+    hhp.write("[FILES]\n" + "\n".join(files))
+
+
+
+def underspace(s):
+    return s.replace("_", " ")
+
+def main():
+    global processHeaders, outputstub, TOCStack, title, files, index, TOCRoot, TOCStack
+    
+    bookname = ""
+    dir = outputstub = underspace(sys.argv[1])
+    
+    processHeaders = outputstub != "catalog"
+
+    files = sets.Set()
+    files.add(dir+"/style.css")
+
+    index = {}
+    TOCRoot = TOCEntry("", dir + "/default.htm")
+    TOCStack = [TOCRoot]
+
+    re_hrefomod = re.compile(r'href\s*=\s*"\.\.[/\\](?P<module>(ofb)|(reference)|(modules))[/\\](?P<rest>[^"]+)"', re.IGNORECASE + re.DOTALL)
+    
+    for fle in file(dir+"/hhstructure.txt"):
+        fle = fle.rstrip(" \n\r")
+        if not fle:
+            continue
+        
+        level = 0
+        while fle[level] == "\t":
+            level += 1
+
+        arrow = fle.find("--->")
+        title = fle[:arrow].strip()
+        fn = fle[arrow+4:].strip()
+        if not TOCRoot.title:
+            TOCRoot.title = title
+            
+
+        filename = dir+"/"+fn
+
+        newentry = TOCEntry(title, filename)
+
+        if level > len(TOCStack)-1:
+            print "Error in '%s/hhstructure.txt' (invalid identation in line '%s')" % (dir, fle.strip())
+            sys.exit()
+        TOCStack = TOCStack[:level+1]
+        TOCStack[-1].subentries.append(newentry)
+        TOCStack.append(newentry)
+
+        if not filename in files:
+            files.add(filename)
+
+            page = findIndices(filename, title)
+            page = re_hrefomod.sub(r'href="ms-its:\g<module>.chm::/\g<module>/\g<rest>"', page)
+            page = page.replace("../style.css", "ms-its:"+outputstub+".chm::/"+dir+"/style.css")
+            page = page.replace('Up: <a href="../default.htm">Orange Documentation</a>', '')
+
+            file(filename, "w").write(page)    
+
+
+    writeIndexHH(outputstub)
+    writeTocHH(outputstub)
+    writeHHP(outputstub, TOCRoot.title)
+
+    anoun = False
+    cfiles = sets.Set([f.lower() for f in files] + [dir+"/path.htm", dir+"/links.htm"])
+    dir = dir.lower()
+    if processHeaders:
+        for fn in os.listdir(dir):
+            if fn.lower()[-4:] == ".htm" and dir+"/"+fn.lower() not in cfiles:
+                if not anoun:
+                    print "\nFiles that are not referenced in hhstructure.txt:"
+                    anoun = True
+                print "  "+fn
+    else:
+        for dr in os.listdir(dir):
+            adr = (dir+"/"+dr).lower()
+            if os.path.isdir(adr):
+                for fn in os.listdir(adr):
+                    if fn.lower()[-4:] == ".htm" and adr+"/"+fn.lower() not in cfiles:
+                        if not anoun:
+                            print "\nFiles that are not used (possibly due to name mismatches):"
+                            anoun = True
+                        print "  "+fn
+
+
+hhphead = """
+[OPTIONS]
+Binary Index=Yes
+Compiled file=../%(stub)s.chm
+Contents file=%(stub)s.hhc
+Default topic=%(stub)s/default.htm
+Display compile progress=No
+Full text search stop list file=../stop.stp
+Full-text search=Yes
+Index file=%(stub)s.hhk
+Language=0x409
+Title=%(title)s
+"""
+
+hhchead = """
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+    <param name="Window Styles" value="0x801227">
+    <param name="ImageType" value="Folder">
+</OBJECT>
+<UL>
+"""
+
+hhcentry = """%(spc)s<LI><OBJECT type="text/sitemap">
+%(spc)s    <param name="Name" value="%(name)s">
+%(spc)s    <param name="Local" value="%(file)s">
+%(spc)s</OBJECT>
+"""
+
+hhcfoot = "</UL>"
+
+hhkhead = """
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+"""
+
+hhkentry = """<LI><OBJECT type="text/sitemap">
+    <param name="Name" value="%s">"""
+
+hhksubentry = """
+    <param name="Name" value="%s">
+    <param name="Local" value="%s#HH%i">
+"""
+
+hhkendentry = "\n</OBJECT>\n"
+
+main()

install-scripts/doc/makeLocalCatalog.bat

+cd ..\..\doc\widgets\catalog
+copy default-chm.htm default.htm
+python ..\..\..\scripts\doc\widgetCatalogs.py html ..\..\..\orangeCanvas\widgetRegistry.xml . >> default.htm

install-scripts/doc/makeLocalCatalogVerbose.bat

+cd ..\..\doc\widgets\catalog
+copy default-chm.htm default.htm
+python ..\..\..\scripts\doc\widgetCatalogs.py htmlverb ..\..\..\orangeCanvas\widgetRegistry.xml . >> default.htm

install-scripts/doc/orange.hhc

+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+	<param name="ImageType" value="Folder">
+</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="catalog.chm::/catalog.hhc">
+
+		</OBJECT>
+
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="scripting.htm">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="ofb.chm::/ofb.hhc">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="modules.chm::/modules.hhc">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="reference.chm::/reference.hhc">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="widgets.chm::/widgets.hhc">
+
+		</OBJECT>
+</BODY></HTML>

install-scripts/doc/orange.hhk

+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<UL>
+	<LI> <OBJECT type="text/sitemap">
+		<param name="Name" value="orange">
+		<param name="Local" value="orange.htm">
+		</OBJECT>
+</UL>
+</BODY></HTML>

install-scripts/doc/orange.hhp

+[OPTIONS]
+Compatibility=1.1 or later
+Compiled file=orange.chm
+Contents file=orange.hhc
+Display compile progress=No
+Full-text search=Yes
+Index file=orange.hhk
+Language=0x409 English (United States)
+Title=Orange Documentation
+Default topic=orange.htm
+
+
+[MERGE FILES]
+catalog.chm
+modules.chm
+ofb.chm
+reference.chm
+widgets.chm
+
+[FILES]
+style.css
+
+[INFOTYPES]
+

install-scripts/doc/orange.htm

+<HTML>
+<HEAD>
+<title>Orange Documentation</title>
+<LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen>
+</HEAD>
+<BODY>
+
+<H1>Orange Documentation</H1>
+
+<p>A collection of white papers, tutorials and reference guides is
+avaible for Orange. Orange widget catalog is in preparation, and to
+get a feeling how it will look like browse through the paper on Orange
+widgets for functional genomics.</p>
+
+<h2 TOC=0>White Papers</h2>
+
+<dl>
+<dt><a href="http://www.ailab.si/orange/wp/orange.pdf">Orange: From Experimental Machine
+Learning to Interactive Data Mining</a></dt>
+<dd>This is a core white paper to Orange, and gives some basic ideas
+of its design, architecture and history.</dd>
+
+<dt><a href="http://www.ailab.si/orange/wp/orange widgets.pdf">Orange Widgets</a></dt>
+<dd>A white paper on Orange widgets gives a brief overview of how our
+visual programming interface with GUI commponents we call widgets are
+used to do explorative data analysis and visually construct
+applications of your need.</dd>
+
+<dt><a href="http://www.ailab.si/orange/wp/mac orange.pdf">Installation for Mac OS</a></dt>
+<dd>An installation guide for Orange on Mac OS X.</dd>
+
+<dt><a href="/http://www.ailab.siorange/wp/orange genomics.pdf">Orange Widgets for
+Functional Genomics</a></dt>
+<dd>A tutorial-style catalog of Orange widgets we have developed to
+fit some tasks in functional genomics, with emphasis on microarray
+data analysis, GO gene annotation, and gene mapping.</dd>
+
+</dl>
+
+<h2 TOC=0>On-Line Reference and Tutorials</h2>
+
+<P>The documentation posted on the web is updated from the CVS in
+real-time and refers to the latest snapshot of Orange. If you encounter
+any inconsistencies please compare the standalone documentation with the
+one on the web.</P>
+
+<dl>
+
+<dt><a href="ms-its:ofb.chm::ofb/default.htm">Orange for Beginners</a></dt>
+<dd>If you are new to Orange, and are interesting in scripting in
+Python, this is where you should start.</dd>
+
+<dt><a href="ms-its:reference.chm::reference/default.htm">Orange Reference Guide</a></dt>
+<dd>This is the core reference guide to Orange. It describes the basic
+data structures used in Orange (such as examples, attributes...),
+preprocessing, learning and classifying etc.</dd>
+
+<dt><a href="ms-its:modules.chm::modules/default.htm">Orange Modules</a></dt>
+<dd>An average user will mostly call Orange through specialized Orange modules. Each module covers a
+specific task (discretization, feature subset selection, sampling,
+assessing qualities of models) or learning method.</dd>
+
+<dt><a href="ms-its:widgets.chm::widgets/default.htm">Orange Widgets</a></dt>
+<dd>This is a tutorial that should help you start writing your own
+widgets. Widgets are often quite simple pieces of code, consisting of
+few hudred lines, that are easy to build but may offer quite a
+satisfaction when used in interaction with other widgets in Orange.</dd>
+</dl>
+
+<h2 TOC=0>Flyers</h2>
+
+<dl>
+<dt><a href="http://www.ailab.si/orange/wp/orange-leaflet.pdf">Orange</a></dt>
+<dd>Two pages about Orange data mining framework.</dd>
+
+<dt><a href="http://www.ailab.si/orange/wp/orange-leaflet-scripting.pdf">Orange
+Scripting</a></dt>
+<dd>In brief about scripting in Python for machine learning and data
+mining.</dd>
+
+<dt><a href="http://www.ailab.si/orange/wp/orange-leaflet-visual.pdf">Orange Visual
+Programming</a></dt>
+<dd>Starter for visual programming in Orange, Orange widgets and data
+mining schemas.</dd>
+</dl>
+
+</BODY></HTML>

install-scripts/doc/scheduledDocUpdate.bat

+pushd
+cd ..\..
+svn update doc
+cd doc\widgets\catalog
+move default-web.htm default.htm
+python ..\..\..\scripts\doc\widgetCatalogs.py html widgetRegistry.xml . >> default.htm
+popd

install-scripts/doc/scripting.hhc

+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<OBJECT type="text/site properties">
+	<param name="ImageType" value="Folder">
+</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="scripting.htm">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="ofb.chm::/ofb.hhc">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="modules.chm::/modules.hhc">
+
+		</OBJECT>
+	<OBJECT type="text/sitemap">
+		<param name="Merge" value="reference.chm::/reference.hhc">
+
+		</OBJECT>
+</BODY></HTML>

install-scripts/doc/scripting.hhk

+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
+<!-- Sitemap 1.0 -->
+</HEAD><BODY>
+<UL>
+	<LI> <OBJECT type="text/sitemap">
+		<param name="Name" value="orange">
+		<param name="Local" value="scripting.htm">
+		</OBJECT>
+</UL>
+</BODY></HTML>

install-scripts/doc/scripting.hhp

+[OPTIONS]
+Compatibility=1.1 or later
+Compiled file=scripting.chm
+Contents file=scripting.hhc
+Display compile progress=No
+Full-text search=Yes
+Index file=scripting.hhk
+Language=0x409 English (United States)
+Title=Orange Documentation
+Default topic=scripting.htm
+
+
+[MERGE FILES]
+modules.chm
+ofb.chm
+reference.chm
+
+[FILES]
+style.css
+
+[INFOTYPES]
+

install-scripts/doc/scripting.htm

+<HTML>
+<HEAD>
+<title>Orange Documentation for Scripting</title>
+<LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen>
+</HEAD>
+<BODY>
+
+<H1>Orange Documentation for Scripting</H1>
+
+<dl>
+<dt><a href="ms-its:ofb.chm::ofb/default.htm">Orange for Beginners</a></dt>
+<dd>If you are new to Orange, and are interesting in scripting in
+Python, this is where you should start.</dd>
+
+<dt><a href="ms-its:reference.chm::reference/default.htm">Orange Reference Guide</a></dt>
+<dd>This is the core reference guide to Orange. It describes the basic
+data structures used in Orange (such as examples, attributes...),
+preprocessing, learning and classifying etc.</dd>
+
+<dt><a href="ms-its:modules.chm::modules/default.htm">Orange Modules</a></dt>
+<dd>An average user will mostly call Orange through specialized <a
+href="ms-its::/modules/default.htm">Orange modules</a>. Each module covers a
+specific task (discretization, feature subset selection, sampling,
+assessing qualities of models) or learning method.</dd>
+
+</dl>

install-scripts/doc/widgetCatalogs.py

+def getWidgetsByCategory(xmlfilename):
+    categories = {}
+    from xml.dom import minidom
+    for categoryNode in minidom.parse(open(xmlfilename)).getElementsByTagName("category"):
+        category = categoryNode.getAttribute("name")
+        if category == "Prototypes" or categoryNode.hasAttribute("directory"):
+            continue
+        for widgetNode in categoryNode.getElementsByTagName("widget"):
+            categories.setdefault(category, []).append(dict([(x, widgetNode.getAttribute(x)) for x in ["name", "contact", "icon", "priority", "file", "in", "out"]]))
+    for cw in categories.values():
+        cw.sort(lambda x,y: cmp(int(x["priority"]), int(y["priority"])) or cmp(x["name"], y["name"]))
+    return categories
+
+
+def mergeCategories(categoriesOrder, xmlCategories):
+    return categoriesOrder + [x for x in xmlCategories.keys() if x not in categoriesOrder]
+
+
+def createCanvasCatalogPage(xmlCategories, docpath =".", categoriesOrder = ["Data", "Visualize", "Classify", "Evaluate", "Associate", "Regression"], verbose=False):
+    from os.path import exists
+    
+    catalogPage = "<table>"
+    if docpath[-1] not in "\\/":
+        docpath += "/"
+    
+    for category in mergeCategories(categoriesOrder, xmlCategories):
+        catalogPage += '<tr><td COLSPAN="6" style="border-bottom: 2px solid #F8CB66; padding-left: 4px; font-weight:bold; padding-top: 12px; padding-bottom: 4px; margin-bottom: 12px;">%s</td></tr>\n\n\n' % category
+        catalogPage += '<tr valign="top">\n'
+        for i, widget in enumerate(xmlCategories[category]):
+            if i and not i % 6:
+                catalogPage += '</tr><tr valign="top">'
+            name = widget["name"]
+            namep = name.replace(" ", "")
+            htmlfile = docpath + category + "/" + namep + ".htm"
+            icon = widget["icon"]
+            if not exists(docpath + icon):
+                icon = "icons/" + namep + ".png"
+                if not exists(docpath + icon):
+                    icon = "icons/Unknown.png"
+            if verbose:
+                contact = widget["contact"]
+                if "(" in contact:
+                    widget["contact"] = contact[:contact.index("(")]
+                verb = '<br/><font color="#bbbbbb"><small><br>%(file)s, %(priority)s<br>%(contact)s<br></small></font>' % widget
+            else:
+                verb = ""
+            if exists(htmlfile):
+                catalogPage += '<td align="center" style="padding-bottom: 12px; padding-top: 6px"><a href="%s"><img src="%s"><br/>%s</a>%s</td>' % (htmlfile, icon, name, verb)
+            else:
+                catalogPage += '<td align="center" style="padding-bottom: 12px; padding-top: 6px"><img src="%s"><br/><FONT COLOR="#bbbbbb">%s</FONT>%s</td>\n\n' % (icon, name, verb)
+        catalogPage += '</tr>'
+
+    catalogPage += "</table>"
+    
+    return catalogPage
+
+
+def createHHStructure(xmlCategories, docpath = ".", categoriesOrder = ["Data", "Visualize", "Classify", "Evaluate", "Associate", "Regression"]):
+    from os.path import exists
+    
+    hhStructure = "Widget Catalog ---> default.htm\n"
+    
+    if docpath[-1] not in "\\/":
+        docpath += "/"
+
+    for category in mergeCategories(categoriesOrder, xmlCategories):
+        introduction = "\t%s ---> default.htm\n" % category
+        for widget in xmlCategories[category]:
+            name = widget["name"]
+            catnamep = category + "/" + name.replace(" ", "") + ".htm"
+            if exists(docpath + catnamep):
+                hhStructure += introduction
+                introduction = ""
+                hhStructure += "\t\t%s ---> %s\n" % (name, catnamep)
+                
+    return hhStructure                
+
+if __name__=="__main__":
+    from sys import argv
+    categories = getWidgetsByCategory(argv[2])
+    docpath = len(argv) > 3 and argv[3] or "."
+    
+    if argv[1] == "hh":
+        print createHHStructure(categories, docpath)
+    elif argv[1] == "html":
+        print createCanvasCatalogPage(categories, docpath)
+    elif argv[1] == "htmlverb":
+        print createCanvasCatalogPage(categories, docpath, verbose=True)

install-scripts/install3.nsi

+Name "Orange"
+Icon OrangeInstall.ico
+UninstallIcon OrangeInstall.ico
+
+!ifndef ORANGEDIR
+	!define ORANGEDIR orange
+!endif
+
+!define PYFILENAME python-${NPYVER}.msi
+!define PYWINFILENAME pywin32-210.win32-py${NPYVER}.exe
+
+OutFile ${OUTFILENAME}
+
+!include "LogicLib.nsh"
+
+
+
+licensedata license.txt
+licensetext "Acknowledgments and License Agreement"
+
+AutoCloseWindow true
+ShowInstDetails nevershow
+
+Var PythonDir
+Var WhatsDownFile
+Var AdminInstall
+Var MissingModules
+
+Page license
+Page instfiles
+
+!define SHELLFOLDERS \
+  "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
+ 
+
+
+Section Uninstall
+	MessageBox MB_YESNO "Are you sure you want to remove Orange?$\r$\n$\r$\nThis won't remove any 3rd party software possibly installed with Orange, such as Python or Qt,$\r$\n$\r$\nbut make sure you have not left any of your files in Orange's directories!" /SD IDYES IDNO abort
+	RmDir /R "$INSTDIR"
+	${If} $AdminInstall = 0
+	    SetShellVarContext all
+	${Else}
+	    SetShellVarContext current	   
+	${Endif}
+	RmDir /R "$SMPROGRAMS\Orange"
+
+	ReadRegStr $0 HKCU "${SHELLFOLDERS}" AppData
+	StrCmp $0 "" 0 +2
+	  ReadRegStr $0 HKLM "${SHELLFOLDERS}" "Common AppData"
+	StrCmp $0 "" +2 0
+	  RmDir /R "$0\Orange"
+	
+	ReadRegStr $PythonDir HKLM Software\Python\PythonCore\${NPYVER}\InstallPath ""
+	${If} $PythonDir != ""
+		DeleteRegKey HKLM "SOFTWARE\Python\PythonCore\${NPYVER}\PythonPath\Orange"
+		DeleteRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Orange"
+	${Else}
+		DeleteRegKey HKCU "SOFTWARE\Python\PythonCore\${NPYVER}\PythonPath\Orange"
+		DeleteRegKey HKCU "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Orange"
+	${Endif}
+	
+	Delete "$DESKTOP\Orange Canvas.lnk"
+
+	DeleteRegKey HKEY_CLASSES_ROOT ".ows"
+	DeleteRegKey HKEY_CLASSES_ROOT "OrangeCanvas"
+
+	MessageBox MB_OK "Orange has been succesfully removed from your system.$\r$\nPython and other applications need to be removed separately.$\r$\n$\r$\nYou may now continue without rebooting your machine." /SD IDOK
+  abort:
+SectionEnd
+
+
+!macro WarnMissingModule FILE MODULE
+	${Unless} ${FileExists} ${FILE}
+		${If} $MissingModules == ""
+			StrCpy $MissingModules ${MODULE}
+		${Else}
+			StrCpy $MissingModules "$MissingModules, ${MODULE}"
+		${EndIf}
+	${EndUnless}
+!macroend
+
+!macro GetPythonDir
+    ${If} $AdminInstall == 0
+	    ReadRegStr $PythonDir HKCU Software\Python\PythonCore\${NPYVER}\InstallPath ""
+		StrCmp $PythonDir "" 0 trim_backslash
+		ReadRegStr $PythonDir HKLM Software\Python\PythonCore\${NPYVER}\InstallPath ""
+		StrCmp $PythonDir "" return
+		MessageBox MB_OK "Please ask the administrator to install Orange$\r$\n(this is because Python was installed by him, too)."
+		Quit
+	${Else}
+	    ReadRegStr $PythonDir HKLM Software\Python\PythonCore\${NPYVER}\InstallPath ""
+		StrCmp $PythonDir "" 0 trim_backslash
+		ReadRegStr $PythonDir HKCU Software\Python\PythonCore\${NPYVER}\InstallPath ""
+		StrCmp $PythonDir "" return
+		StrCpy $AdminInstall 0
+	${EndIf}
+
+	trim_backslash:
+	StrCpy $0 $PythonDir "" -1
+    ${If} $0 == "\"
+        StrLen $0 $PythonDir
+        IntOp $0 $0 - 1
+        StrCpy $PythonDir $PythonDir $0 0
+    ${EndIf}
+
+	return:
+!macroend
+		
+
+
+!ifdef COMPLETE
+
+!if ${PYVER} == 23
+	!define MFC mfc42.dll
+!else
+	!define MFC mfc71.dll
+!endif
+
+Section ""
+		StrCmp $PythonDir "" 0 have_python
+
+		SetOutPath $DESKTOP
+		!if ${PYVER} == 23
+			askpython23:
+				MessageBox MB_OKCANCEL "Orange installer will first launch installation of Python ${NPYVER}$\r$\nOrange installation will continue after you finish installing Python." /SD IDOK IDOK installpython23
+					MessageBox MB_YESNO "Orange cannot run without Python.$\r$\nAbort the installation?" IDNO askpython23
+						Quit
+			installpython23:
+				File 3rdparty-23\Python-2.3.5.exe
+				ExecWait "$DESKTOP\Python-2.3.5.exe"
+				Delete "$DESKTOP\Python-2.3.5.exe"
+
+		!else
+		    StrCpy $0 ""
+			askpython:
+				MessageBox MB_YESNOCANCEL "Orange installer will first launch installation of Python ${NPYVER}.$\r$\nWould you like it to install automatically?$\r$\n(Press No for Custom installation of Python, Cancel to cancel installation of Orange." /SD IDYES IDYES installsilently IDNO installpython
+					MessageBox MB_YESNO "Orange cannot run without Python.$\r$\nAbort the installation?" IDNO askpython
+						Quit
+			installsilently:
+				StrCpy $0 "/Qb-"
+			installpython:
+				File 3rdparty-${PYVER}\${PYFILENAME}
+				${If} $AdminInstall == 1
+					ExecWait 'msiexec.exe /i "$DESKTOP\${PYFILENAME}" ADDLOCAL=Extensions,Documentation,TclTk ALLUSERS=1 $0' $0
+				${Else}
+					ExecWait 'msiexec.exe /i "$DESKTOP\${PYFILENAME}" ADDLOCAL=Extensions,Documentation,TclTk $0' $0
+				${EndIf}
+				Delete "$DESKTOP\${PYFILENAME}"
+			!endif
+
+		!insertMacro GetPythonDir
+		StrCmp $PythonDir "" 0 have_python
+			MessageBox MB_OK "Python installation failed.$\r$\nOrange installation cannot continue."
+			Quit
+	have_python:
+
+
+		IfFileExists $PythonDir\lib\site-packages\PythonWin have_pythonwin
+			MessageBox MB_YESNO "Do you want to install PythonWin (recommended)?$\r$\n(Orange installation will continue afterwards.)" /SD IDYES IDNO have_pythonwin
+			IfFileExists "$SysDir\${MFC}" have_mfc
+				SetOutPath $SysDir
+				File various\${MFC}
+			have_mfc:
+			SetOutPath $DESKTOP
+			File 3rdparty-${PYVER}\${PYWINFILENAME}
+			ExecWait "$DESKTOP\${PYWINFILENAME}"
+			Delete "$DESKTOP\${PYWINFILENAME}"
+	have_pythonwin:
+
+
+		SetOutPath $PythonDir\lib\site-packages
+		IfFileExists $PythonDir\lib\site-packages\qt.py have_pyqt
+			File /r 3rdparty-${PYVER}\pyqt\*.*
+	have_pyqt:
+
+
+		IfFileExists $PythonDir\lib\site-packages\qwt\*.* have_pyqwt
+			File /r 3rdparty-${PYVER}\qwt
+	have_pyqwt:
+
+
+		IfFileExists $PythonDir\lib\site-packages\Numeric\*.* have_numeric
+			File /r 3rdparty-${PYVER}\numeric
+			File various\Numeric.pth
+	have_numeric:
+
+
+		IfFileExists $PythonDir\lib\site-packages\numpy\*.* have_numpy
+			File /r 3rdparty-${PYVER}\numpy
+	have_numpy:
+
+
+		IfFileExists "$PythonDir\lib\site-packages\qt-mt230nc.dll" have_qt
+		IfFileExists "$SysDir\qt-mt230nc.dll" have_qt
+			File various\qt-mt230nc.dll
+			SetOutPath $INSTDIR
+			File various\QT-LICENSE.txt
+		have_qt:
+
+SectionEnd
+!endif
+
+
+Section ""
+	ReadRegStr $0 HKCU "${SHELLFOLDERS}" AppData
+	StrCmp $0 "" 0 +2
+	  ReadRegStr $0 HKLM "${SHELLFOLDERS}" "Common AppData"
+	StrCmp $0 "" not_installed_before 0
+
+	IfFileExists "$0\Orange" 0 not_installed_before
+		ask_remove_old:
+		MessageBox MB_YESNOCANCEL "Another version of Orange has been found on the computer.$\r$\nDo you want to keep the existing settings for canvas and widgets?$\r$\n$\r$\nYou can usually safely answer 'Yes'; in case of problems, re-run this installation." /SD IDYES IDYES not_installed_before IDNO remove_old_settings
+			MessageBox MB_YESNO "Abort the installation?" IDNO ask_remove_old
+				Quit
+
+		remove_old_settings:
+		RmDir /R "$0\Orange"
+
+	not_installed_before:
+
+	StrCpy $INSTDIR  "$PythonDir\lib\site-packages\orange"
+	SetOutPath $INSTDIR
+	File "license.txt"
+
+	FileOpen $WhatsDownFile $INSTDIR\whatsdown.txt w
+    
+	!include ${INCLUDEPREFIX}_base.inc
+	!include ${INCLUDEPREFIX}_binaries.inc
+	!include ${INCLUDEPREFIX}_widgets.inc
+	!include ${INCLUDEPREFIX}_canvas.inc
+
+	SetOutPath $INSTDIR\icons
+	File Orange.ico
+	SetOutPath $INSTDIR\OrangeCanvas\icons
+	File OrangeOWS.ico
+
+   	!include ${INCLUDEPREFIX}_doc.inc
+
+	SetOutPath $INSTDIR\doc
+	File "various\Orange White Paper.pdf"
+	File "various\Orange Widgets White Paper.pdf"
+
+	SetOutPath $INSTDIR\doc\datasets
+	File ${ORANGEDIR}\doc\datasets\*
+
+	!ifdef INCLUDEGENOMICS
+		!include ${INCLUDEPREFIX}_genomics.inc
+	    
+		SetOutPath $INSTDIR\doc
+		File "various\Orange Genomics.pdf"
+	
+		SetOutPath $INSTDIR
+		CreateDirectory "$SMPROGRAMS\Orange"
+		CreateShortCut "$SMPROGRAMS\Orange\Orange Widgets For Functional Genomics.lnk" "$INSTDIR\doc\Orange Genomics.pdf"
+	
+		SetOutPath "$INSTDIR\OrangeCanvas"
+		File various\bi-visprog\*.tab
+		File various\bi-visprog\*.ows
+	!endif
+
+	!ifdef INCLUDETEXTMINING
+		SetOutPath $PythonDir\lib\site-packages
+		File E:\orange\download\snapshot\${PYVER}\lib\site-packages\orngText.pth