Bug 695742 - Implement 'Save as PDF' [r=mfinkle]

Add a menu item that allows the user to save the page the
selected tab as a PDF. Currently this will list the generated
PDF as a download.
This commit is contained in:
Kartikaya Gupta 2011-10-25 11:51:23 -04:00
parent 32f767413d
commit 258be86c37
4 changed files with 84 additions and 0 deletions

View File

@ -467,6 +467,9 @@ abstract public class GeckoApp
case R.id.reload:
doReload();
return true;
case R.id.saveaspdf:
GeckoAppShell.sendEventToGecko(new GeckoEvent("SaveAs:PDF", null));
return true;
default:
return super.onOptionsItemSelected(item);
}

View File

@ -39,3 +39,4 @@
<!ENTITY quit "Quit">
<!ENTITY share "Share">
<!ENTITY saveaspdf "Save as PDF">

View File

@ -12,6 +12,9 @@
android:icon="@drawable/share"
android:title="@string/share" />
<item android:id="@+id/saveaspdf"
android:title="@string/saveaspdf" />
<item android:id="@+id/quit"
android:icon="@drawable/quit"
android:title="@string/quit" />

View File

@ -73,6 +73,7 @@ var BrowserApp = {
Services.obs.addObserver(this, "Tab:Close", false);
Services.obs.addObserver(this, "session-back", false);
Services.obs.addObserver(this, "session-reload", false);
Services.obs.addObserver(this, "SaveAs:PDF", false);
NativeWindow.init();
@ -196,6 +197,80 @@ var BrowserApp = {
}
},
saveAsPDF: function saveAsPDF(aBrowser) {
// Create the final destination file location
let ContentAreaUtils = {};
Services.scriptloader.loadSubScript("chrome://global/content/contentAreaUtils.js", ContentAreaUtils);
let fileName = ContentAreaUtils.getDefaultFileName(aBrowser.contentTitle, aBrowser.documentURI, null, null);
fileName = fileName.trim() + ".pdf";
let dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
let downloadsDir = dm.defaultDownloadsDirectory;
let file = downloadsDir.clone();
file.append(fileName);
file.createUnique(file.NORMAL_FILE_TYPE, 0666);
fileName = file.leafName;
// We must manually add this to the download system
let db = dm.DBConnection;
let stmt = db.createStatement(
"INSERT INTO moz_downloads (name, source, target, startTime, endTime, state, referrer) " +
"VALUES (:name, :source, :target, :startTime, :endTime, :state, :referrer)"
);
let current = aBrowser.currentURI.spec;
stmt.params.name = fileName;
stmt.params.source = current;
stmt.params.target = Services.io.newFileURI(file).spec;
stmt.params.startTime = Date.now() * 1000;
stmt.params.endTime = Date.now() * 1000;
stmt.params.state = Ci.nsIDownloadManager.DOWNLOAD_NOTSTARTED;
stmt.params.referrer = current;
stmt.execute();
stmt.finalize();
let newItemId = db.lastInsertRowID;
let download = dm.getDownload(newItemId);
try {
DownloadsView.downloadStarted(download);
}
catch(e) {}
Services.obs.notifyObservers(download, "dl-start", null);
let printSettings = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(Ci.nsIPrintSettingsService).newPrintSettings;
printSettings.printSilent = true;
printSettings.showPrintProgress = false;
printSettings.printBGImages = true;
printSettings.printBGColors = true;
printSettings.printToFile = true;
printSettings.toFileName = file.path;
printSettings.printFrameType = Ci.nsIPrintSettings.kFramesAsIs;
printSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
//XXX we probably need a preference here, the header can be useful
printSettings.footerStrCenter = "";
printSettings.footerStrLeft = "";
printSettings.footerStrRight = "";
printSettings.headerStrCenter = "";
printSettings.headerStrLeft = "";
printSettings.headerStrRight = "";
let listener = {
onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {},
onProgressChange : function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {},
// stubs for the nsIWebProgressListener interfaces which nsIWebBrowserPrint doesn't use.
onLocationChange : function() {},
onStatusChange: function() {},
onSecurityChange : function() {}
};
let webBrowserPrint = content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebBrowserPrint);
webBrowserPrint.print(printSettings, listener);
},
observe: function(aSubject, aTopic, aData) {
let browser = this.selectedBrowser;
if (!browser)
@ -214,6 +289,8 @@ var BrowserApp = {
this.selectTab(this.getTabForId(parseInt(aData)));
else if (aTopic == "Tab:Close")
this.closeTab(this.getTabForId(parseInt(aData)));
else if (aTopic == "SaveAs:PDF")
this.saveAsPDF(browser);
}
}