Custom addLink funciton

PDF-XChange Editor SDK for Developers

Moderators: TrackerSupp-Daniel, Tracker Support, Paul - Tracker Supp, Vasyl-Tracker Dev Team, Chris - Tracker Supp, Sean - Tracker, Ivan - Tracker Software, Tracker Supp-Stefan

Forum rules
DO NOT post your license/serial key, or your activation code - these forums, and all posts within, are public and we will be forced to immediately deactivate your license.

When experiencing some errors, use the IAUX_Inst::FormatHRESULT method to see their description and include it in your post along with the error code.
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Custom addLink funciton

Post by kinwind »

Hi

I can find the origin "add link" from context menu.

In my application, I want to add a custom add Link function.

When I click this function , I can pick one file from PDF file list and add a page number for goto function.

After above the step , I can click the link and jump to the PDF pages.

How Can I do finish this function

Thanks

ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello ken,

You can use this operation to add the link annotation:
https://sdkhelp.pdf-xchange.com/vie ... ots_addNew
And here's how you can add a custom command:
https://forum.pdf-xchange.com/ ... 66&t=24171

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi. Sasha

I already add a custom add function

I have some question need to help

Q1: After select the text and click the "Add Link..."(ref 1) function created by my code, how to use the "InsertNewAnnot" method to create the annotation link.
I have a problem in the get text position.

Q2: I want to add a custom function in "Add Link..."(ref 2). The function can invoke the window as above. How can invoke the window and modify "the Document" (ref3) region use by my file list

Q3: Can I handle the annotation link action when the user click?

Image

Image

Image

Thanks

Ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

What kind of problem are you experiencing with the text position? Do you want to create the link around the selected text?
You mean you want to remove the entire group and paste a list there? If so, then I'm afraid that it's not possible.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi.. Sasha

Yes, I want to create the link around the selected text.
In our application, we compress the pdf file to another type file.

The user create the link that can click and jump to the other file location.
The user can use the dialog(like "Go to a Page in Another Document" dialog) to set the page.
The other file need to decompress before the user click link.
After decompress, the pdf editor goto the pdf file pages.

thanks

Ken.
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

From what you describe you can do this:
1) You add the link annotation based of the selected text coordinates.
2) Then you will need to fill the action list with the GoToR action. For that you will have to use this method:
https://sdkhelp.pdf-xchange.com/vie ... t_AddGotoR
At this point you can show your own dialog of some sort so that the user can choose one of your files, path to which will be used for the GoToR action.
3) As for the command that will edit the link with the GoToR action. You can get the Actions List from the Link annotation, then you can get your GoToR action as IPXC_Action. After this you will need to get the IPXC_Action handler by using this method with the IPXC_Action::Type property:
https://sdkhelp.pdf-xchange.com/vie ... rForAction
Then the dialog with the needed file will be opened so that the user can change the page to the desired one. Additionally, the button that is used or file choosing can be hidden.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi Alex

Thanks your help.

I already add the link annotation based of the selected text coordinates

But I don't understand step 2 and 3.

I add a GoToR action and GetHandlerForAction in folllow code.

Code: Select all

var AL = ctrl.Doc.CoreDoc.CreateActionsList();
IPXC_Action gotoR = AL.AddGotoR("x.pdf", new PXC_Destination() { nPageNum = 0, nType = PXC_DestType.Dest_Fit });
pAnnot.set_Actions(PXC_TriggerType.Trigger_Up, AL);

IPXV_ActionHandler handler = ctrl.Inst.GetHandlerForAction(gotoR.Type);

I can get the handler , but I don't know how to continue.

I try the method "Perform", it need some parameter I don't how to get.

Another question, If my fileList is a id list not filename list.

The application open real file path by the document id.

How can I do?

Thanks

Ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

Actually, you will only need first two parameters of the Perform method for the GoTo action - other are irrelevant.
As for the ID - you will need to get the document's path from the ID so that you can use the action correctly.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hello.. Allex

I can't use the Perform method only tow parameters

IPXV_ActionHandler::Perform Method
https://sdkhelp.pdf-xchange.com/vie ... er_Perform

shows the parameter must have 5 parameters.

I try to use above codes

Code: Select all

    
IPXV_ActionHandler actionHandler = ctrl.Inst.GetHandlerForAction(gotoR.Type);
var opendocparams = ctrl.Inst.CreateOpenDocParams();                  
IPXV_Document srcDoc = ctrl.Inst.ActiveMainFrm.OpenDocFromPath(@"D:\\x.pdf", opendocparams);
actionHandler.Perform(srcDoc, gotoR, null, 0, 0);
it always have error on actionHandler.Perform method

thanks

ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

Please use the try-catch block and FormatHRESULT method and tell me what the error is precisely.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi..

the error

Image

thanks

ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

1) I have a suspicion, that you only have added the annotation to the Core level and have not executed the operation to add it to the Editor Level:

Code: Select all

//Executing the operation so that the annotation will be updated from structure
int nID = pdfCtl.Inst.Str2ID("op.annots.addNew", false);
PDFXEdit.IOperation pOp = pdfCtl.Inst.CreateOp(nID);
PDFXEdit.ICabNode input = pOp.Params.Root["Input"];
input.Add().v = pAnnot;
pOp.Do();
Only after the operation the Link annotation would exist on the Editor level.

2) Why do you need the Perform method? This method executes the action itself and basically will open the file that you gave to the action. You will need to show your own dialog with your files list so that the user can pick one of them. Then you will need to create the GoToR action with that file name. Then you will need to show the dialog by using the https://sdkhelp.pdf-xchange.com/vie ... Properties method so that the user can choose a page by using our dialog.
NOTE: ShowProperties should be called only when the annotation exists on the Editor Level.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Thanks Alex

Finally, I can add the link and show the dialog.

I have another question need to help.

1. Hide the target document region (ref. 1)
2. After click action button (ref 2), I want to hide the filename (ref. 3) in "Edit Action List" dialog.
3. When click the "Edit" action button, how to handle the event that I can change the file path in my code. otherwise the dialog will show the error (ref. 4).

Image

Image

Image

Image
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

1) You will need to handle the https://sdkhelp.pdf-xchange.com/vie ... beginModal and check whether the:

Code: Select all

if (pTarget.get_ID() == pTarget.ThreadCtx.Inst.Str2ID("DlgActionsGotoPage"))
This will mean that the GoToR action dialog was launched. Then you will need to hide the needed layer by using this method:
https://sdkhelp.pdf-xchange.com/vie ... _ShowLayer
The layer name is Layer2.
2) Hiding that name only is not possible.
3) Why did you specify the invalid path? You will need to give the path to the file that the user picks in your dialog.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi Alex

I still have some question from your reply.

1. How to handle e.beginModal on OnEvent ? I can't find the pTarget object.

2. "Why did you specify the invalid path?" => When user add the link function, I change the filepath extenstion from "pdf.bak" to "pdf". Can I handle the event when user click the "edit" button that I can use the code to change extenstion?

3. Which event can I handle user click the hyperlink url?

thanks your help

Ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello kinwind,

1) Check out the FullDemo application for the UIEventDemoMon class.
2) Well you can catch the command execution event with the custom command handler and update the filename - the ID of the command is cmd.actions.edit:
https://forum.pdf-xchange.com/ ... 82#p108382
You will need to listen for the OnNotify method execution.
3) Please describe more precisely what do you need.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi..

1) Check out the FullDemo application for the UIEventDemoMon class.
=> done.

2) Well you can catch the command execution event with the custom command handler and update the filename
=> I can handle the edit click event, but I don't know how the change the filename, can you tell more detail.
Otherwise, can I get the dialog object when the user click edit button?

3) Please describe more precisely what do you need.
=> I want to handle the user click the hyperlink url.
When the user click the url, I want check the url contain some string.
I find the event named "e.document.beforeRunAction", it can handle the user click event.

thank your help

ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello kinwind,

2) I meant changing the name of the file as specified in the action list not the name in the action list itself.

3) I've updated the event's description:
https://sdkhelp.pdf-xchange.com/vie ... eRunAction

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi

I use my custom link function with .bak filename and show the properties by "ShowProperties" method.

Code: Select all

   var AL = ctrl.Doc.CoreDoc.CreateActionsList();
   IPXC_Action gotoR = AL.AddGotoR(openfilePath + ".bak", new PXC_Destination() { nPageNum = 2, nType = PXC_DestType.Dest_Fit });
   pAnnot.set_Actions(PXC_TriggerType.Trigger_Up, AL);
Another code is change the .bak filename

Code: Select all

	if (oper.ID == axPXV_Ctrl.Inst.Str2ID("op.openDoc", false))
          {
                    var input = oper.Params.Root["Input"];
                    var fileName = string.Empty;
                    PDFXEdit.IAFS_Name name = input.v as PDFXEdit.IAFS_Name;
                    if (name == null)
                    {
                        PDFXEdit.IAFS_File file = input.v as PDFXEdit.IAFS_File;
                        if (file == null)
                        {
                            PDFXEdit.IString str = input.v as PDFXEdit.IString;
                            fileName = str.Value;
                        }
                    }
                    else
                    {
                        var filesys = name.FileSys;
                        fileName = fsInst.DefaultFileSys.NameToString(name);                        
                    }
                    if (Path.GetExtension(fileName) == ".bak")
                    {
                        input.v = fsInst.DefaultFileSys.StringToName(fileName.Replace(".bak", string.Empty));                        
                    }
	}
I change the Page Number from 3 to 1, and click the "OK" button.
Image

The page number is not correct in the link.

Another situation is modify the action in the "Edit Actions List"
Image

Click Edit button show the dialog to change the page number or others
I change the Page Number from 3 to 1, and click the "OK" button.

The result show the error
Image

There are have two question
1. How to handle the 'OK' Button if I want to add other function
2. How to fix the "Failed to open file" problem

Thanks

Ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

1. Having the needed IUIX_Dialog, you can get the OK button by it's ID:

Code: Select all

PDFXEdit.IUIX_Obj btnObj = dlg.GetItem("btn.ok");
btnObj.QueryImpl(typeof(PDFXEdit.IUIX_Button).GUID, null, out outPtr);
PDFXEdit.IUIX_Button btn = (PDFXEdit.IUIX_Button)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(outPtr);
Then you will need to create a class that would listen to the button's object notifications:

Code: Select all

public partial class ObjectEventTarget :
PDFXEdit.IUIX_ObjImpl,
IDisposable
{
	public ObjectEventTarget(PDFXEdit.IUIX_Obj obj)
	{
		Obj_ = obj;
		if (Obj_ != null)
			Obj_.PushImpl(this);
	}
	~ObjectEventTarget()
	{
		Dispose();
	}
	//Disposing of all of the links we made with objects and parent
	public void Dispose()
	{
		if (Disposed_)
			return;
		Disposed_ = true;
		if (Obj_ != null)
		{
			Obj_.PopImpl(this);
			System.Runtime.InteropServices.Marshal.ReleaseComObject(Obj_);
			Obj_ = null;
		}
	}

	//Object for which we are implementing the custom event listener
	public PDFXEdit.IUIX_Obj Obj_;
	//Used for single dispose control
	private bool Disposed_ = false;

	// IUIX_ObjImpl
	public PDFXEdit.IUIX_Obj Obj
	{
		get { return this.Obj_; }
	}
	//Getting Y coordinate from event param2
	public static short HiWord(uint dword)
	{
		return (short)(dword >> 16);
	}
	//Getting X coordinate from event param2
	public static short LoWord(uint dword)
	{
		return (short)dword;
	}

	//Event listener that listens for all of the needed events
	public void OnEvent(PDFXEdit.IUIX_Obj pSender, PDFXEdit.IUIX_Event pEvent)
	{
		//If the event is not handled then it will be 
		pEvent.Handled = false;
		//
		if (pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_Notify)
		{
			IntPtr outPtr = new IntPtr(pEvent.Param1);
			PDFXEdit.UIX_NotifyInfo ni = (PDFXEdit.UIX_NotifyInfo)System.Runtime.InteropServices.Marshal.PtrToStructure(outPtr, typeof(PDFXEdit.UIX_NotifyInfo));
			if (ni.nCode == (int)PDFXEdit.UIX_NotifyCodes.UIX_Notify_Clicked)
			{
				//The button was clicked
			}
		}
		else if (pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_BeforeDestroy)
		{
			Dispose();
		}
		else if (pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_Last)
		{
			Dispose();
		}
	}

	public void OnPostEvent(PDFXEdit.IUIX_Obj pSender, PDFXEdit.IUIX_Event pEvent)
	{

	}

	public void OnPreEvent(PDFXEdit.IUIX_Obj pSender, PDFXEdit.IUIX_Event pEvent)
	{

	}
}
After that you will have to initialize a class with the button's object (after you have extracted it from the dialog):

Code: Select all

PDFXEdit.IUIX_Button btn = (PDFXEdit.IUIX_Button)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(outPtr);
//Create this variable in the EventMonitor's class
//public ObjectEventTarget objectTarget = null;
objectTarget = new ObjectEventTarget(btn.Obj);
2) To fix this problem you will need to provide an existing file. In your case you will need to remain the file.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Hi.. Alex

Thanks your help

I can handle the "btn.ok" click event now.

But, the click event execute twice ObjectEventTarget OnEvent().

How can fix it.

Thanks
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

Have you compared the Event parameters that you have in both cases? Probably one is from mouse down and the other from the mouse up.

Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Thanks Alex

I fix the btn event problem.

The last question is I don't want user click the add button.

How can I hide the button.

Image

Ken
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

Hello Ken,

Add this code to your event monitor:

Code: Select all

if ((pEvent.Code == (int)PDFXEdit.UIX_EventCodes.e_ShowModal))
{
	if (pTarget.get_ID() == pTarget.ThreadCtx.Inst.Str2ID("DlgEditActionsList"))
	{
		IntPtr outPtr;
		pTarget.QueryImpl(typeof(PDFXEdit.IUIX_Dialog).GUID, null, out outPtr);
		PDFXEdit.IUIX_Dialog dlg = (PDFXEdit.IUIX_Dialog)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(outPtr);
		if (dlg == null)
			return;
		PDFXEdit.IUIX_Inst iuiInst = (PDFXEdit.IUIX_Inst)m_Inst.GetExtension("UIX");
		PDFXEdit.IUIX_Cmd cmd = iuiInst.CmdManager.Cmds.Find("cmd.actions.add");
		cmd.Offline = true;
		cmd.Hidden = true;
	}
}
The ShowModal event will launch after the initialization of the command bar. Thus the new commands will already be added at this point and their modification will be possible.
The event monitor class implementation can be taken from the FullDemo project. Search for the UIEventDemoMon and add the code I gave you into this method:

Code: Select all

public void OnEventMonitor(PDFXEdit.IUIX_Obj pTarget, PDFXEdit.IUIX_Event pEvent)
Cheers,
Alex
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ
kinwind
User
Posts: 38
Joined: Tue May 31, 2016 7:03 am

Re: Custom addLink funciton

Post by kinwind »

Thanks Alex
Sasha - Tracker Dev Team
User
Posts: 5522
Joined: Fri Nov 21, 2014 8:27 am

Re: Custom addLink funciton

Post by Sasha - Tracker Dev Team »

:)
Subscribe at:
https://www.youtube.com/channel/UC-TwAMNi1haxJ1FX3LvB4CQ