iPhone 4.2 airprint Print job fails - xamarin.ios

No matter which printer I select, I get "Print-job failed: Unsupported document format "application/pdf".
I am trying to print on HP printers only.
I see no place in code to change the output type.
I am using UISimpleTextFormatter to format the string.
Not sure how to get around this one.
Edit : Code below is straight up from Miguel's example. with the only difference being, I tried out the markupformatter to see whether it gets output in a different format than application/pdf.
The print dialog comes up with the list of HP printers, I select a printer but nothing gets printed and in debug mode, the error specified at the top gets logged.
Other than UIPrintInfoOutputType.General, I have also tried UIPrintInfoOutputType.GrayScale but with the same effect.
public partial class AppDelegate : UIApplicationDelegate
{
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window.MakeKeyAndVisible ();
var button = UIButton.FromType (UIButtonType.RoundedRect);
button.Frame = new RectangleF (100, 100, 120, 60);
button.SetTitle ("Print", UIControlState.Normal);
button.TouchDown += delegate {
Print ();
};
window.AddSubview (button);
return true;
}
void Print ()
{
var printInfo = UIPrintInfo.PrintInfo;
printInfo.JobName = "Test :";
printInfo.OutputType = UIPrintInfoOutputType.General;
printInfo.JobName = "Test: My first Print Job";
/*
var textFormatter = new UISimpleTextPrintFormatter ("Once upon a time...") {
StartPage = 0,
ContentInsets = new UIEdgeInsets (72, 72, 72, 72),
MaximumContentWidth = 6 * 72,
};
*/
var htmlFormatter = new UIMarkupTextPrintFormatter("<html><body>Test : Hi There!!</body></html>");
htmlFormatter.StartPage = 0;
htmlFormatter.ContentInsets = new UIEdgeInsets (72, 72, 72, 72); // 1 inch margins
htmlFormatter.MaximumContentWidth = 6 * 72;
var printer = UIPrintInteractionController.SharedPrintController;
printer.PrintInfo = printInfo;
printer.PrintFormatter = htmlFormatter;
printer.ShowsPageRange = true;
printer.Present (true, (handler, completed, err) => {
if (!completed && err != null){
Console.WriteLine ("error");
}
});
}
public override void OnActivated (UIApplication application)
{
}
}

I was expecting the print dialog to come up with only the air print enabled printers. But it comes up with non airprint enabled HP printers as well. That amde me think, it could print to those printers and that they are air print enabled.
But that was not the case.

Related

GTK4 Problem setting image from pixbuf with a GtkDropTarget

I am testing a gtk4 widget which is GtkDropTarget. I plan on setting an image which is dragged to the window as the image of the window itself. But errors come up as soon as I drag an image file. To be clear, this is the code in vala:
int main (string[] args) {
var app = new App();
return app.run(args);
}
public class App : Gtk.Application {
public App () {
Object (
application_id: "com.github.ea",
flags: ApplicationFlags.FLAGS_NONE
);
}
public override void activate () {
var window = new Window (this);
add_window (window);
}
}
public class Window : Gtk.ApplicationWindow {
public Window (Gtk.Application app) {
Object (application: app);
}
construct {
title = "Drag";
set_default_size (640, 480);
var drag_source = new DragSource ();
set_child (drag_source.self);
show ();
}
}
public class DragSource {
public Gtk.Image self;
public DragSource () {
self = new Gtk.Image ();
var drag_controller = new Gtk.DropTarget (GLib.Type.INVALID, Gdk.DragAction.COPY);
drag_controller.set_gtypes ({typeof(File)});
self.add_controller (drag_controller);
drag_controller.on_drop.connect (on_drop);
}
private bool on_drop (GLib.Value val, double x, double y) {
File filename = (File) val;
var file_path = filename.get_path ();
if (val.holds(typeof(File)) == true) {
print ("The dragged object is a file.\n");
if ("png" in file_path || "jpg" in file_path) {
print ("The dragged object is an image.\n");
self.set_from_pixbuf (pixbuf(file_path));
}
else {
print ("The dragged object is NOT an image.\n");
}
}
else {
print ("The dragged object is NOT a file.\n");
return false;
}
return true;
}
private Gdk.Pixbuf pixbuf (string file) {
try {
return new Gdk.Pixbuf.from_file (file);
} catch (Error e) {
error ("%s", e.message);
}
}
}
This compiles and runs. But as soon as I drag an image file to the window, error occurs and the image is not displayed. This are the pictures of what happens. What should happen is, when I drag a png file from my file manager, the dragged image should be the image showing in the GtkImage, which is the main widget of the window.
On my first drag of an image file from my pc, this error shows up:
The dragged object is a file.
The dragged object is an image.
(v:3891): Gtk-CRITICAL **: 08:52:28.861: gtk_image_set_from_pixbuf: assertion 'GTK_IS_IMAGE (image)' failed
On the second drag, this shows up:
(v:3891): Gdk-CRITICAL **: 08:53:33.388: gdk_drop_set_actions: assertion 'priv->state == GDK_DROP_STATE_NONE' failed
The dragged object is a file.
The dragged object is an image.
(v:3891): Gtk-CRITICAL **: 08:53:33.973: gtk_image_set_from_pixbuf: assertion 'GTK_IS_IMAGE (image)' failed
I would really appreciate a help. Thank You!
This is how I would implement your intention
int main (string[] args) {
var app = new App ();
return app.run (args);
}
public class App : Gtk.Application {
public App () {
Object (
application_id: "com.github.ea",
flags : ApplicationFlags.FLAGS_NONE
);
}
public override void activate () {
var window = new Window (this);
window.present ();
}
}
public class Window : Gtk.ApplicationWindow {
public Window (Gtk.Application app) {
Object (application: app);
}
construct {
title = "Drag an Image!";
set_default_size (640, 480);
var image = new Gtk.Image ();
image.vexpand = image.hexpand = true;
var controller = new Gtk.DropTarget (typeof (GLib.File), Gdk.DragAction.COPY);
controller.on_drop.connect ((target, value, x, y) => {
var file = (GLib.File) value;
var filename = file.get_path ();
if (GLib.ContentType.guess (filename, null, null).contains ("image")) {
image.set_from_file (filename);
}
});
image.add_controller (controller);
set_child (image);
}
}

Desperately need Xamarin.IOS modal MessageBox like popup

Coding in Xamarin IOS. I have a drop down list type popup, where, if The end user types in a new value, I want to ask a yes/no question: Do You want to add a new row?
The control is inside a UIStackView, which is inside a container UIView, which is in turn inside another which is presented via segue. Xamarin demanded a UIPopoverController, which I implemented. Here is The code I have so far:
using System.Threading.Tasks;
using Foundation;
using UIKit;
namespace PTPED_Engine
{
public enum MessagePopupType
{
YesNo = 1,
OKCancel = 2,
OKOnly = 3
}
public enum PopupResultType
{
OK = 1,
Cancel = 2,
Yes = 3,
No = 4
}
public static class AlertPopups
{
static NSObject nsObject;
public static void Initialize(NSObject nsObject)
{
AlertPopups.nsObject = nsObject;
}
public static Task<PopupResultType> AskUser(UIViewController parent, UIView V, string strTitle, string strMsg, MessagePopupType mpt)
{
using (UIPopoverController pc = new UIPopoverController(parent))
{
// pc.ContentViewController
// method to show an OK/Cancel dialog box and return true for OK, or false for cancel
var taskCompletionSource = new TaskCompletionSource<PopupResultType>();
var alert = UIAlertController.Create(strTitle, strMsg, UIAlertControllerStyle.ActionSheet);
// set up button event handlers
if (mpt == MessagePopupType.OKCancel)
{
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.OK)));
alert.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.Cancel)));
}
if (mpt == MessagePopupType.YesNo)
{
alert.AddAction(UIAlertAction.Create("Yes", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.Yes)));
alert.AddAction(UIAlertAction.Create("No", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.No)));
}
if (mpt == MessagePopupType.OKOnly)
{
alert.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Default, a => taskCompletionSource.SetResult(PopupResultType.OK)));
}
// show it
nsObject.InvokeOnMainThread(() =>
{
pc.PresentFromRect(V.Bounds, V, UIPopoverArrowDirection.Any, true);
});
return taskCompletionSource.Task;
}
}
}
}
and I invoke it as follows:
LookupCombo.Completed += async (object sender, CompletedEventArgs e) =>
{
C1AutoComplete AC = (C1AutoComplete)sender;
if (AC.Text.Trim() != "")
{
string sColName = AC.AccessibilityIdentifier.Trim();
var ValuesVC = (List<Lookupcombo_Entry>)AC.ItemsSource;
var IsThisAHit = from Lookupcombo_Entry in ValuesVC
where Lookupcombo_Entry.sDispVal.ToUpper().Trim() == e.value.ToUpper().Trim()
select Lookupcombo_Entry.sMapVal;
if (!IsThisAHit.Any())
{
string sTitle = "";
string sFull = _RM.GetString(sColName);
if (sFull == null) { sFull = "???-" + sColName.Trim(); }
sTitle = " Add New " + sFull.Trim() + "?";
string sPPrompt = "Do you want to add a new " + sFull.Trim() + " named " + AC.Text.Trim() + " to the Database?";
var popupResult = await AlertPopups.AskUser(CurrentViewController(), V, sTitle, sPPrompt, MessagePopupType.YesNo);
}
}
};
CurrentViewController is defined like this:
private UIViewController CurrentViewController()
{
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
return vc;
}
This does nothing. It hangs The user interface.
This should be built in, but it is only built in in Xamarin.Forms, which I do not want to use.
I have no problem in doing this stuff with an await, but this is simply not working. Can anyone help?
Thanks!
You can just use the ACR UserDialogs library:
https://github.com/aritchie/userdialogs
This is a solution I provided a few years ago, I think it is an ugly hack, compared to your elegant approach. You did not say what part does not work exactly, that might help spot the problem.
Here is my solution from a few years back:
iphone UIAlertView Modal

ZXing.Net.Mobile Sample.WindowsUniversal Sample Not Scanning

Testing this to incorporate into Win 10 UWP app to scan 1D barcodes (format 39 & 128). I have updated latest through nuget 2.0.4.46. Referenced post at http://www.yortondotnet.com/2015/07/mobile-barcode-scanning-with-zxingnet.html regarding some options setting prior to scan() with no luck. The scanner (camera) opens but never recognizes a barcode scan successfully - or failure for that matter. It seems nothing is happening whatsoever. I have included straight, pertinent sample code with some options modifications for review. I have gotten Scandit API to work and was going to try Manateeworks but both are really costly and not an option. I am developing on Surface Pro 3 (Win 10) and that build will also be target machines when complete.
public sealed partial class MainPage : Page
{
UIElement customOverlayElement = null;
MobileBarcodeScanner scanner;
public MainPage()
{
this.InitializeComponent();
//Create a new instance of our scanner
scanner = new MobileBarcodeScanner(this.Dispatcher);
scanner.Dispatcher = this.Dispatcher;
}
private void buttonScanDefault_Click(object sender, RoutedEventArgs e)
{
//Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of our default overlay
scanner.TopText = "Hold camera up to barcode";
scanner.BottomText = "Camera will automatically scan barcode\r\n\r\nPress the 'Back' button to Cancel";
// GWS Set Options
var options = new MobileBarcodeScanningOptions();
options.PossibleFormats = new List<ZXing.BarcodeFormat>() {
ZXing.BarcodeFormat.CODE_39, ZXing.BarcodeFormat.CODE_128
};
options.AutoRotate = false;
options.TryHarder = false;
options.TryInverted = false;
//Start scanning
scanner.Scan(options).ContinueWith(t =>
{
if (t.Result != null)
HandleScanResult(t.Result);
});
}
private void buttonScanContinuously_Click(object sender, RoutedEventArgs e)
{
//Tell our scanner to use the default overlay
scanner.UseCustomOverlay = false;
//We can customize the top and bottom text of our default overlay
scanner.TopText = "Hold camera up to barcode";
scanner.BottomText = "Camera will automatically scan barcode\r\n\r\nPress the 'Back' button to Cancel";
// GWS Set Options
var options = new MobileBarcodeScanningOptions();
options.PossibleFormats = new List<ZXing.BarcodeFormat>() {
ZXing.BarcodeFormat.CODE_39, ZXing.BarcodeFormat.CODE_128
};
options.AutoRotate = false;
options.TryHarder = false;
options.TryInverted = false;
//Start scanning
scanner.ScanContinuously(options, async (result) =>
{
var msg = "Found Barcode: " + result.Text;
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
{
await MessageBox(msg);
});
});
}
async void HandleScanResult(ZXing.Result result)
{
string msg = "";
if (result != null && !string.IsNullOrEmpty(result.Text))
msg = "Found Barcode: " + result.Text;
else
msg = "Scanning Canceled!";
await MessageBox(msg);
}
}
Simon,
I have the exact same problem. I tested your code with the latest nuget 2.1.47, the problem still exists.
You need to download the latest from Github and add the following projects (or DLLs) to your project:
ZXing.Net (project: zxing.portable.csproj)
ZXing.Net.Mobile.Core
ZXing.Net.Mobile.WindowsUniversal
I have tested your code and it works fine. I hope this help.
Cheers,
Sam
I think that the problem in the hardware you are testing with. Surface Pro 3 (Win 10) does not have an auto focus camera. I've never succeed to scan with ZXing using my Surface Pro 3, while the same application is working fine with my other windows 10 device.

HaxeFlixel. Access violation reading location 0x00000008

I have a sprite that I can drag around on screen. I want to be able to drag this sprite into an area (box). As it stands now I can only drop the sprite into the box, but when I drag it directly inn, the the program crashes.
*Im developing in FlashDevelop but windows gave me av option to debug in VS.
I debugged in VS and got this ERROR:
Unhandled exception at 0x00ACCEE9 in Proj.exe: 0xC0000005: Access violation reading location 0x00000008.
Relevant code:
class Drag extends FlxGroup {
var mouseJoint:DistanceJoint;
public inline function registerPhysSprite(spr:FlxNapeSprite)
{
MouseEventManager.add(spr, createMouseJoint);
}
function createMouseJoint(spr:FlxSprite)
{
var body:Body = cast(spr, FlxNapeSprite).body;
mouseJoint = new DistanceJoint(FlxNapeState.space.world, body, new Vec2(FlxG.mouse.x, FlxG.mouse.y),
body.worldPointToLocal(new Vec2(FlxG.mouse.x, FlxG.mouse.y)), 0, 0);
mouseJoint.space = FlxNapeState.space;
}
override public function update():Void
{
super.update();
if (mouseJoint != null)
{
mouseJoint.anchor1 = new Vec2(FlxG.mouse.x, FlxG.mouse.y);
if (FlxG.mouse.justReleased)
{
mouseJoint.space = null;
}
}
}
}
class PlayState extends FlxNapeState {
override public function create()
{
super.create();
bgColor = FlxColor.BLACK;
napeDebugEnabled = true;
var light = new Light(10, 10);
var box = new Box(100, 100);
var drag:Drag;
createWalls(1, 1, 1024, 768, 10, new Material(1, 1, 2, 1, 0.001));
add(light);
add(box);
drag = new Drag();
add(drag);
drag.registerPhysSprite(light);
light.body.velocity.y = 200;
FlxNapeState.space.listeners.add(new InteractionListener(
CbEvent.BEGIN,
InteractionType.COLLISION,
Light.CB_TYPE,
Box.CB_TYPE,
collideLightBox));
}
function collideLightBox(callback:InteractionCallback)
{
var light:Light = cast callback.int1.castBody.userData.sprite;
light.kill();
}
}
class Light extends FlxNapeSprite {
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(10, 10, FlxColor.TRANSPARENT);
var radius = 5;
drawCircle(5, 5, radius, FlxColor.WHITE);
createCircularBody(radius);
body.cbTypes.add(CB_TYPE);
body.userData.sprite = this;
}
}
class Box extends FlxNapeSprite {
public static var CB_TYPE(default, null) = new CbType();
public function new(x:Float, y:Float)
{
super(x, y);
makeGraphic(100, 50, FlxColor.GREEN);
createRectangularBody(width, height);
body.cbTypes.add(CB_TYPE);
body.type = BodyType.STATIC;
}
}
If you're possibly accessing a null pointer, consider the answer given in this question:
Why is this Haxe try-catch block still crashing, when using Release mode for C++ target
That way you can turn on null pointer checks in hxcpp so you can get better debug information.
Also, if you're trying to debug hxcpp directly in FlashDevelop (step-through and all that), that feature isn't released yet, but I spoke with the team recently and they're working on it.

Access ViewController in DependencyService to present MFMailComposeViewController

How can i access the ViewController in my DependencyService to present a MFMailComposeViewController? I tried using Application.Context but this seems to be only working on Android. Any advice?
You can present a MFMailComposeViewController by doing a window.RootController.PresentViewController (mail controller, true, null);. Depending on your app architecture, the RootViewController might not be an usable ViewController in the hierarchy. In that case you get a
Warning: Attempt to present <MFMailComposeViewController: 0x16302c30> on <Xamarin_Forms_Platform_iOS_PlatformRenderer: 0x14fd1530> whose view is not in the window hierarchy!
In that case, you have to dig for the concrete ViewController, in my case it is:
var rootController = ((AppDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.ChildViewControllers[0].ChildViewControllers[1].ChildViewControllers[0];
which is a bit wicked, but works (An issue for this have been filed for future fix).
The full solution then looks like:
in your AppDelegate.cs, add this:
public UIWindow Window {
get { return window; }
}
in your PCL project, declare the interface: ISendMailService.cs
public interface ISendMailService
{
void ComposeMail (string[] recipients, string subject, string messagebody = null, Action<bool> completed = null);
}
in your iOS project, implement and register the interface: SendMailService.cs
[assembly: DependencyAttribute(typeof(SendMailService))]
public class SendMailService : ISendMailService
{
public void ComposeMail (string[] recipients, string subject, string messagebody = null, Action<bool> completed = null)
{
var controller = new MFMailComposeViewController ();
controller.SetToRecipients (recipients);
controller.SetSubject (subject);
if (!string.IsNullOrEmpty (messagebody))
controller.SetMessageBody (messagebody, false);
controller.Finished += (object sender, MFComposeResultEventArgs e) => {
if (completed != null)
completed (e.Result == MFMailComposeResult.Sent);
e.Controller.DismissViewController (true, null);
};
//Adapt this to your app structure
var rootController = ((AppDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.ChildViewControllers[0].ChildViewControllers[1].ChildViewControllers[0];
var navcontroller = rootController as UINavigationController;
if (navcontroller != null)
rootController = navcontroller.VisibleViewController;
rootController.PresentViewController (controller, true, null);
}
}
And you can now consume it from your Xamarin.Forms PCL project:
new Button {
Font = Font.SystemFontOfSize (NamedSize.Medium),
Text = "Contact us",
TextColor = Color.White,
BackgroundColor = ColorsAndStyles.LightBlue,
BorderRadius = 0,
Command = new Command (()=>{
var mailservice = DependencyService.Get<ISendMailService> ();
if (mailservice == null)
return;
mailservice.ComposeMail (new [] {"foo#example.com"}, "Test", "Hello, World");
})
}
Use: UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(controller, true, null);
I would like to add an additional answer based off of the KeyWindow not always being the main window. (this occurs when you are presenting your controller after the user has interacted with an action sheet or alert dialog)
public static UIViewController GetCurrentUIController()
{
UIViewController viewController;
var window = UIApplication.SharedApplication.KeyWindow;
if (window == null)
{
throw new InvalidOperationException("There's no current active window");
}
if (window.RootViewController.PresentedViewController == null)
{
window = UIApplication.SharedApplication.Windows
.First(i => i.RootViewController != null &&
i.RootViewController.GetType().FullName
.Contains(typeof(Xamarin.Forms.Platform.iOS.Platform).FullName));
}
viewController = window.RootViewController;
while (viewController.PresentedViewController != null)
{
viewController = viewController.PresentedViewController;
}
return viewController;
}
This will guarantee that you get the Xamarin Forms platform renderer window, then find the foremost presented ViewController and return it for use presenting whatever UI or view controller you need to present.
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(controller, true, null);
This only works in above all solutions
Just for a reference. It took me some time to figure it out how to launch it from modal window.
Here comes the solution:
var rootController = ((AppDelegate)(UIApplication.SharedApplication.Delegate)).Window.RootViewController.PresentedViewController;
var navcontroller = rootController as UINavigationController;
if (navcontroller != null)
rootController = navcontroller.VisibleViewController;
rootController.PresentViewController (controller, true, null);

Resources