[#14 state:port] Changed the results export method to a pure python (and simpler) one.
--HG-- extra : convert_revision : svn%3Ac306627e-7827-47d3-bdf0-9a457c9553a1/trunk%40106
This commit is contained in:
parent
7112c57b92
commit
4eebc7bb2c
|
@ -20,7 +20,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
- (void)saveIgnoreList;
|
||||
- (void)clearIgnoreList;
|
||||
- (void)purgeIgnoreList;
|
||||
- (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds xslt:(NSString *)xsltPath css:(NSString *)cssPath;
|
||||
- (NSString *)exportToXHTMLwithColumns:(NSArray *)aColIds;
|
||||
|
||||
- (NSNumber *)doScan;
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
- (NSString *)logoImageName;
|
||||
|
||||
/* Helpers */
|
||||
- (NSArray *)getColumnsOrder;
|
||||
- (NSDictionary *)getColumnsWidth;
|
||||
- (NSArray *)getSelected:(BOOL)aDupesOnly;
|
||||
- (NSArray *)getSelectedPaths:(BOOL)aDupesOnly;
|
||||
- (void)updatePySelection;
|
||||
|
@ -48,6 +50,7 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
- (IBAction)copyMarked:(id)sender;
|
||||
- (IBAction)deleteMarked:(id)sender;
|
||||
- (IBAction)expandAll:(id)sender;
|
||||
- (IBAction)exportToXHTML:(id)sender;
|
||||
- (IBAction)moveMarked:(id)sender;
|
||||
- (IBAction)switchSelected:(id)sender;
|
||||
- (IBAction)togglePowerMarker:(id)sender;
|
||||
|
|
|
@ -75,6 +75,37 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
}
|
||||
|
||||
/* Helpers */
|
||||
//Returns an array of identifiers, in order.
|
||||
- (NSArray *)getColumnsOrder
|
||||
{
|
||||
NSTableColumn *col;
|
||||
NSString *colId;
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
|
||||
while (col = [e nextObject])
|
||||
{
|
||||
colId = [col identifier];
|
||||
[result addObject:colId];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSDictionary *)getColumnsWidth
|
||||
{
|
||||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||||
NSTableColumn *col;
|
||||
NSString *colId;
|
||||
NSNumber *width;
|
||||
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
|
||||
while (col = [e nextObject])
|
||||
{
|
||||
colId = [col identifier];
|
||||
width = [NSNumber numberWithFloat:[col width]];
|
||||
[result setObject:width forKey:colId];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSArray *)getSelected:(BOOL)aDupesOnly
|
||||
{
|
||||
if (_powerMode)
|
||||
|
@ -185,6 +216,12 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
[matches expandItem:[matches itemAtRow:i]];
|
||||
}
|
||||
|
||||
- (IBAction)exportToXHTML:(id)sender
|
||||
{
|
||||
NSString *exported = [py exportToXHTMLwithColumns:[self getColumnsOrder]];
|
||||
[[NSWorkspace sharedWorkspace] openFile:exported];
|
||||
}
|
||||
|
||||
- (IBAction)moveMarked:(id)sender
|
||||
{
|
||||
int mark_count = [[py getMarkCount] intValue];
|
||||
|
|
|
@ -19,7 +19,7 @@ from hsutil.reg import RegistrableApplication, RegistrationRequired
|
|||
from hsutil.misc import flatten, first
|
||||
from hsutil.str import escape
|
||||
|
||||
from . import directories, results, scanner
|
||||
from . import directories, results, scanner, export
|
||||
|
||||
JOB_SCAN = 'job_scan'
|
||||
JOB_LOAD = 'job_load'
|
||||
|
@ -177,6 +177,20 @@ class DupeGuru(RegistrableApplication):
|
|||
self._demo_check()
|
||||
self._start_job(JOB_DELETE, self._do_delete)
|
||||
|
||||
def export_to_xhtml(self, column_ids):
|
||||
column_ids = [colid for colid in column_ids if colid.isdigit()]
|
||||
column_ids = map(int, column_ids)
|
||||
column_ids.sort()
|
||||
colnames = [col['display'] for i, col in enumerate(self.data.COLUMNS) if i in column_ids]
|
||||
rows = []
|
||||
for group in self.results.groups:
|
||||
for dupe in group:
|
||||
data = self.data.GetDisplayInfo(dupe, group)
|
||||
row = [data[colid] for colid in column_ids]
|
||||
row.insert(0, dupe is not group.ref)
|
||||
rows.append(row)
|
||||
return export.export_to_xhtml(colnames, rows)
|
||||
|
||||
def load(self):
|
||||
self._start_job(JOB_LOAD, self._do_load)
|
||||
self.load_ignore_list()
|
||||
|
|
|
@ -17,7 +17,7 @@ from hsutil.cocoa import install_exception_hook
|
|||
from hsutil.misc import stripnone
|
||||
from hsutil.reg import RegistrationRequired
|
||||
|
||||
import export, app, data
|
||||
import app, data
|
||||
|
||||
JOBID2TITLE = {
|
||||
app.JOB_SCAN: "Scanning for duplicates",
|
||||
|
@ -116,16 +116,6 @@ class DupeGuru(app.DupeGuru):
|
|||
copy_or_move_marked = demo_method(app.DupeGuru.copy_or_move_marked)
|
||||
delete_marked = demo_method(app.DupeGuru.delete_marked)
|
||||
|
||||
def ExportToXHTML(self,column_ids,xslt_path,css_path):
|
||||
columns = []
|
||||
for index,column in enumerate(self.data.COLUMNS):
|
||||
display = column['display']
|
||||
enabled = str(index) in column_ids
|
||||
columns.append((display,enabled))
|
||||
xml_path = op.join(self.appdata,'results_export.xml')
|
||||
self.results.save_to_xml(xml_path,self.data.GetDisplayInfo)
|
||||
return export.export_to_xhtml(xml_path,xslt_path,css_path,columns)
|
||||
|
||||
def MakeSelectedReference(self):
|
||||
self.make_reference(self.selected_dupes)
|
||||
|
||||
|
|
|
@ -7,60 +7,132 @@
|
|||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from xml.dom import minidom
|
||||
import tempfile
|
||||
import os.path as op
|
||||
import os
|
||||
from StringIO import StringIO
|
||||
from tempfile import mkdtemp
|
||||
|
||||
from hsutil.files import FileOrPath
|
||||
# Yes, this is a very low-tech solution, but at least it doesn't have all these annoying dependency
|
||||
# and resource problems.
|
||||
|
||||
def output_column_xml(outfile, columns):
|
||||
"""Creates a xml file outfile with the supplied columns.
|
||||
|
||||
outfile can be a filename or a file object.
|
||||
columns is a list of 2 sized tuples (display,enabled)
|
||||
"""
|
||||
doc = minidom.Document()
|
||||
root = doc.appendChild(doc.createElement('columns'))
|
||||
for display,enabled in columns:
|
||||
col_node = root.appendChild(doc.createElement('column'))
|
||||
col_node.setAttribute('display', display)
|
||||
col_node.setAttribute('enabled', {True:'y',False:'n'}[enabled])
|
||||
with FileOrPath(outfile, 'wb') as fp:
|
||||
doc.writexml(fp, '\t','\t','\n', encoding='utf-8')
|
||||
MAIN_TEMPLATE = u"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
|
||||
<title>dupeGuru Results</title>
|
||||
<style type="text/css">
|
||||
BODY
|
||||
{
|
||||
background-color:white;
|
||||
}
|
||||
|
||||
def merge_css_into_xhtml(xhtml, css):
|
||||
with FileOrPath(xhtml, 'r+') as xhtml:
|
||||
with FileOrPath(css) as css:
|
||||
try:
|
||||
doc = minidom.parse(xhtml)
|
||||
except Exception:
|
||||
return False
|
||||
head = doc.getElementsByTagName('head')[0]
|
||||
links = head.getElementsByTagName('link')
|
||||
for link in links:
|
||||
if link.getAttribute('rel') == 'stylesheet':
|
||||
head.removeChild(link)
|
||||
style = head.appendChild(doc.createElement('style'))
|
||||
style.setAttribute('type','text/css')
|
||||
style.appendChild(doc.createTextNode(css.read()))
|
||||
xhtml.truncate(0)
|
||||
doc.writexml(xhtml, '\t','\t','\n', encoding='utf-8')
|
||||
xhtml.seek(0)
|
||||
return True
|
||||
BODY,A,P,UL,TABLE,TR,TD
|
||||
{
|
||||
font-family:Tahoma,Arial,sans-serif;
|
||||
font-size:10pt;
|
||||
color: #4477AA;
|
||||
}
|
||||
|
||||
def export_to_xhtml(xml, xslt, css, columns, cmd='xsltproc --path "%(folder)s" "%(xslt)s" "%(xml)s"'):
|
||||
folder = op.split(xml)[0]
|
||||
output_column_xml(op.join(folder,'columns.xml'),columns)
|
||||
html = StringIO()
|
||||
cmd = cmd % {'folder': folder, 'xslt': xslt, 'xml': xml}
|
||||
html.write(os.popen(cmd).read())
|
||||
html.seek(0)
|
||||
merge_css_into_xhtml(html,css)
|
||||
html.seek(0)
|
||||
html_path = op.join(folder,'export.htm')
|
||||
html_file = open(html_path,'w')
|
||||
html_file.write(html.read().encode('utf-8'))
|
||||
html_file.close()
|
||||
return html_path
|
||||
TABLE
|
||||
{
|
||||
background-color: #225588;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
TR
|
||||
{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
TH
|
||||
{
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
background-color: #C8D6E5;
|
||||
}
|
||||
|
||||
TH TD
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
|
||||
TD
|
||||
{
|
||||
padding-left: 2pt;
|
||||
}
|
||||
|
||||
TD.rightelem
|
||||
{
|
||||
text-align:right;
|
||||
/*padding-left:0pt;*/
|
||||
padding-right: 2pt;
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
TD.indented
|
||||
{
|
||||
padding-left: 12pt;
|
||||
}
|
||||
|
||||
H1
|
||||
{
|
||||
font-family:"Courier New",monospace;
|
||||
color:#6699CC;
|
||||
font-size:18pt;
|
||||
color:#6da500;
|
||||
border-color: #70A0CF;
|
||||
border-width: 1pt;
|
||||
border-style: solid;
|
||||
margin-top: 16pt;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
padding-top: 2pt;
|
||||
padding-bottom:2pt;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>dupeGuru Results</h1>
|
||||
<table>
|
||||
<tr>$colheaders</tr>
|
||||
$rows
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
COLHEADERS_TEMPLATE = u"<th>{name}</th>"
|
||||
|
||||
ROW_TEMPLATE = u"""
|
||||
<tr>
|
||||
<td class="{indented}">{filename}</td>{cells}
|
||||
</tr>
|
||||
"""
|
||||
|
||||
CELL_TEMPLATE = u"""<td>{value}</td>"""
|
||||
|
||||
def export_to_xhtml(colnames, rows):
|
||||
# a row is a list of values with the first value being a flag indicating if the row should be indented
|
||||
if rows:
|
||||
assert len(rows[0]) == len(colnames) + 1 # + 1 is for the "indented" flag
|
||||
colheaders = u''.join(COLHEADERS_TEMPLATE.format(name=name) for name in colnames)
|
||||
rendered_rows = []
|
||||
for row in rows:
|
||||
# [2:] is to remove the indented flag + filename
|
||||
indented = u'indented' if row[0] else u''
|
||||
filename = row[1]
|
||||
cells = u''.join(CELL_TEMPLATE.format(value=value) for value in row[2:])
|
||||
rendered_rows.append(ROW_TEMPLATE.format(indented=indented, filename=filename, cells=cells))
|
||||
rendered_rows = u''.join(rendered_rows)
|
||||
# The main template can't use format because the css code uses {}
|
||||
content = MAIN_TEMPLATE.replace('$colheaders', colheaders).replace('$rows', rendered_rows)
|
||||
folder = mkdtemp()
|
||||
destpath = op.join(folder, u'export.htm')
|
||||
fp = open(destpath, 'w')
|
||||
fp.write(content.encode('utf-8'))
|
||||
fp.close()
|
||||
return destpath
|
||||
|
|
|
@ -252,7 +252,7 @@ class Results(Markable):
|
|||
group.clean_matches()
|
||||
self.__dupes = None
|
||||
|
||||
def save_to_xml(self, outfile, with_data=False):
|
||||
def save_to_xml(self, outfile):
|
||||
self.apply_filter(None)
|
||||
outfile, must_close = open_if_filename(outfile, 'wb')
|
||||
writer = XMLGenerator(outfile, 'utf-8')
|
||||
|
@ -275,14 +275,6 @@ class Results(Markable):
|
|||
'marked': cond(self.is_marked(d), 'y', 'n')
|
||||
})
|
||||
writer.startElement('file', attrs)
|
||||
if with_data:
|
||||
data_list = self.data.GetDisplayInfo(d, g)
|
||||
for data in data_list:
|
||||
attrs = AttributesImpl({
|
||||
'value': data,
|
||||
})
|
||||
writer.startElement('data', attrs)
|
||||
writer.endElement('data')
|
||||
writer.endElement('file')
|
||||
for match in g.matches:
|
||||
attrs = AttributesImpl({
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
# Created By: Virgil Dupras
|
||||
# Created On: 2006/09/16
|
||||
# $Id$
|
||||
# Copyright 2009 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/hs_license
|
||||
|
||||
from xml.dom import minidom
|
||||
from StringIO import StringIO
|
||||
|
||||
from hsutil.testcase import TestCase
|
||||
|
||||
from .. import export
|
||||
from ..export import *
|
||||
|
||||
class TCoutput_columns_xml(TestCase):
|
||||
def test_empty_columns(self):
|
||||
f = StringIO()
|
||||
output_column_xml(f,[])
|
||||
f.seek(0)
|
||||
doc = minidom.parse(f)
|
||||
root = doc.documentElement
|
||||
self.assertEqual('columns',root.nodeName)
|
||||
self.assertEqual(0,len(root.childNodes))
|
||||
|
||||
def test_some_columns(self):
|
||||
f = StringIO()
|
||||
output_column_xml(f,[('foo',True),('bar',False),('baz',True)])
|
||||
f.seek(0)
|
||||
doc = minidom.parse(f)
|
||||
columns = doc.getElementsByTagName('column')
|
||||
self.assertEqual(3,len(columns))
|
||||
c1,c2,c3 = columns
|
||||
self.assertEqual('foo',c1.getAttribute('display'))
|
||||
self.assertEqual('bar',c2.getAttribute('display'))
|
||||
self.assertEqual('baz',c3.getAttribute('display'))
|
||||
self.assertEqual('y',c1.getAttribute('enabled'))
|
||||
self.assertEqual('n',c2.getAttribute('enabled'))
|
||||
self.assertEqual('y',c3.getAttribute('enabled'))
|
||||
|
||||
|
||||
class TCmerge_css_into_xhtml(TestCase):
|
||||
def test_main(self):
|
||||
css = StringIO()
|
||||
css.write('foobar')
|
||||
css.seek(0)
|
||||
xhtml = StringIO()
|
||||
xhtml.write("""<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>dupeGuru - Duplicate file scanner</title>
|
||||
<link rel="SHORTCUT ICON" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="../hardcoded.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>""")
|
||||
xhtml.seek(0)
|
||||
self.assert_(merge_css_into_xhtml(xhtml,css))
|
||||
xhtml.seek(0)
|
||||
doc = minidom.parse(xhtml)
|
||||
head = doc.getElementsByTagName('head')[0]
|
||||
#A style node should have been added in head.
|
||||
styles = head.getElementsByTagName('style')
|
||||
self.assertEqual(1,len(styles))
|
||||
style = styles[0]
|
||||
self.assertEqual('text/css',style.getAttribute('type'))
|
||||
self.assertEqual('foobar',style.firstChild.nodeValue.strip())
|
||||
#all <link rel="stylesheet"> should be removed
|
||||
self.assertEqual(1,len(head.getElementsByTagName('link')))
|
||||
|
||||
def test_empty(self):
|
||||
self.assert_(not merge_css_into_xhtml(StringIO(),StringIO()))
|
||||
|
||||
def test_malformed(self):
|
||||
xhtml = StringIO()
|
||||
xhtml.write("""<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">""")
|
||||
xhtml.seek(0)
|
||||
self.assert_(not merge_css_into_xhtml(xhtml,StringIO()))
|
||||
|
|
@ -395,30 +395,6 @@ class TCResultsXML(TestCase):
|
|||
self.assertEqual('ibabtu',d1.getAttributeNode('words').nodeValue)
|
||||
self.assertEqual('ibabtu',d2.getAttributeNode('words').nodeValue)
|
||||
|
||||
def test_save_to_xml_with_columns(self):
|
||||
class FakeDataModule:
|
||||
def GetDisplayInfo(self,dupe,group):
|
||||
return [str(dupe.size),dupe.foo.upper()]
|
||||
|
||||
for i,object in enumerate(self.objects):
|
||||
object.size = i
|
||||
object.foo = u'bar\u00e9'
|
||||
f = StringIO.StringIO()
|
||||
self.results.data = FakeDataModule()
|
||||
self.results.save_to_xml(f,True)
|
||||
f.seek(0)
|
||||
doc = xml.dom.minidom.parse(f)
|
||||
root = doc.documentElement
|
||||
g1,g2 = root.getElementsByTagName('group')
|
||||
d1,d2,d3 = g1.getElementsByTagName('file')
|
||||
d4,d5 = g2.getElementsByTagName('file')
|
||||
self.assertEqual('0',d1.getElementsByTagName('data')[0].getAttribute('value'))
|
||||
self.assertEqual(u'BAR\u00c9',d1.getElementsByTagName('data')[1].getAttribute('value')) #\u00c9 is upper of \u00e9
|
||||
self.assertEqual('1',d2.getElementsByTagName('data')[0].getAttribute('value'))
|
||||
self.assertEqual('2',d3.getElementsByTagName('data')[0].getAttribute('value'))
|
||||
self.assertEqual('3',d4.getElementsByTagName('data')[0].getAttribute('value'))
|
||||
self.assertEqual('4',d5.getElementsByTagName('data')[0].getAttribute('value'))
|
||||
|
||||
def test_LoadXML(self):
|
||||
def get_file(path):
|
||||
return [f for f in self.objects if str(f.path) == path][0]
|
||||
|
|
|
@ -25,7 +25,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
NSMutableIndexSet *_deltaColumns;
|
||||
}
|
||||
- (IBAction)clearIgnoreList:(id)sender;
|
||||
- (IBAction)exportToXHTML:(id)sender;
|
||||
- (IBAction)filter:(id)sender;
|
||||
- (IBAction)ignoreSelected:(id)sender;
|
||||
- (IBAction)markAll:(id)sender;
|
||||
|
@ -47,8 +46,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
- (IBAction)toggleDetailsPanel:(id)sender;
|
||||
|
||||
- (NSTableColumn *)getColumnForIdentifier:(int)aIdentifier title:(NSString *)aTitle width:(int)aWidth refCol:(NSTableColumn *)aColumn;
|
||||
- (NSArray *)getColumnsOrder;
|
||||
- (NSDictionary *)getColumnsWidth;
|
||||
- (void)initResultColumns;
|
||||
- (void)restoreColumnsPosition:(NSArray *)aColumnsOrder widths:(NSDictionary *)aColumnsWidth;
|
||||
@end
|
||||
|
|
|
@ -58,14 +58,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
[py clearIgnoreList];
|
||||
}
|
||||
|
||||
- (IBAction)exportToXHTML:(id)sender
|
||||
{
|
||||
NSString *xsltPath = [[NSBundle mainBundle] pathForResource:@"dg" ofType:@"xsl"];
|
||||
NSString *cssPath = [[NSBundle mainBundle] pathForResource:@"hardcoded" ofType:@"css"];
|
||||
NSString *exported = [py exportToXHTMLwithColumns:[self getColumnsOrder] xslt:xsltPath css:cssPath];
|
||||
[[NSWorkspace sharedWorkspace] openFile:exported];
|
||||
}
|
||||
|
||||
- (IBAction)filter:(id)sender
|
||||
{
|
||||
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
|
||||
|
@ -272,37 +264,6 @@ http://www.hardcoded.net/licenses/hs_license
|
|||
return col;
|
||||
}
|
||||
|
||||
//Returns an array of identifiers, in order.
|
||||
- (NSArray *)getColumnsOrder
|
||||
{
|
||||
NSTableColumn *col;
|
||||
NSString *colId;
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
|
||||
while (col = [e nextObject])
|
||||
{
|
||||
colId = [col identifier];
|
||||
[result addObject:colId];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSDictionary *)getColumnsWidth
|
||||
{
|
||||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||||
NSTableColumn *col;
|
||||
NSString *colId;
|
||||
NSNumber *width;
|
||||
NSEnumerator *e = [[matches tableColumns] objectEnumerator];
|
||||
while (col = [e nextObject])
|
||||
{
|
||||
colId = [col identifier];
|
||||
width = [NSNumber numberWithFloat:[col width]];
|
||||
[result setObject:width forKey:colId];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
- (void)initResultColumns
|
||||
{
|
||||
NSTableColumn *refCol = [matches tableColumnWithIdentifier:@"0"];
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||
CE073F6309CAE1A3005C1D2F /* dupeguru_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_help */; };
|
||||
CE0D67640ABC2D3E00E2FFD9 /* dg.xsl in Resources */ = {isa = PBXBuildFile; fileRef = CE0D67620ABC2D3E00E2FFD9 /* dg.xsl */; };
|
||||
CE0D67650ABC2D3E00E2FFD9 /* hardcoded.css in Resources */ = {isa = PBXBuildFile; fileRef = CE0D67630ABC2D3E00E2FFD9 /* hardcoded.css */; };
|
||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
||||
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9A09914ADF003581CE /* ResultWindow.m */; };
|
||||
CE381D0509915304003581CE /* dg_cocoa.plugin in Resources */ = {isa = PBXBuildFile; fileRef = CE381CF509915304003581CE /* dg_cocoa.plugin */; };
|
||||
|
@ -77,8 +75,6 @@
|
|||
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
8D1107320486CEB800E47090 /* dupeGuru.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = dupeGuru.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CE073F5409CAE1A3005C1D2F /* dupeguru_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_help; path = help/dupeguru_help; sourceTree = "<group>"; };
|
||||
CE0D67620ABC2D3E00E2FFD9 /* dg.xsl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; name = dg.xsl; path = w3/dg.xsl; sourceTree = SOURCE_ROOT; };
|
||||
CE0D67630ABC2D3E00E2FFD9 /* hardcoded.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = hardcoded.css; path = w3/hardcoded.css; sourceTree = SOURCE_ROOT; };
|
||||
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||
CE381C9A09914ADF003581CE /* ResultWindow.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = ResultWindow.m; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -215,7 +211,6 @@
|
|||
CE073F5409CAE1A3005C1D2F /* dupeguru_help */,
|
||||
CE381CF509915304003581CE /* dg_cocoa.plugin */,
|
||||
CEFC294309C89E0000D9F998 /* images */,
|
||||
CE0D67610ABC2D3E00E2FFD9 /* w3 */,
|
||||
CEEB135109C837A2004D2330 /* dupeguru.icns */,
|
||||
8D1107310486CEB800E47090 /* Info.plist */,
|
||||
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
|
||||
|
@ -235,15 +230,6 @@
|
|||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CE0D67610ABC2D3E00E2FFD9 /* w3 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE0D67620ABC2D3E00E2FFD9 /* dg.xsl */,
|
||||
CE0D67630ABC2D3E00E2FFD9 /* hardcoded.css */,
|
||||
);
|
||||
path = w3;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CEDD92D50FDD01640031C7B7 /* brsinglelineformatter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -375,8 +361,6 @@
|
|||
CEF7823809C8AA0200EF38FF /* gear.png in Resources */,
|
||||
CECA899909DB12CA00A3D774 /* Details.nib in Resources */,
|
||||
CE3AA46709DB207900DB3A21 /* Directories.nib in Resources */,
|
||||
CE0D67640ABC2D3E00E2FFD9 /* dg.xsl in Resources */,
|
||||
CE0D67650ABC2D3E00E2FFD9 /* hardcoded.css in Resources */,
|
||||
CEFC7FAD0FC9518A00CD5728 /* ErrorReportWindow.xib in Resources */,
|
||||
CEFC7FAE0FC9518A00CD5728 /* progress.nib in Resources */,
|
||||
CEFC7FAF0FC9518A00CD5728 /* registration.nib in Resources */,
|
||||
|
@ -534,12 +518,11 @@
|
|||
C01FCF5008A954540054247B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = (
|
||||
ppc,
|
||||
i386,
|
||||
);
|
||||
ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
|
||||
ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
|
||||
FRAMEWORK_SEARCH_PATHS = "@executable_path/../Frameworks";
|
||||
GCC_C_LANGUAGE_STANDARD = c99;
|
||||
GCC_VERSION = 4.0;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.4;
|
||||
|
|
|
@ -41,8 +41,8 @@ class PyDupeGuru(PyApp):
|
|||
def doScan(self):
|
||||
return self.app.start_scanning()
|
||||
|
||||
def exportToXHTMLwithColumns_xslt_css_(self,column_ids,xslt_path,css_path):
|
||||
return self.app.ExportToXHTML(column_ids,xslt_path,css_path)
|
||||
def exportToXHTMLwithColumns_(self, column_ids):
|
||||
return self.app.export_to_xhtml(column_ids)
|
||||
|
||||
def loadIgnoreList(self):
|
||||
self.app.load_ignore_list()
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
|
||||
<xsl:output
|
||||
method="xml"
|
||||
encoding="utf-8"
|
||||
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
|
||||
indent="yes"/>
|
||||
|
||||
<xsl:template match="column">
|
||||
<xsl:if test="@enabled = 'y'">
|
||||
<th>
|
||||
<xsl:value-of select="@display"/>
|
||||
</th>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="file">
|
||||
<tr>
|
||||
<xsl:variable name="td_class">
|
||||
<xsl:if test="position() > 1">
|
||||
<xsl:text>indented</xsl:text>
|
||||
</xsl:if>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="file_node" select="."/>
|
||||
<xsl:for-each select="data">
|
||||
<xsl:variable name="data_pos" select="position()"/>
|
||||
<xsl:if test="document('columns.xml')/columns/column[$data_pos]/@enabled = 'y'">
|
||||
<td>
|
||||
<xsl:if test="position() = 1">
|
||||
<xsl:attribute name="class">
|
||||
<xsl:value-of select="$td_class"/>
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="@value"/>
|
||||
</td>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<!-- <xsl:for-each select="//results/column">
|
||||
<td>
|
||||
<xsl:variable name="attr_name">
|
||||
<xsl:text>attr_</xsl:text>
|
||||
<xsl:value-of select="@name"/>
|
||||
</xsl:variable>
|
||||
<xsl:value-of select="$file_node/@*[local-name(.) = $attr_name]"/>
|
||||
</td>
|
||||
</xsl:for-each> -->
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="group">
|
||||
<xsl:apply-templates select="file"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="results">
|
||||
<html>
|
||||
<head>
|
||||
<title>dupeGuru Results</title>
|
||||
<link rel="stylesheet" href="hardcoded.css" type="text/css"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1>dupeGuru Results</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<xsl:apply-templates select="document('columns.xml')/columns/column"/>
|
||||
</tr>
|
||||
<xsl:apply-templates select="group"/>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -1,71 +0,0 @@
|
|||
BODY
|
||||
{
|
||||
background-color:white;
|
||||
}
|
||||
|
||||
BODY,A,P,UL,TABLE,TR,TD
|
||||
{
|
||||
font-family:Tahoma,Arial,sans-serif;
|
||||
font-size:10pt;
|
||||
color: #4477AA;
|
||||
}
|
||||
|
||||
TABLE
|
||||
{
|
||||
background-color: #225588;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
TR
|
||||
{
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
TH
|
||||
{
|
||||
font-weight: bold;
|
||||
color: black;
|
||||
background-color: #C8D6E5;
|
||||
}
|
||||
|
||||
TH TD
|
||||
{
|
||||
color:black;
|
||||
}
|
||||
|
||||
TD
|
||||
{
|
||||
padding-left: 2pt;
|
||||
}
|
||||
|
||||
TD.rightelem
|
||||
{
|
||||
text-align:right;
|
||||
/*padding-left:0pt;*/
|
||||
padding-right: 2pt;
|
||||
width: 17%;
|
||||
}
|
||||
|
||||
TD.indented
|
||||
{
|
||||
padding-left: 12pt;
|
||||
}
|
||||
|
||||
H1
|
||||
{
|
||||
font-family:"Courier New",monospace;
|
||||
color:#6699CC;
|
||||
font-size:18pt;
|
||||
color:#6da500;
|
||||
border-color: #70A0CF;
|
||||
border-width: 1pt;
|
||||
border-style: solid;
|
||||
margin-top: 16pt;
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
padding-top: 2pt;
|
||||
padding-bottom:2pt;
|
||||
text-align: center;
|
||||
}
|
Loading…
Reference in New Issue