Implement printing

This commit is contained in:
Matthias Neeracher 2015-03-16 05:39:09 +01:00 committed by Matthias Neeracher
parent 61ef712df4
commit 30652c5627
6 changed files with 243 additions and 17 deletions

View File

@ -16,6 +16,7 @@
950AB9271A296A160033A9DA /* ProjIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 950AB9261A296A160033A9DA /* ProjIcon.icns */; }; 950AB9271A296A160033A9DA /* ProjIcon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 950AB9261A296A160033A9DA /* ProjIcon.icns */; };
951CD1741A23C9FC0066C1A1 /* ASBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */; }; 951CD1741A23C9FC0066C1A1 /* ASBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */; };
951CD1771A2615000066C1A1 /* BuildProject in Resources */ = {isa = PBXBuildFile; fileRef = 951CD1761A2615000066C1A1 /* BuildProject */; }; 951CD1771A2615000066C1A1 /* BuildProject in Resources */ = {isa = PBXBuildFile; fileRef = 951CD1761A2615000066C1A1 /* BuildProject */; };
95388E5D1AB6882600061435 /* FileRevision in Resources */ = {isa = PBXBuildFile; fileRef = 95388E5C1AB6882600061435 /* FileRevision */; };
9538E0EC1A8FB215001E02CC /* ACEView.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 95EA325B1A17B8DA00F66EB0 /* ACEView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 9538E0EC1A8FB215001E02CC /* ACEView.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 95EA325B1A17B8DA00F66EB0 /* ACEView.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
95468DDF1A228BE600668EE2 /* ASHardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95468DDE1A228BE600668EE2 /* ASHardware.swift */; }; 95468DDF1A228BE600668EE2 /* ASHardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95468DDE1A228BE600668EE2 /* ASHardware.swift */; };
95468DE31A228E1300668EE2 /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 95468DE21A228E1300668EE2 /* Defaults.plist */; }; 95468DE31A228E1300668EE2 /* Defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 95468DE21A228E1300668EE2 /* Defaults.plist */; };
@ -102,6 +103,7 @@
950AB9261A296A160033A9DA /* ProjIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ProjIcon.icns; path = IconResources/ProjIcon.icns; sourceTree = "<group>"; }; 950AB9261A296A160033A9DA /* ProjIcon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ProjIcon.icns; path = IconResources/ProjIcon.icns; sourceTree = "<group>"; };
951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASBuilder.swift; sourceTree = "<group>"; }; 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASBuilder.swift; sourceTree = "<group>"; };
951CD1761A2615000066C1A1 /* BuildProject */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = BuildProject; sourceTree = "<group>"; }; 951CD1761A2615000066C1A1 /* BuildProject */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = BuildProject; sourceTree = "<group>"; };
95388E5C1AB6882600061435 /* FileRevision */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; path = FileRevision; sourceTree = "<group>"; };
95468DDE1A228BE600668EE2 /* ASHardware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASHardware.swift; sourceTree = "<group>"; }; 95468DDE1A228BE600668EE2 /* ASHardware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ASHardware.swift; sourceTree = "<group>"; };
95468DE21A228E1300668EE2 /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = "<group>"; }; 95468DE21A228E1300668EE2 /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = "<group>"; };
95539B661A3E7EAF00D8595C /* ASSerial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSerial.h; sourceTree = "<group>"; }; 95539B661A3E7EAF00D8595C /* ASSerial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASSerial.h; sourceTree = "<group>"; };
@ -211,6 +213,7 @@
951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */, 951CD1731A23C9FC0066C1A1 /* ASBuilder.swift */,
95A7C6451A3894C900EF1963 /* ASPreferences.swift */, 95A7C6451A3894C900EF1963 /* ASPreferences.swift */,
951CD1761A2615000066C1A1 /* BuildProject */, 951CD1761A2615000066C1A1 /* BuildProject */,
95388E5C1AB6882600061435 /* FileRevision */,
95539B661A3E7EAF00D8595C /* ASSerial.h */, 95539B661A3E7EAF00D8595C /* ASSerial.h */,
95539B671A3E7EAF00D8595C /* ASSerial.mm */, 95539B671A3E7EAF00D8595C /* ASSerial.mm */,
95DF20661A45A6090013D1B5 /* ASSketchBook.swift */, 95DF20661A45A6090013D1B5 /* ASSketchBook.swift */,
@ -305,6 +308,7 @@
9501D7F41A17025C0034C530 /* Project object */ = { 9501D7F41A17025C0034C530 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0630; LastUpgradeCheck = 0630;
ORGANIZATIONNAME = "Aere Perennius"; ORGANIZATIONNAME = "Aere Perennius";
TargetAttributes = { TargetAttributes = {
@ -383,6 +387,7 @@
95CC3F071A6385B8003507AD /* CSrcIcon.icns in Resources */, 95CC3F071A6385B8003507AD /* CSrcIcon.icns in Resources */,
951CD1771A2615000066C1A1 /* BuildProject in Resources */, 951CD1771A2615000066C1A1 /* BuildProject in Resources */,
95CC3F081A6385B8003507AD /* HSrcIcon.icns in Resources */, 95CC3F081A6385B8003507AD /* HSrcIcon.icns in Resources */,
95388E5D1AB6882600061435 /* FileRevision in Resources */,
95CC3F061A6385B8003507AD /* CppSrcIcon.icns in Resources */, 95CC3F061A6385B8003507AD /* CppSrcIcon.icns in Resources */,
95CC3F051A6385B8003507AD /* AsmSrcIcon.icns in Resources */, 95CC3F051A6385B8003507AD /* AsmSrcIcon.icns in Resources */,
); );

View File

@ -1,11 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "0630" LastUpgradeVersion = "0700"
version = "1.8"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"
buildImplicitDependencies = "YES" buildImplicitDependencies = "YES">
enableAddressSanitizer = "NO">
<BuildActionEntries> <BuildActionEntries>
<BuildActionEntry <BuildActionEntry
buildForTesting = "YES" buildForTesting = "YES"
@ -85,6 +84,11 @@
</BuildableReference> </BuildableReference>
</BuildableProductRunnable> </BuildableProductRunnable>
<AdditionalOptions> <AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions> </AdditionalOptions>
</LaunchAction> </LaunchAction>
<ProfileAction <ProfileAction

View File

@ -60,6 +60,12 @@ private let kNameKey = "Name"
// exposed to ObjC APIs. As a workaround, we declare this hierarchy @objc // exposed to ObjC APIs. As a workaround, we declare this hierarchy @objc
// //
@objc class ASFileNode { @objc class ASFileNode {
var name : String
init(name: String) {
self.name = name
}
func nodeName() -> String { func nodeName() -> String {
return "" return ""
} }
@ -87,23 +93,33 @@ private let kNameKey = "Name"
func exists() -> Bool { func exists() -> Bool {
return true return true
} }
func modDate() -> NSDate? {
return nil;
}
func revision() -> String? {
return nil;
}
} }
class ASLogNode : ASFileNode { class ASLogNode : ASFileNode {
var name : String
var path : String var path : String
init(name: String, path: String) { init(name: String, path: String) {
self.name = name
self.path = path self.path = path
super.init(name: name)
} }
override func nodeName() -> String { override func nodeName() -> String {
return "📜 "+name return "📜 "+name
} }
override func modDate() -> NSDate? {
let url = NSURL(fileURLWithPath: path)
var date: AnyObject?
url?.getResourceValue(&date, forKey: NSURLContentModificationDateKey, error: nil)
return date as? NSDate
}
} }
class ASFileGroup : ASFileNode { class ASFileGroup : ASFileNode {
var name : String
var children : [ASFileNode] var children : [ASFileNode]
var expanded : Bool var expanded : Bool
@ -111,18 +127,18 @@ class ASFileGroup : ASFileNode {
private let kExpandedKey = "Expanded" private let kExpandedKey = "Expanded"
private var kNodeType : String { return kNodeTypeGroup } private var kNodeType : String { return kNodeTypeGroup }
init(name: String = "") { override init(name: String = "") {
self.name = name
self.children = [] self.children = []
self.expanded = true self.expanded = true
super.init(name: name)
} }
init(_ prop: NSDictionary, withRootURL rootURL: NSURL) { init(_ prop: NSDictionary, withRootURL rootURL: NSURL) {
name = prop[kNameKey] as! String
expanded = prop[kExpandedKey] as! Bool expanded = prop[kExpandedKey] as! Bool
children = [] children = []
for child in (prop[kChildrenKey] as! [NSDictionary]) { for child in (prop[kChildrenKey] as! [NSDictionary]) {
children.append(ASFileNode.readPropertyList(child, rootURL: rootURL)) children.append(ASFileNode.readPropertyList(child, rootURL: rootURL))
} }
super.init(name: prop[kNameKey] as! String)
} }
override func nodeName() -> String { override func nodeName() -> String {
return (expanded ? "📂" : "📁")+" "+name return (expanded ? "📂" : "📁")+" "+name
@ -167,6 +183,7 @@ class ASFileItem : ASFileNode {
init(url: NSURL, type: ASFileType) { init(url: NSURL, type: ASFileType) {
self.url = url self.url = url
self.type = type self.type = type
super.init(name:url.lastPathComponent!)
} }
init(_ prop: NSDictionary, withRootURL rootURL: NSURL) { init(_ prop: NSDictionary, withRootURL rootURL: NSURL) {
type = ASFileType(rawValue: prop[kKindKey] as! String)! type = ASFileType(rawValue: prop[kKindKey] as! String)!
@ -175,9 +192,10 @@ class ASFileItem : ASFileNode {
} else { } else {
url = NSURL(fileURLWithPath:(prop[kPathKey] as! String))!.URLByStandardizingPath! url = NSURL(fileURLWithPath:(prop[kPathKey] as! String))!.URLByStandardizingPath!
} }
super.init(name:url.lastPathComponent!)
} }
override func nodeName() -> String { override func nodeName() -> String {
return "📄 "+url.lastPathComponent! return "📄 "+name
} }
func relativePath(relativeTo: String) -> String { func relativePath(relativeTo: String) -> String {
@ -211,6 +229,23 @@ class ASFileItem : ASFileNode {
override func exists() -> Bool { override func exists() -> Bool {
return url.checkResourceIsReachableAndReturnError(nil) return url.checkResourceIsReachableAndReturnError(nil)
} }
override func modDate() -> NSDate? {
var date: AnyObject?
url.getResourceValue(&date, forKey: NSURLContentModificationDateKey, error: nil)
return date as? NSDate
}
override func revision() -> String? {
let task = NSTask()
task.launchPath = NSBundle.mainBundle().pathForResource("FileRevision", ofType: "")!
let outputPipe = NSPipe()
task.standardOutput = outputPipe
task.standardError = NSFileHandle.fileHandleWithNullDevice()
task.arguments = [url.path!]
task.launch()
return NSString(data: outputPipe.fileHandleForReading.readDataToEndOfFile(),
encoding: NSUTF8StringEncoding) as? String
}
} }
class ASFileTree : NSObject, NSOutlineViewDataSource { class ASFileTree : NSObject, NSOutlineViewDataSource {

View File

@ -26,7 +26,7 @@ func pushToFront(inout list: [String], front: String) {
list.insert(front, atIndex: 0) list.insert(front, atIndex: 0)
} }
class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePanelDelegate { class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePanelDelegate, ACEViewDelegate {
@IBOutlet weak var editor : ACEView! @IBOutlet weak var editor : ACEView!
@IBOutlet weak var outline : NSOutlineView! @IBOutlet weak var outline : NSOutlineView!
@IBOutlet weak var boardTool: NSPopUpButton! @IBOutlet weak var boardTool: NSPopUpButton!
@ -49,7 +49,10 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
var logModified = NSDate.distantPast() as! NSDate var logModified = NSDate.distantPast() as! NSDate
var logSize = 0 var logSize = 0
var updateLogTimer : NSTimer? var updateLogTimer : NSTimer?
var printingDone : () -> () = {}
var printModDate : NSDate?
var printRevision : String?
let kVersionKey = "Version" let kVersionKey = "Version"
let kCurVersion = 1.0 let kCurVersion = 1.0
let kFilesKey = "Files" let kFilesKey = "Files"
@ -107,6 +110,8 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
editor.setTheme(currentTheme) editor.setTheme(currentTheme)
editor.setKeyboardHandler(keyboardHandler) editor.setKeyboardHandler(keyboardHandler)
editor.setFontSize(fontSize) editor.setFontSize(fontSize)
editor.delegate = self
outline.setDataSource(files) outline.setDataSource(files)
files.apply() { node in files.apply() { node in
if let group = node as? ASFileGroup { if let group = node as? ASFileGroup {
@ -277,8 +282,147 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate, NSOpenSavePa
// MARK: Printing // MARK: Printing
override func printDocument(sender: AnyObject?) { override func printDocumentWithSettings(printSettings: [NSObject : AnyObject], showPrintPanel: Bool, delegate: AnyObject?, didPrintSelector: Selector, contextInfo: UnsafeMutablePointer<Void>) {
editor.print(sender) //
// Thanks to Erica Sadun for showing me how to call a selector in Swift
//
printingDone =
{ () -> () in
if let del : AnyObject = delegate {
NSThread.detachNewThreadSelector(didPrintSelector, toTarget: del, withObject: contextInfo as? AnyObject)
}
}
printModDate = mainEditor?.modDate()
printRevision = mainEditor?.revision()
editor.print(self)
}
func printSettings() -> NSPrintInfo! {
var info = printInfo.copy() as! NSPrintInfo
//
// Minimize margins
//
let kXMargin : CGFloat = 50.0
let kYMargin : CGFloat = 50.0
let paperSize = info.paperSize
var maxBounds = info.imageablePageBounds
if paperSize.width - maxBounds.size.width < kXMargin {
let adjust = kXMargin-paperSize.width+maxBounds.size.width
maxBounds.origin.x += 0.5*adjust
maxBounds.size.width -= adjust
}
if paperSize.height - maxBounds.size.height < kYMargin {
let adjust = kYMargin-paperSize.height+maxBounds.size.height
maxBounds.origin.y += 0.5*adjust
maxBounds.size.height -= adjust
}
info.leftMargin = maxBounds.origin.x
info.bottomMargin = maxBounds.origin.y
info.topMargin = paperSize.height-maxBounds.size.height-info.bottomMargin
info.rightMargin = paperSize.width-maxBounds.size.width-info.leftMargin
return info
}
func printJobTitle() -> String! {
return mainEditor?.nodeName() ??
fileURL?.lastPathComponent?.stringByDeletingPathExtension ??
"Untitled"
}
func printHeaderHeight() -> Float {
return 41.0
}
func printFooterHeight() -> Float {
return 20.0
}
func drawPrintHeaderForPage(pageNo: Int32, inRect r: NSRect) {
var rect = r
rect.origin.y += 5.0
rect.size.height -= 5.0
let ctx = NSGraphicsContext.currentContext()!
ctx.saveGraphicsState()
NSColor(white: 0.95, alpha: 1.0).setFill()
var wideBox = rect
wideBox.size.height = 20.0
wideBox.origin.y += 0.5*(rect.size.height-wideBox.size.height)
NSRectFill(wideBox)
NSColor(white: 0.7, alpha: 1.0).setFill()
var pageNoBox = rect
pageNoBox.size.width = 50.0
pageNoBox.origin.x += 0.5*(rect.size.width-pageNoBox.size.width)
NSRectFill(pageNoBox)
ctx.restoreGraphicsState()
let pageNoFont = NSFont.userFixedPitchFontOfSize(25.0)!
let pageNoAttr = [
NSFontAttributeName: pageNoFont,
NSForegroundColorAttributeName: NSColor.whiteColor(),
NSStrokeWidthAttributeName: -5.0]
let pageNoStr = "\(pageNo)"
let pageNoSize = pageNoStr.sizeWithAttributes(pageNoAttr)
let pageNoAt = NSPoint(
x: pageNoBox.origin.x+0.5*(pageNoBox.size.width-pageNoSize.width),
y: pageNoBox.origin.y+3.5)
pageNoStr.drawAtPoint(pageNoAt, withAttributes:pageNoAttr)
let kXOffset : CGFloat = 5.0
let titleFont = NSFont.userFontOfSize(12.0)!
let titleAttr = [NSFontAttributeName:titleFont]
var titleAt = NSPoint(
x: wideBox.origin.x+kXOffset,
y: wideBox.origin.y+0.5*(wideBox.size.height-titleFont.ascender+titleFont.descender))
if let fileNameStr = mainEditor?.name {
fileNameStr.drawAtPoint(titleAt, withAttributes:titleAttr)
}
if let projectNameStr = fileURL?.lastPathComponent?.stringByDeletingPathExtension {
let projectNameSize = projectNameStr.sizeWithAttributes(titleAttr)
titleAt.x = wideBox.origin.x+wideBox.size.width-projectNameSize.width-kXOffset
projectNameStr.drawAtPoint(titleAt, withAttributes:titleAttr)
}
}
func drawPrintFooterForPage(pageNo: Int32, inRect r: NSRect) {
var rect = r
rect.size.height -= 5.0
let ctx = NSGraphicsContext.currentContext()!
ctx.saveGraphicsState()
NSColor(white: 0.95, alpha: 1.0).setFill()
NSRectFill(rect)
ctx.restoreGraphicsState()
let kXOffset : CGFloat = 5.0
let footFont = NSFont.userFixedPitchFontOfSize(10.0)!
let footAttr = [NSFontAttributeName:footFont]
var footAt = NSPoint(
x: rect.origin.x+kXOffset,
y: rect.origin.y+0.5*(rect.size.height-footFont.ascender+footFont.descender))
if let revisionStr = printRevision {
revisionStr.drawAtPoint(footAt, withAttributes:footAttr)
}
if let modDate = printModDate
{
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let modDateStr = dateFormatter.stringFromDate(modDate)
let modDateSize = modDateStr.sizeWithAttributes(footAttr)
footAt.x = rect.origin.x+rect.size.width-modDateSize.width-kXOffset
modDateStr.drawAtPoint(footAt, withAttributes:footAttr)
}
}
func printingComplete() {
printingDone()
} }
// MARK: Outline View Delegate // MARK: Outline View Delegate

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7515.2" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7519.1" systemVersion="14C109" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7515.2"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7519.1"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/> <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies> </dependencies>
<objects> <objects>
@ -11,6 +11,7 @@
<outlet property="editor" destination="Nhg-qn-6A8" id="eUR-Gk-IBw"/> <outlet property="editor" destination="Nhg-qn-6A8" id="eUR-Gk-IBw"/>
<outlet property="outline" destination="nij-C2-Fna" id="sVi-eL-hqZ"/> <outlet property="outline" destination="nij-C2-Fna" id="sVi-eL-hqZ"/>
<outlet property="portTool" destination="4rZ-U5-AH6" id="8Nb-iI-pJH"/> <outlet property="portTool" destination="4rZ-U5-AH6" id="8Nb-iI-pJH"/>
<outlet property="printView" destination="HFe-2c-jeW" id="dh0-q5-QVW"/>
<outlet property="progTool" destination="08n-xg-fNl" id="959-as-OtP"/> <outlet property="progTool" destination="08n-xg-fNl" id="959-as-OtP"/>
<outlet property="window" destination="xOd-HO-29H" id="JIz-fz-R2o"/> <outlet property="window" destination="xOd-HO-29H" id="JIz-fz-R2o"/>
</connections> </connections>
@ -278,6 +279,10 @@
<point key="canvasLocation" x="408" y="438"/> <point key="canvasLocation" x="408" y="438"/>
</window> </window>
<userDefaultsController representsSharedInstance="YES" id="fpc-q0-yYy"/> <userDefaultsController representsSharedInstance="YES" id="fpc-q0-yYy"/>
<customView id="HFe-2c-jeW" customClass="ACEView">
<rect key="frame" x="0.0" y="0.0" width="163" height="96"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
</objects> </objects>
<resources> <resources>
<image name="BuildIcon" width="32" height="32"/> <image name="BuildIcon" width="32" height="32"/>

33
AVRsack/FileRevision Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/ruby
#
# FileRevision FILE
#
# AVRsack
#
# Created by Matthias Neeracher on 03/16/15.
# Copyright © 2015 Aere Perennius. All rights reserved.
#
file = ARGV[0]
if file =~ %r|(.*)/(.*)|
Dir.chdir($1)
file = $2
end
rev = ''
IO.popen("git log -1 --pretty=oneline '#{file}'", 'r') do |io|
if line = io.gets
rev = line[0..7]
end
end
if $? == 0 && rev.size > 0
print rev
else
IO.popen("svn info '#{file}'") do |io|
io.each_line do |line|
if line =~ /Last Changed Rev:\s+(\S+)/
print "r"+$1
exit 0
end
end
end
end