topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Thursday March 28, 2024, 10:17 am
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Last post Author Topic: FARR C# SDK and Documentation V2 (19/10/2008)  (Read 64199 times)

Perry Mowbray

  • N.A.N.Y. Organizer
  • Charter Member
  • Joined in 2005
  • ***
  • Posts: 1,817
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #25 on: November 16, 2008, 08:07 PM »
Cool: that works -- Thanks.

vitalyb

  • Supporting Member
  • Joined in 2007
  • **
  • Posts: 143
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #26 on: November 17, 2008, 01:18 AM »
Weird... I used WinRAR, true.
However, I told it to archive it as ZIP file.

Lemme look.

vitalyb

  • Supporting Member
  • Joined in 2007
  • **
  • Posts: 143
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #27 on: November 17, 2008, 01:23 AM »
Weird but you were right.

Re-uploading.

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #28 on: December 26, 2008, 10:28 AM »
okej, ive gote the sdk up and running, but how do i write plugins now? what are actionitems and actionlists and how do they make my life easyer? and what happened to SetSearchParameters method? could you please update the documentation, or at least the examples?

thanks.
s
It is impossible to make anything foolproof because fools are so ingenious.

vitalyb

  • Supporting Member
  • Joined in 2007
  • **
  • Posts: 143
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #29 on: December 26, 2008, 11:25 AM »
Err. The examples ARE using ActionItems and ActionLists. See iTunes plugin for example.

All the documentation is in the first post.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #30 on: January 05, 2009, 01:35 AM »
I'm having troubles compiling, using VS2005 and the latest SDK. I've copied parts from FARRAltTab, but I get "no suitable method found to override" for SetSearchParameters and SetFeatureParamers. I loaded the template, changed the class to my name, but left the namespace alone. Then just copied some bits from FARRAltTab. It compiled when I initially opened the template ok.

I note all the examples inherit from FARRPluginBase, not FARRCSharpPluginBase, but I get more issues if I change it to the former base, suggesting the template and SDK has changed since the example code was written.

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #31 on: January 05, 2009, 03:24 AM »
Err. The examples ARE using ActionItems and ActionLists. See iTunes plugin for example.

All the documentation is in the first post.
Sorry, my mistake. I was tired and wasn't thinking very well :) In the meantime, i had a look on all the provided plugins and figured it out, and I must say, it is great! I wrote a plugin in half an hour!
It is impossible to make anything foolproof because fools are so ingenious.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #32 on: January 05, 2009, 03:38 PM »
skajfes, any chance I could pls look at your source so I can figure it out?

Edt: I didn't see you post about the missing/changed SetSearchParameters method; Perhaps I need to examine the iTunes plugin more; I'm new to all of this.
« Last Edit: January 05, 2009, 08:51 PM by joshuawood »

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #33 on: January 06, 2009, 06:01 PM »
Ok, I'm still confused. FARRTunes still uses SetSearchParameters and SetFeatureParamaters, and won't compile for me as it stands. Can anyone help?

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #34 on: January 09, 2009, 06:18 AM »
Itunes plugin does use SetSearchParameters method that no longer exists (at least from what i can see) but that didn't compile for me because I don't have itunes libraries installed.

So to write a plugin I used the suplied Visual Studio template for FARR plugin project, created a new project and that's it.
Most of my plugin logic is in the classes that derive from ActionList and ActionItem.

In the class that derives from FARRCSharpPluginBase override the method SetGeneralInfoParameters to set general parameters of the plugin (plugin name, creator, icon etc.)

In the constructor of the class that derives from ActionList call the base constructor and pass it pluginBase object and regex to activate the plugin as string. Like this:
      
public ClipboardList(FARRCSharpPluginBase pluginBase)
   : base(pluginBase, "^clip")
{
         
}


In the GetActionsCount method I fill my results into SourceList. SourceList is defined as List<ActionItem> in ActionList class that I derived from. Results are of type ActionItem (or any derived class).

Use the constructor of ActionItem derived class to initialize the item. I did a clipboard plugin so i passed it some text that I read from a file as an argument.

Override the GetDataRaw and Execute methods. In GetDataRaw you define what will be written in Path and Group variables of the result. And Execute method defines what happens when user executes an item.
You need to override the CaptionRaw property to set the Caption that is displayed in result list.

use pluginbase.ExecuteFarrCommand () method to pass commands to farr.

And that's mostly it, I hope that this isn't as confusing as I think it is.
It is impossible to make anything foolproof because fools are so ingenious.

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #35 on: January 09, 2009, 06:28 AM »
Now I have a question. It concerns the new feature of adding buttons to the statusbar and context menu.
I can add an item to the statusbar with ExecuteFARRCommand() method, but how can I set the command to to tell the plugin something? In the help it says that I have to use "pcommand" launch string with some extra text as parameter, and that FARR will do a plugin->set_strvalue("pcommand",EXTRA_TEXT) call to the plugin. Now, how can I catch that call?

And another question is about adding context menu items. Help states that
The "contextmenu" addmenu command must be called at a very specific time, only after farr requests it from your plugin.  This happens when your plugin received an AllowProcessTrigger call with triggermode=PrepareContextMenu.
How can I answer that call?

Thanks.
It is impossible to make anything foolproof because fools are so ingenious.

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 40,896
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Read more about this member.
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #36 on: January 09, 2009, 08:08 AM »
all good questions.

let me start with pcommand.

the idea of pcommand is normally to give a way for plugins to call each other, but it can also be useful for doing a kind of callback as you suggest.  czb uses pcommand in some very clever and creative ways to do things from web pages presented to the user, since links on a web page can trigger pcommands.

as you say:

FARR will do a plugin->set_strvalue("pcommand",EXTRA_TEXT) call to the plugin. Now, how can I catch that call?

basically what happens is the EVERY plugin will receive a set_strvalue callback with ("pcommand",EXTRA_TEXT).
then the idea is that all plugins will examine the EXTRA_TEXT and decide whether they should handle it.
ONLY if a plugin wants to tell FARR that it has assumed responsibility for it will it return a TRUE, otherwise FALSE.

So lets say you wanted to implement a special callback from farr, you would give it a unique name like "skajfes_callback_doadance"
and then you would make a context menu or statusbar or web page link that was like this: "pcommand skajfes_callback_doadance:some more info here"

and then in your set_strvalue(name,value) event function that gets called by farr
you would check if name=="pcommand" and value STARTS WITH "skajfes_callback_doadance:" and if so, then the pcommand is meant for you, so you process it and return TRUE to farr.
if not, then its for some other plugin so you return false and let some other plugin try to handle it.

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 40,896
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Read more about this member.
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #37 on: January 09, 2009, 08:14 AM »
Ok for question 2:

The "contextmenu" addmenu command must be called at a very specific time, only after farr requests it from your plugin.  This happens when your plugin received an AllowProcessTrigger call with triggermode=PrepareContextMenu.

you create the context menu items in the exact same way that you create status bar items; here is an example from a javascript plugin:

            FARR.setStrValue("addmenu.contextmenu","type=item|caption=Help|hint=Help for the plugin|icon=help.ico|launch=restartsearch hello\ntype=item|caption=Help2|hint=Help2 for the plugin|icon=web.ico|launch=restartsearch hello2");

and then i think you were asking WHEN you have to make this call in order to add the context menu item.  this is an important question since the contextmenu items need to be set at a very particular time, right after the user right clicks on an item.

now in order to do that, you NEED the new farr callback which was recently added (and is not yet in the C# api but i have on good authority it will be added soon):

Allow_ProcessTriggerV2(const char* destbuf_path, const char* destbuf_caption, const char* destbuf_groupname, int pluginid,int thispluginid, int score, E_EntryTypeT entrytype, void* tagvoidp, BOOL *closeafterp, int triggermode);

where triggermode is E_AllowProcessTriggerMode_PrepareContextMenu=2

so the key thing here is that the new callback ProcessTriggerV2 gets called when an item is right-clicked (not just when launched as old V1 did), and that is what you want to listen for; when that is called, thats when you need to set the addmenu.contextmenu.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #38 on: January 10, 2009, 02:05 AM »
Thanks for the help skajfes. I've got a better idea now after look at the iTunes code some more.

I seem to need to put my code in the constructor:

public FARRTrayList(FARRCSharpPluginBase pluginBase)
            : base(pluginBase, "^tray")
        {            EnumTray.GetTrayData(out buttonData);       // populate tray data

            foreach (TrayIconData trayData in buttonData)
            {
                if (trayData.button.fsState != 8)     // only add if button is not invisible
                    SourceList.Add(new Actions.FARRTrayAction(trayData, m_TempPath));
                //if (this.Count > 10)
                //  break;
            }
}

If I put it in GetActionsCount it doesn't work. That's ok though. However, on executing a result, it does nothing except hide FARR. I have a simple MessageBox.Show() string printed at the moment (in Execute()), but the MessageBox doesn't show?

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #39 on: January 10, 2009, 06:00 AM »
now in order to do that, you NEED the new farr callback which was recently added (and is not yet in the C# api but i have on good authority it will be added soon)
Now, that's all that I needed :)

and then in your set_strvalue(name,value) event function that gets called by farr
This one is for vitalyb: what is the function(method) name in c# sdk that I need to override to catch this call or is it not yet implemented?
It is impossible to make anything foolproof because fools are so ingenious.

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #40 on: January 10, 2009, 06:04 AM »
If I put it in GetActionsCount it doesn't work. That's ok though. However, on executing a result, it does nothing except hide FARR. I have a simple MessageBox.Show() string printed at the moment (in Execute()), but the MessageBox doesn't show?

Try setting the path value of every item in the result list. It doesn't matter what it is, and results wont execute unless it is set. (at least from what I have seen)
It is impossible to make anything foolproof because fools are so ingenious.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #41 on: January 10, 2009, 06:17 PM »
Thanks skajfes, you're right about the PathItem needing to be set. It also appears that it needs to be unique. I just it to the same fixed string for each result, and it would only display 1 result. Change it to a result unique string and it lists all results.

Could you please explain what GetActionsCount does more? Do I need to use it? I currently do nothing with it, and don't appear to need to.

Further, I'm trying to remove all files in a set folder when my plugin is called. I have this code in a few places, but it only appears to be called when FARR is first loaded (and hence the plugin). I would have thought having it in the ActionList constructor would mean it got called everytime to the plugin got called, but doesn't appear to do so:

static string m_TempPath = null;

        public FARRTrayList(FARRCSharpPluginBase pluginBase)
            : base(pluginBase, "^tray")
        {
            m_TempPath = Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), "Temp");
            Directory.CreateDirectory(m_TempPath);
            string[] Files = Directory.GetFiles(m_TempPath);
            foreach (string FileName in Files)
            {
                File.Delete(FileName);
            }
           
            EnumTray.GetTrayData(out buttonData);       // populate tray data

            foreach (TrayIconData trayData in buttonData)
            {
                if (trayData.button.fsState != 8)     // only add if button is not invisible
                    SourceList.Add(new Actions.FARRTrayAction(trayData, m_TempPath));
                //if (this.Count > 10)
                //  break;
            }
        }

Edit: On further testing, it appears that FARR creates an instance of this plugin at runtime only. So using the above code, it is only called once, and hence my results list is not dynamic. How do I make the results list update each time the plugin is executed by it's regex? Is that what I need to use GetActionsCount for?

Edit again: I'm not sure if the above edit comment is actually correct. In some strange cases my first plugin call will not pickup the FARR tray icon, but sometimes after a while it does. But not another program loaded after FARR has started. It's a bit strange.

What I want to do is call
EnumTray.GetTrayData(out buttonData);

            foreach (TrayIconData trayData in buttonData)
            {
                if (trayData.button.fsState != 8)     // only add if button is not invisible
                    SourceList.Add(new Actions.FARRTrayAction(trayData, m_TempPath));
                //if (this.Count > 10)
                //  break;
            }
each time I execute the plugin by typing in it's regex.
« Last Edit: January 10, 2009, 07:35 PM by joshuawood »

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #42 on: January 11, 2009, 05:07 AM »
I think you should add your code that is supposed to execute every time the plugin is called in the GetActionsCount method (that's what I did). Maybe the Farr icon is not loaded because when farr is started(and your plugin with it) your plugin picks up the icon list just before FARR puts its icon in the tray.

So, every time the plugin is activated Farr calls GetActionsCount to get the number of results your plugin has to offer, so I think it is the best time to fill in the results.

Hope it helps
skajfes
It is impossible to make anything foolproof because fools are so ingenious.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #43 on: January 11, 2009, 02:30 PM »
That's what I think GetActionsCount does also - gets called everytime; but it doesn't appear to work for me. I will investigate further.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #44 on: January 12, 2009, 12:30 AM »
Ok, still don't get why it doesn't work for me. Here is what I have:
    class FARRTrayList : ActionsList
    {
        private TrayIconData[] buttonData = null;
        static string m_TempPath = null;

        public FARRTrayList(FARRCSharpPluginBase pluginBase)
            : base(pluginBase, "^tray")
        {
            m_TempPath = Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Temp");
            Directory.CreateDirectory(m_TempPath);

            //SourceList.Add(new Actions.FARRTrayAction(null, m_TempPath));
            //SourceList.Add(new Actions.FARRTrayAction(this.PluginBase));
        }

        public override int GetActionsCount(string KeyKeywords)
        {
            MessageBox.Show("In GAC, m_TempPath = " + m_TempPath);
            string[] Files = Directory.GetFiles(m_TempPath);
            MessageBox.Show(Files.Length.ToString());
            foreach (string FileName in Files)
            {
                MessageBox.Show("Deleting file: " + FileName.ToString());
                File.Delete(FileName);
            }

            EnumTray.GetTrayData(out buttonData);       // populate tray data

            if (buttonData != null)
            {
                foreach (TrayIconData trayData in buttonData)
                {
                    if (trayData.button.fsState != 8)
                    {    // only add if button is not invisible
                        MessageBox.Show("Found tray app: " + trayData.Text);
                        SourceList.Add(new Actions.FARRTrayAction(trayData, m_TempPath));
                    }
                    if (SourceList.Count > 10)
                        break;
                }
                MessageBox.Show("IN GAC, with data count: " + SourceList.Count);
                return SourceList.Count;
            }

            else
            {
                MessageBox.Show("IN GAC, with no data count");
                return 0;
            }
        }
    }

It appears to work ok, but something is still not quite right. The msgboxes get called correctly. Each time the msgbox will display each tray icon's name, and count them correctly (ie, they've been added to the SourceList). If I re-execute my plugin again after loading a new tray app, it is correctly enumerated, so it is now dynamic as desired. However, still no results show, even though it is getting the data correctly. It correctly deletes any existing icons.

Edit: I should mention that this section of code:
            EnumTray.GetTrayData(out buttonData);       // populate tray data

            if (buttonData != null)
            {
                foreach (TrayIconData trayData in buttonData)
                {
                    if (trayData.button.fsState != 8)
                    {    // only add if button is not invisible
                        MessageBox.Show("Found tray app: " + trayData.Text);
                        SourceList.Add(new Actions.FARRTrayAction(trayData, m_TempPath));
                    }
                    if (SourceList.Count > 10)
                        break;
                }
                MessageBox.Show("IN GAC, with data count: " + SourceList.Count);
                return SourceList.Count;
            }
without the msgboxes of course, does work as expect when placed in the constructor, except then it is not dynamic. The results will show however, unlike when in GAC. Hopefully I'm just missing something very simple.
« Last Edit: January 12, 2009, 12:34 AM by joshuawood »

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #45 on: January 12, 2009, 07:30 AM »
Sorry, my mistake, I said that you need to fill SourceList to get the results but you need to to fill "this" (your class is derived from a list so this.add() works just fine), and SourceList is used like a temporary storage for your data. So if you need to load your data just once do it in the constructor, and load the SourceList, and than in GetActionsCount you fill "this" so the items get displayed. I need my data to be fresh every time so i call the reloadClippings() method that loads the clips from a file and filter the results in regard of parameters passed (typed after plugin regex ). Here's the code:
public override int GetActionsCount(string KeyKeywords)
{
                       reloadClippings();     // loads the SourceList
KeyKeywords = GetSearch(KeyKeywords);  // strips plugin regex from the input sting

this.ClearTemporaryItems();
foreach (Actions.ClipboardAction Item in SourceList)
{
if (Item.Caption.ToLower().Contains(KeyKeywords))
this.Add(Item);
}

return this.Count;
}

It is impossible to make anything foolproof because fools are so ingenious.

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #46 on: January 12, 2009, 03:33 PM »
Still no luck. I understand what you're saying, it makes sense to have the results on the this Object, but I don't see why I should also need to populate SourceList. Anyways, whether I do or don't, it still doesn't work; again, this.Count returns the correct number of items, so it is populated correctly (I had a msgbox in there):

        public override int GetActionsCount(string KeyKeywords)
        {           
            string[] Files = Directory.GetFiles(m_TempPath);     // remove temp icon files       
            foreach (string FileName in Files)                       
                File.Delete(FileName);           

            SourceList.Clear();
            EnumTray.GetTrayData(out buttonData);       // populate tray data
            if (buttonData != null)
            {
                foreach (TrayIconData trayData in buttonData)   // fill SourceList
                {

                    if (trayData.button.fsState != 8)   // only add if button is not invisible
                        SourceList.Add(new Actions.FARRTrayAction(trayData, m_TempPath));
                    if (SourceList.Count > 10)
                        break;
                }
                this.ClearTemporaryItems();
                foreach (Actions.FARRTrayAction item in SourceList)     // Copy SourceList to thisList
                    this.Add(item);               
                return this.Count;
            }
            else return 0;           
        }

It seems the same as your code, except I do nothing with the search keywords as I don't need to (I think). I also need to reset the SL using SourceList.Clear()
« Last Edit: January 12, 2009, 03:55 PM by joshuawood »

joshuawood

  • Participant
  • Joined in 2008
  • *
  • default avatar
  • Posts: 22
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #47 on: January 16, 2009, 07:06 PM »
Ok I've got it working. Something else if a different place prevented the plugin from working correctly. Not sure why, but it's fixed.

Is there a way to register a Keyword rather than a RegEx to activate the plugin? I want FARR to use terms after my plugin word to filter results.

Eg, "tray" will list all items. "tray win" will list only tray  items containing "win". Mouser said that FARR will do this itself if tray is a keyword, but if it's a RegEx then I need to code it.

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 40,896
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Read more about this member.
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #48 on: January 16, 2009, 07:12 PM »
To expound on the issue:

There are two different ways that plugins can get triggered, one is by matching a plugin specified keyword on the left hand side of string.  The other is by matching a regex pattern supplied by the plugin.

The former should be used whenever appropriate since it allows FARR to be smarter about subsequent filtering;  regex should only be used when a plugin has a more advanced pattern to match.

skajfes

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 267
    • View Profile
    • Donate to Member
Re: FARR C# SDK and Documentation V2 (19/10/2008)
« Reply #49 on: January 17, 2009, 06:17 AM »
i don't know about keyword registering, but it is not such a problem to filter out the results. :)
It is impossible to make anything foolproof because fools are so ingenious.