Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 1,065
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: InvokeActionItem 10.2

[ Edited ]

WARNING: This is going to be a pretty long post, but I hope it will be helpful to some. I built a C++ class to wrap up all the ugly details and make this solution available to QML/JavaScript only developers as well as those comfortable with C++. I designed and built it this afternoon because:

 

  1. I like anything I know I'll use many times in my app to be neatly wrapped.
  2. I have a thing for class builders, so I created one for this class to make it easier to use.
  3. I didn't think it was fair that only us C++ devs could use this solution for the BB 10.2 InvokeQuery bug.

I'll post the C++ source code at the end, but first I want to tell you what this class does and how to use it:

 

QML Properties:

 

QString action
QUrl uri
QString
QByteArray data
FileTransferMode::Type fileTransferMode
int listId
QVariantMap metaData
QString mimeType
SecurityPerimeter::Type perimeter
InvokeTarget::Types targetTypes

These properties correspond to all the settings available on InvokeRequest. Just like other Cascades class properties, they can also be accessed from C++ directly with get and set functions. So, for instance, you can obtain listID with Invoker::listId() and set it with Invoker::setListId(). Each of these properties also has a builder argument function so you can set up Invoker in a single line. More on this later.

 

Incidentally, unlike the regular Cascades and Qt classes, all my setter functions return the old value of the setting rather than void so in addition to setting the value it is easy to restore it later, like this:

 

int oldListId = invoker.setListId( newListId );
...
...
... Do stuff...
...
...
invoker.setListId( oldListId );

In addition to these InvokeRequest mirror properties, Invoker has a few of its own:

 

bool valid: true if Invoker initialized itself ok, false otherwise.
InvokeReplyError::Type lastError: the result of the last invocation.
QString lastErrorText: a human readable version of lastError.

All three of these are read only, and have get functions only for C++.

 

Signals:

 

Invoker only emits two signals:

 

invocationFinished(): The invocation finished successfully.
invocationFailed(): The invocation failed.

In your handler for invocationFailed you can find out what went wrong by checking the lastError property.

 

Builder:

 

I really like having a builder for classes with many parameters. All the invocation parameters for Invoker can be set in a single line:

 

Invoker* invoker = Invoker::create().parent(this)
.action("action").uri("http://uri").target("target").data(data)
.fileTransferMode(transferMode).listId(2).metaData(metaData)
.mimeType("mimeType").perimeter(perimeter).targetTypes(types);

 

Invocation:

 

Once you have an instance of Invoker configured you can execute it with Invoker::Invoke(). This function is Q_INVOKABLE so you can call it from QML too. Unfortunately you can't declare a member function as both a slot and Q_INVOKABLE so there is a distinct invocation slot with a slightly different name: invokeSlot(). You can connect this slot directly to the triggered() signal of an ActionItem, for instance.

 

QML/JavaScript;

 

This class was designed to make invocation as easy from QML as from C++. First you need to make it available to QML with qRegisterType():

 

qmlRegisterType<Invoker>( "MyCustomClasses", 1, 0, "Invoker" );

I usually put this line at the beginning of main(). Then at the top of your QML file put the line:

 

import MyCustomClasses 1.0

Now you can access Invoker in your QML. The easiest way to use it is to attach it to a Page:

 

Page {
   attachedObjects: [
      Invoker {
         id:invoker
         action: "bb.action.OPEN"
         target: "sys.browser"
         onInvocationFailed: {
            var errMsg = "Invocation Failed: " + uri + " (" + lastErrorText() + ")";
         }
      }
   ]
function doInvocation() {
invoker.uri = "TargetURL";
invoker.invoke();
}
}

 

When you execute doInvocation() the URL is opened in the full browser.

 

Caveats:

 

This class was designed and built in an afternoon. I tested it in both C++ and QML, and it worked as intended, but my tests were far from exhaustive. I am pretty confident in the design of this class, but I make no guarantees it will work for you as-is.

 

License:

 

I am attaching the Creative Commons CC By 3.0 license to this work. What this means is that you are free to use it in your own code as you like, even commercially, and alter it however you wish, but if you pass it on to someone else just give me credit and ask that they do the same.

 

The Source:

 

Invoker.hpp:

 

/*
 * Invoker.hpp
 *
 *  Created on: Oct 28, 2013
 *      Author: Martin R. Green
 *     Licence: CC By 3.0 (http://creativecommons.org/licenses/by/3.0)
 *
 */

#ifndef INVOKER_HPP_
#define INVOKER_HPP_

#include <bb/cascades/BaseObject>
#include <InvokeManager>
#include <InvokeReply>
#include <InvokeTargetReply>
#include <InvokeRequest>

using namespace bb::system;

class Invoker: public bb::cascades::BaseObject
{
    Q_OBJECT

    InvokeRequest* _request;

    InvokeReplyError::Type _lastError;
    Q_PROPERTY(InvokeReplyError::Type lastError READ lastError)
    Q_PROPERTY(QString lastErrorText READ lastErrorText)
    Q_PROPERTY(bool valid READ valid)

    // ---InvokeRequest properties
    Q_PROPERTY(QString action READ action WRITE setAction)
    Q_PROPERTY(QUrl uri READ uri WRITE setUri)
    Q_PROPERTY(QString target READ target WRITE setTarget)
    Q_PROPERTY(QByteArray data READ data WRITE setData)
    Q_PROPERTY(FileTransferMode::Type fileTransferMode READ fileTransferMode WRITE setFileTransferMode)
    Q_PROPERTY(int listId READ listId WRITE setListId)
    Q_PROPERTY(QVariantMap metaData READ metaData WRITE setMetaData)
    Q_PROPERTY(QString mimeType READ mimeType WRITE setMimeType)
    Q_PROPERTY(SecurityPerimeter::Type perimeter READ perimeter WRITE setPerimeter)
    Q_PROPERTY(InvokeTarget::Types targetTypes READ targetTypes WRITE setTargetTypes)

private Q_SLOTS:
    void invokeReplyFinishedHandler();

Q_SIGNALS:
    void invocationFinished();
    void invocationFailed();

public:
    Invoker( QObject* parent = NULL );
    ~Invoker();

    Q_INVOKABLE void invoke();

    // ---Can't make a slot Q_INVOKABLE so need a separate slot
    Q_SLOT void invokeSlot();

    // ---Accessors
    bool valid();
    InvokeReplyError::Type lastError();
    QString lastErrorText();

    QString action();
    Q_SLOT QString setAction( const QString& action );

    QUrl uri() const;
    Q_SLOT QUrl setUri ( const QUrl& uri ) const;
    Q_SLOT QString setUri ( const QString& uri ) const;
    Q_SLOT char* setUri ( const char* uri ) const;

    QString target() const;
    Q_SLOT QString setTarget( const QString& target ) const;

    QByteArray data();
    Q_SLOT QByteArray setData(const QByteArray& data );

    FileTransferMode::Type fileTransferMode();
    Q_SLOT FileTransferMode::Type setFileTransferMode( FileTransferMode::Type fileTransferMode );

    int listId();
    Q_SLOT int setListId( int listId );

    QVariantMap metaData() const;
    Q_SLOT QVariantMap setMetaData( const QVariantMap& metaData ) const;

    QString mimeType() const;
    Q_SLOT QString setMimeType( const QString& mimeType ) const;

    SecurityPerimeter::Type perimeter();
    Q_SLOT SecurityPerimeter::Type setPerimeter( SecurityPerimeter::Type perimeter );

    InvokeTarget::Types targetTypes();
    Q_SLOT InvokeTarget::Types setTargetTypes( InvokeTarget::Types targetTypes );

    // ---Builder template
    template<typename BuilderType, typename BuiltType>
    class TBuilder: public BaseObject::TBuilder<BuilderType, BuiltType>
    {
    protected:
        TBuilder( BuiltType* node ) :
            BaseObject::TBuilder<BuilderType, BuiltType>( node ) {
        }
    public:

        // ---Builder parameters
        BuilderType& parent( BaseObject* parent ) {
            this->instance().setParent( parent );
            return this->builder();
        }

        BuilderType& action( const QString& action ) {
            this->instance().setAction( action );
            return this->builder();
        }

        BuilderType& uri( const QUrl& uri ) {
            this->instance().setUri( uri );
            return this->builder();
        }

        BuilderType& uri( const QString& uri ) {
            this->instance().setUri( uri );
            return this->builder();
        }

        BuilderType& uri( const char* action ) {
            this->instance().setUri( action );
            return this->builder();
        }

        BuilderType& target( const QString& target ) {
            this->instance().setTarget( target );
            return this->builder();
        }

        BuilderType& data( const QByteArray& data ) {
            this->instance().setData( data );
            return this->builder();
        }

        BuilderType& fileTransferMode( FileTransferMode::Type fileTransferMode ) {
            this->instance().setFileTransferMode( fileTransferMode );
            return this->builder();
        }

        BuilderType& listId( int listId ) {
            this->instance().setListId( listId );
            return this->builder();
        }

        BuilderType& metaData( const QVariantMap& metaData ) {
            this->instance().setMetaData( metaData );
            return this->builder();
        }

        BuilderType& mimeType( const QString& mimeType ) {
            this->instance().setMimeType( mimeType );
            return this->builder();
        }

        BuilderType& perimeter( SecurityPerimeter::Type perimeter ) {
            this->instance().setPerimeter( perimeter );
            return this->builder();
        }

        BuilderType& targetTypes( InvokeTarget::Types targetTypes ) {
            this->instance().setTargetTypes( targetTypes );
            return this->builder();
        }
    };

    class Builder: public TBuilder<Builder, Invoker>
    {
    public:
        Builder() : TBuilder<Builder, Invoker>( new Invoker() ) {
        }
    };

    static Builder create() {
        return Builder();
    }
};

#endif /* INVOKER_HPP_ */

 

Invoker.cpp:

 

/*
 * Invoker.cpp
 *
 *  Created on: Oct 28, 2013
 *      Author: Martin R. Green
 *     Licence: CC By 3.0 (http://creativecommons.org/licenses/by/3.0)
 *
 */

#include "Invoker.hpp"

Invoker::Invoker( QObject* parent ) :
        BaseObject( parent ) {
    this->_lastError = InvokeReplyError::None;

    try {
        this->_request = new InvokeRequest();

    } catch ( ... ) {
        this->_request = NULL;
    }
}

Invoker::~Invoker() {
if( this->_request ) delete this->_request; } void Invoker::invoke() { if ( this->_request ) { InvokeManager* manager = new InvokeManager(); InvokeTargetReply* reply = manager->invoke( *this->_request ); if ( reply ) { bool success; Q_UNUSED( success ) // ---Make sure the manager gets deleted when the invocation reply is finished processing success = QObject::connect( reply, SIGNAL(finished()), manager, SLOT(deleteLater()) ); Q_ASSERT( success ); // ---Allow error checking and cleanup when the invocation reply is finished processing success = QObject::connect( reply, SIGNAL(finished()), this, SLOT(invokeReplyFinishedHandler()) ); Q_ASSERT( success ); } } } void Invoker::invokeSlot() { this->invoke(); } void Invoker::invokeReplyFinishedHandler() { InvokeTargetReply* reply = qobject_cast<InvokeTargetReply*>( sender() ); if ( ( this->_lastError = reply->error() ) != InvokeReplyError::None ) { emit invocationFailed(); } else { emit invocationFinished(); } reply->deleteLater(); } // ---Accessors bool Invoker::valid() { return this->_request; } InvokeReplyError::Type Invoker::lastError() { return this->_lastError; } QString Invoker::lastErrorText() { switch ( this->_lastError ) { case InvokeReplyError::BadRequest: return "Bad Request"; case InvokeReplyError::InsufficientPrivileges: return "Insufficient Privileges"; case InvokeReplyError::Internal: return "Internal Error"; case InvokeReplyError::NoTarget: return "No Target Found"; case InvokeReplyError::Target: return "Target Failed"; case InvokeReplyError::TargetNotOwned: return "Target Not Owned"; case InvokeReplyError::None: break; } return ""; } QString Invoker::action() { return ( this->_request ) ? this->_request->action() : QString::null; } QString Invoker::setAction( const QString& action ) { if ( this->_request ) { QString oldVal = this->_request->action(); this->_request->setAction( action ); return oldVal; } else return QString::null; } QUrl Invoker::uri() const { return ( this->_request ) ? this->_request->uri() : QUrl(); } QUrl Invoker::setUri( const QUrl& uri ) const { if ( this->_request ) { QUrl oldUri = this->_request->uri(); this->_request->setUri( uri ); return oldUri; } else return QUrl(); } QString Invoker::setUri( const QString& uri ) const { if ( this->_request ) { QUrl oldUri = this->_request->uri(); this->_request->setUri( uri ); return oldUri.toString(); } else return QString::null; } char* Invoker::setUri( const char* uri ) const { if ( this->_request ) { QUrl oldUri = this->_request->uri(); this->_request->setUri( uri ); return oldUri.toString().toLatin1().data(); } else return NULL; } QString Invoker::target() const { return ( this->_request ) ? this->_request->target() : QString::null; } QString Invoker::setTarget( const QString& target ) const { if ( this->_request ) { QString oldTarget = this->_request->target(); this->_request->setTarget( target ); return oldTarget; } else return QString::null; } QByteArray Invoker::data() { if ( this->_request ) { return this->_request->data(); } else return QByteArray(); } QByteArray Invoker::setData( const QByteArray& data ) { if ( this->_request ) { QByteArray oldData = this->_request->data(); this->_request->setData( data ); return oldData; } else return QByteArray(); } FileTransferMode::Type Invoker::fileTransferMode() { return ( this->_request ) ? this->_request->fileTransferMode() : FileTransferMode::Unspecified; } FileTransferMode::Type Invoker::setFileTransferMode( FileTransferMode::Type fileTransferMode ) { if ( this->_request ) { FileTransferMode::Type oldMode = this->_request->fileTransferMode(); this->_request->setFileTransferMode( fileTransferMode ); return oldMode; } else return FileTransferMode::Unspecified; } int Invoker::listId() { return ( this->_request ) ? this->_request->listId() : 0; } int Invoker::setListId( int listId ) { if ( this->_request ) { int oldId = this->_request->listId(); this->_request->setListId( listId ); return oldId; } else return 0; } QVariantMap Invoker::metaData() const { return ( this->_request ) ? this->_request->metadata() : QVariantMap(); } QVariantMap Invoker::setMetaData( const QVariantMap& metaData ) const { if ( this->_request ) { QVariantMap oldMetaData = this->_request->metadata(); this->_request->setMetadata( metaData ); return oldMetaData; } else return QVariantMap(); } QString Invoker::mimeType() const { return ( this->_request ) ? this->_request->mimeType() : QString::null; } QString Invoker::setMimeType( const QString& mimeType ) const { if ( this->_request ) { QString oldMimeType = this->_request->mimeType(); this->_request->setMimeType( mimeType ); return oldMimeType; } else return QString::null; } SecurityPerimeter::Type Invoker::perimeter() { return ( this->_request ) ? this->_request->perimeter() : SecurityPerimeter::Default; } SecurityPerimeter::Type Invoker::setPerimeter( SecurityPerimeter::Type perimeter ) { if ( this->_request ) { SecurityPerimeter::Type oldPerimeter = this->_request->perimeter(); this->_request->setPerimeter( perimeter ); return oldPerimeter; } else return SecurityPerimeter::Default; } InvokeTarget::Types Invoker::targetTypes() { return ( this->_request ) ? this->_request->targetTypes() : InvokeTarget::Unspecified; } InvokeTarget::Types Invoker::setTargetTypes( InvokeTarget::Types targetTypes ) { if ( this->_request ) { InvokeTarget::Types oldTypes = this->_request->targetTypes(); this->_request->setTargetTypes( targetTypes ); return oldTypes; } else return InvokeTarget::Unspecified; }

 



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
Developer
Posts: 826
Registered: ‎10-16-2012
My Device: Red Z10
My Carrier: Rogers

Re: InvokeActionItem 10.2

[ Edited ]

That's an excellent example of qml/c++ integration... gotta say (from scratch) it seems like a ton of work for something so simple though.

 

Thanks for sharing =)

Retired
Posts: 749
Registered: ‎12-16-2008
My Device: BlackBerry Z30
My Carrier: Bell

Re: InvokeActionItem 10.2

That's a great sample! Have you considered contributing it to the Cascades Community Samples repo on GitHub? It's not hard to get involved, would make it easier for people to find, and make it easier to track any changes or improvements made.

 

If you (or anyone else) want to get started, this is a good place: http://devblog.blackberry.com/2013/05/blackberry-open-source/

Paul Bernhardt
Application Development Consultant
BlackBerry
@PBernhardt

Did this answer your question? Please accept this post as the solution.
Found a bug? Report it to the Developer Issue Tracker
Developer
Posts: 1,065
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: InvokeActionItem 10.2

[ Edited ]

Yes it was a lot of work, but I put that much effort into for a few reasons.

 

  • This solution for the InvokeQuery bug was only doable from C++. There are huge numbers of devs who build entirely in QML/JavaScript. I wanted to provide a solution that worked for them too. Plus I can see myself wanting to invoke this way from QML too, even though my app currently does it all in C++.
  • As I said in my tutorial post, if I think I will want to use something repeatedly in future I like to wrap it up neatly.
  • I planned from the start to share this class, so I wanted it to be as robust as possible so I wan't constantly bombarded with usage and support questions. LOL

slashkyle wrote:

That's an excellent example of qml/c++ integration... gotta say (from scratch) it seems like a ton of work for something so simple though.

 

Thanks for sharing =)






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
Developer
Posts: 1,065
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: InvokeActionItem 10.2

Yes, I will consider submitting this, but it won't happen for a while since I'm feverishly working to get a new version of multiFEED out, including this InvokeQuery fix.


PBernhardt wrote:

That's a great sample! Have you considered contributing it to the Cascades Community Samples repo on GitHub? It's not hard to get involved, would make it easier for people to find, and make it easier to track any changes or improvements made.

 

If you (or anyone else) want to get started, this is a good place: http://devblog.blackberry.com/2013/05/blackberry-open-source/






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
Highlighted
Developer
Posts: 1,065
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: InvokeActionItem 10.2

IMPORTANT: Anyone who copied my source code will probably want to redownload the .cpp file again since I made a small change in the Invoker::~Invoker() function to check that the request object is valid before trying to delete it.



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
Developer
Posts: 93
Registered: ‎07-30-2014
My Device: Blackberry z10 STL100-1
My Carrier: Blackberry

Re: InvokeActionItem 10.2

hello, greenmr Smiley Happy in my project i am using these integration to work invokation with cascades, but i am facing a error in invoker.hpp on debugging here is a consol log.. please help

19:32:25 **** Incremental Build of configuration Device-Debug for project CascadesProject ****
make -j4 Device-Debug 
make -C .//translations -f Makefile update
make[1]: Entering directory 'D:/pro/CascadesProject/translations'
c:/bbndk/host_10_3_1_12/win32/x86/usr/bin/lupdate CascadesProject.pro
lupdate warning: no TS files specified. Only diagnostics will be produced for 'CascadesProject.pro'.
make[1]: Leaving directory 'D:/pro/CascadesProject/translations'
make -C .//translations -f Makefile release
make[1]: Entering directory 'D:/pro/CascadesProject/translations'
c:/bbndk/host_10_3_1_12/win32/x86/usr/bin/lrelease CascadesProject.pro
lrelease warning: Met no 'TRANSLATIONS' entry in project file 'CascadesProject.pro'
make[1]: Leaving directory 'D:/pro/CascadesProject/translations'
make -C ./arm -f Makefile debug
make[1]: Entering directory 'D:/pro/CascadesProject/arm'
make -f Makefile.Debug
make[2]: Entering directory 'D:/pro/CascadesProject/arm'
qcc -Vgcc_ntoarmv7le -c -Wc,-include -Wc,o.le-v7-g/.obj/CascadesProject -Wno-psabi -lang-c++ -fstack-protector -fstack-protector-all -mcpu=cortex-a9 -g -Wno-psabi -Wall -W -D_REENTRANT -DQT_NO_IMPORT_QT47_QML -DQ_OS_BLACKBERRY -DQT_DECLARATIVE_DEBUG -DQT_DECLARATIVE_LIB -DQT_CORE_LIB -DQT_SHARED -Ic:/bbndk/target_10_3_1_995/qnx6/usr/share/qt4/mkspecs/blackberry-armv7le-qcc -I../../CascadesProject -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/qt4/QtCore -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/qt4/QtDeclarative -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/qt4 -Io.le-v7-g/.moc -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/bb1 -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/freetype2 -I. -o o.le-v7-g/.obj/Invoker.o ../src/Invoker.cpp
qcc -Vgcc_ntoarmv7le -c -Wc,-include -Wc,o.le-v7-g/.obj/CascadesProject -Wno-psabi -lang-c++ -fstack-protector -fstack-protector-all -mcpu=cortex-a9 -g -Wno-psabi -Wall -W -D_REENTRANT -DQT_NO_IMPORT_QT47_QML -DQ_OS_BLACKBERRY -DQT_DECLARATIVE_DEBUG -DQT_DECLARATIVE_LIB -DQT_CORE_LIB -DQT_SHARED -Ic:/bbndk/target_10_3_1_995/qnx6/usr/share/qt4/mkspecs/blackberry-armv7le-qcc -I../../CascadesProject -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/qt4/QtCore -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/qt4/QtDeclarative -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/qt4 -Io.le-v7-g/.moc -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/bb1 -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include -Ic:/bbndk/target_10_3_1_995/qnx6/usr/include/freetype2 -I. -o o.le-v7-g/.obj/moc_Invoker.o o.le-v7-g/.moc/moc_Invoker.cpp
In file included from ../src/Invoker.cpp:1:0:
../src/Invoker.hpp:9:25: fatal error: InvokeManager: No such file or directory
compilation terminated.
In file included from o.le-v7-g/.moc/moc_Invoker.cpp:9:0:
o.le-v7-g/.moc/../../../src/Invoker.hpp:9:25: fatal error: InvokeManager: No such file or directory
compilation terminated.
cc: c:/bbndk/host_10_3_1_12/win32/x86/usr/lib/gcc/arm-unknown-nto-qnx8.0.0eabi/4.6.3/cc1plus caught signal 1
Makefile.Debug:187: recipe for target 'o.le-v7-g/.obj/Invoker.o' failed
make[2]: *** [o.le-v7-g/.obj/Invoker.o] Error 1
make[2]: *** Waiting for unfinished jobs....
cc: c:/bbndk/host_10_3_1_12/win32/x86/usr/lib/gcc/arm-unknown-nto-qnx8.0.0eabi/4.6.3/cc1plus caught signal 1
Makefile.Debug:202: recipe for target 'o.le-v7-g/.obj/moc_Invoker.o' failed
make[2]: *** [o.le-v7-g/.obj/moc_Invoker.o] Error 1
make[2]: Leaving directory 'D:/pro/CascadesProject/arm'
Makefile:50: recipe for target 'debug' failed
make[1]: *** [debug] Error 2
make[1]: Leaving directory 'D:/pro/CascadesProject/arm'
mk/cs-base.mk:31: recipe for target 'Device-Debug' failed
make: *** [Device-Debug] Error 2

 

 

.saini
Developer
Posts: 1,065
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: InvokeActionItem 10.2

[ Edited ]

I suspect you don't have bb/system in your include locations. There are two things you can do to resolve this. Either add the path to the beginning of the affected #includes, or add the bb/system path to your include locations. To do the former:

 

Change:

#include <InvokeManager>
#include <InvokeReply>
#include <InvokeTargetReply>
#include <InvokeRequest>

...to this:

#include <bb/system/InvokeManager>
#include <bb/system/InvokeReply>
#include <bb/system/InvokeTargetReply>
#include <bb/system/InvokeRequest>

 

Although that will work, I suggest the better solution is to add the bb/system path to your project settings. If you added the bbsystem library to your app using Project->Add Library...->Standard BlackBerry platform library->User interfaces->Blackberry System then the include path should have already been added to your project. If, however, you edited your .pro file directly to add the library then you will have to add the include path to your project manually too. Add the following to each of your project's build settings (Project->Properties->C/C++ General->Paths and Symbols->GNU C):

 

${QNX_TARGET}/usr/include/bb/system

Note that you have to do this for each of your project's build profiles (Debug-Simulator, Debug-Device, Release-Device...).



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.