<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Th30z - Coding on the Fly &#187; Carbon</title>
	<atom:link href="http://th30z.netsons.org/tag/carbon/feed/" rel="self" type="application/rss+xml" />
	<link>http://th30z.netsons.org</link>
	<description>Matteo Bertozzi, Objective-C, Cocoa, C, C++, Qt4, iPhone, Mac OS X, Open Moko, Matteo Bertozzi Development</description>
	<lastBuildDate>Sun, 22 Nov 2009 09:47:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Qt4 Mac SearchBox Wrapper</title>
		<link>http://th30z.netsons.org/2008/08/qt4-mac-searchbox-wrapper/</link>
		<comments>http://th30z.netsons.org/2008/08/qt4-mac-searchbox-wrapper/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 07:30:19 +0000</pubDate>
		<dc:creator>Matteo Bertozzi</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Qt4]]></category>
		<category><![CDATA[Carbon]]></category>

		<guid isPermaLink="false">http://th30z.netsons.org/?p=130</guid>
		<description><![CDATA[Do you want to use Mac OS X SearchBox in your Qt Application? Ok, pick up your XCode or your preferred code editor and we&#8217;ll start to write a Qt Wrapper for Carbon HISearchField.

The Header File will be something like this, with two signals textChanged(const QString&#38;) that will be used to &#8220;Filter on the Fly&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>Do you want to use Mac OS X SearchBox in your Qt Application? Ok, pick up your XCode or your preferred code editor and we&#8217;ll start to write a Qt Wrapper for Carbon <em>HISearchField</em>.</p>
<p style="text-align: center;"><a href="http://th30z.netsons.org/wp-content/uploads/mac-searchbox.png"><img class="aligncenter size-full wp-image-131" title="Mac SearchBox" src="http://th30z.netsons.org/wp-content/uploads/mac-searchbox.png" alt="" width="225" height="50" /></a></p>
<p>The Header File will be something like this, with two signals <em>textChanged(const QString&amp;)</em> that will be used to &#8220;<em>Filter on the Fly</em>&#8221; it will be raised when the user type something, <em>findNext()</em> will be raised when user press Return Button.</p>
<pre>#if defined(Q_WS_MAC) &amp;&amp; !defined(_QF_MAC_SEARCHBOX_H_)
#define _QF_MAC_SEARCHBOX_H_

// Qt4 Headers
#include &lt;QWidget&gt;

// Mac OS X - Carbon Headers
#include &lt;Carbon/Carbon.h&gt;

class QfMacSearchBox : public QWidget {
    Q_OBJECT

    public:
        QfMacSearchBox (QWidget *parent = 0);
        ~QfMacSearchBox();

        // Methods
        void raiseTextChanged (void);
        void raiseFindNext (void);

        QSize sizeHint (void) const;

        // GET Properties
        QString text (void) const;

    signals:
        void textChanged (const QString&amp; text);
        void findNext (void);

    public slots:
        void setText (const QString&amp; text);
        void clear (void);

    private:
        CFStringRef searchFieldText;
        HIViewRef searchField;
};

#endif // Q_WS_MAC &amp;&amp; !_QF_MAC_SEARCHBOX_H_</pre>
<p>And now the Class Implementation. I&#8217;ve internally managed the clear button, so you haven&#8217;t a clear signals but a <em>textChanged(const QString&amp;)</em> signal with an empty string.</p>
<pre>// Qt4 Headers
#include &lt;QVarLengthArray&gt;
#include &lt;QMenu&gt;

// SearchBox Headers
#include "searchbox_mac.h"

// =======================================
//  MacSearchBox: PRIVATE FILE Methods
// =======================================
static QString toQString(CFStringRef str) {
    if(!str)
        return QString();

    CFIndex length = CFStringGetLength(str);
    const UniChar *chars = CFStringGetCharactersPtr(str);
    if (chars)
        return QString(reinterpret_cast&lt;const QChar *&gt;(chars), length);

    QVarLengthArray&lt;UniChar&gt; buffer(length);
    CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
    return QString(reinterpret_cast&lt;const QChar *&gt;(buffer.constData()), length);
}

static OSStatus SearchFieldEventHandler(EventHandlerCallRef handlerCallRef,
                                        EventRef event, void *userData)
{
    QfMacSearchBox *searchBox = (QfMacSearchBox *) userData;
    OSType eventClass = GetEventClass(event);
    UInt32 eventKind = GetEventKind(event);

    if (eventClass == kEventClassSearchField) {
        switch (eventKind) {
            case kEventSearchFieldCancelClicked:
                searchBox-&gt;clear();
                break;
            case kEventSearchFieldSearchClicked:
                searchBox-&gt;raiseFindNext();
                break;
            default:
                break;
        }
    } else if (eventClass == kEventClassTextField) {
        switch (eventKind) {
            case kEventTextDidChange:
                searchBox-&gt;raiseTextChanged();
                break;
            case kEventTextAccepted:
                searchBox-&gt;raiseFindNext();
                break;
            default:
                break;
        }
    }

    return(eventNotHandledErr);
}

// =======================================
//  MacSearchBox: PUBLIC Constructors/Destructors
// =======================================
QfMacSearchBox::QfMacSearchBox (QWidget *parent)
    : QWidget(parent)
{
    // Set Widget Properties
    //setFocusPolicy(Qt::StrongFocus);
    setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));

    // Create a native search field and pass its window id to QWidget::create.
    searchFieldText = CFStringCreateWithCString(0,
                                     (const char *) tr("Search").toAscii(), 0);
    HISearchFieldCreate(NULL, kHISearchFieldAttributesSearchIcon |
                              kHISearchFieldAttributesCancel,
                        NULL, searchFieldText, &amp;searchField);
    create(reinterpret_cast&lt;WId&gt;(searchField));

    // Subscribe Events
    EventTypeSpec mySFieldEvents[] = {
                     { kEventClassSearchField, kEventSearchFieldCancelClicked },
                     { kEventClassTextField, kEventTextDidChange },
                     { kEventClassTextField, kEventTextAccepted }
                 };

    HIViewInstallEventHandler(searchField, SearchFieldEventHandler,
                              GetEventTypeCount(mySFieldEvents), mySFieldEvents,
                              (void *) this, NULL);

    // Use a Qt menu for the search field menu.
    QMenu *searchMenu = new QMenu(this);

    QAction *indexAction = searchMenu-&gt;addAction(tr("Index Search"));
    indexAction-&gt;setCheckable(true);
    indexAction-&gt;setChecked(true);

    QAction *fulltextAction = searchMenu-&gt;addAction(tr("Full Text Search"));
    fulltextAction-&gt;setCheckable(true);

    QActionGroup *searchActionGroup = new QActionGroup(this);
    searchActionGroup-&gt;addAction(indexAction);
    searchActionGroup-&gt;addAction(fulltextAction);
    searchActionGroup-&gt;setExclusive(true);

    MenuRef macSearchMenu = searchMenu-&gt;macMenu(0);
    HISearchFieldSetSearchMenu(searchField, macSearchMenu);
}

QfMacSearchBox::~QfMacSearchBox() {
    CFRelease(searchField);
    CFRelease(searchFieldText);
}

// =======================================
//  MacSearchBox: PUBLIC Methods
// =======================================
void QfMacSearchBox::raiseTextChanged (void) {
    emit textChanged(text());
}

void QfMacSearchBox::raiseFindNext (void) {
    emit findNext();
}

QSize QfMacSearchBox::sizeHint (void) const {
    HIRect optimalBounds;
    EventRef event;

    CreateEvent(0, kEventClassControl, kEventControlGetOptimalBounds,
                GetCurrentEventTime(), kEventAttributeUserEvent, &amp;event);

    SendEventToEventTargetWithOptions(event,
                                HIObjectGetEventTarget(HIObjectRef(winId())),
                                kEventTargetDontPropagate);

    GetEventParameter(event, kEventParamControlOptimalBounds, typeHIRect,
                      0, sizeof(HIRect), 0, &amp;optimalBounds);

    ReleaseEvent(event);
    return QSize(optimalBounds.size.width + 200, optimalBounds.size.height);
}

// =======================================
//  MacSearchBox: PUBLIC GET Properties
// =======================================
QString QfMacSearchBox::text (void) const {
    CFStringRef cfString = HIViewCopyText(searchField);
    QString text = toQString(cfString);
    CFRelease(cfString);
    return(text);
}

// =======================================
//  MacSearchBox: PUBLIC SET Properties
// =======================================
void QfMacSearchBox::setText (const QString&amp; text) {
    CFRelease(searchFieldText);

    searchFieldText = CFStringCreateWithCString(0,
                          (const char *) text.toAscii(), 0);
    HIViewSetText(searchField, searchFieldText);

    emit textChanged(text);
}

void QfMacSearchBox::clear (void) {
    setText(QString());
}</pre>
<p>That&#8217;s all folks.</p>
]]></content:encoded>
			<wfw:commentRss>http://th30z.netsons.org/2008/08/qt4-mac-searchbox-wrapper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt4 Mac Dock Icon Click</title>
		<link>http://th30z.netsons.org/2008/08/123/</link>
		<comments>http://th30z.netsons.org/2008/08/123/#comments</comments>
		<pubDate>Mon, 11 Aug 2008 17:38:27 +0000</pubDate>
		<dc:creator>Matteo Bertozzi</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Qt4]]></category>
		<category><![CDATA[Carbon]]></category>

		<guid isPermaLink="false">http://th30z.netsons.org/2008/08/123/</guid>
		<description><![CDATA[When you click the &#8220;close button&#8221; of an application&#8217;s window, on Mac OS X the window will be hidden but the application continue running. When you click on the Dock Icon, the application&#8217;s window will be showed. This is the default behaviour for Mac Apps but Qt Apps doesn&#8217;t the same. So, how we could [...]]]></description>
			<content:encoded><![CDATA[<p>When you click the &#8220;close button&#8221; of an application&#8217;s window, on Mac OS X the window will be hidden but the application continue running. When you click on the Dock Icon, the application&#8217;s window will be showed. This is the default behaviour for Mac Apps but Qt Apps doesn&#8217;t the same. So, how we could implement this behaviour?</p>
<pre>#ifndef _APPLICATION_H_
#define _APPLICATION_H_

// Qt4 Headers
include &lt;QApplication&gt;
include &lt;QWidget&gt;

// Carbon Headers
#ifdef Q_WS_MAC
    #include &lt;Carbon/Carbon.h&gt;
#endif

class Application : public QApplication {
    Q_OBJECT

    public:
        Application (int&amp; argc, char **argv);

         QWidget *mainWindow (void) const;

    private:
         QWidget *m_mainWindow;

#ifdef Q_WS_MAC
    AEEventHandlerUPP m_appleEventProcessorUPP;
#endif
};

#endif // !_APPLICATION_H_</pre>
<p>Here, we&#8217;ve implemented an Application class that Inherits from QApplication. This class contains a reference to the App&#8217;s Main Window.</p>
<pre>#ifdef Q_WS_MAC
static OSStatus appleEventProcessor(const AppleEvent *ae,
                                    AppleEvent *event,
                                    long handlerRefCon)
{
    Application *app = (Application *) handlerRefCon;

     OSType aeID = typeWildCard;
     OSType aeClass = typeWildCard;

     AEGetAttributePtr(ae, keyEventClassAttr, typeType, 0,
                       &amp;aeClass, sizeof(aeClass), 0);
     AEGetAttributePtr(ae, keyEventIDAttr, typeType, 0,
                       &amp;aeID, sizeof(aeID), 0);

     if (aeClass == kCoreEventClass) {
          if (aeID == kAEReopenApplication) {
               app-&gt;mainWindow()-&gt;show();
          }
          return noErr;
    }

    return eventNotHandledErr;
}
#endif

Application::Application (int&amp; argc, char **argv)
    : QApplication(argc, argv)
{
    // Don't Quit the App on Window Close
    setQuitOnLastWindowClosed(false);

    // Initialize Main Window
    m_mainWindow = new QLabel("Test Main Window");

#ifdef Q_WS_MAC
    // Install Reopen Application Event (Dock Clicked)
    m_appleEventProcessorUPP = AEEventHandlerUPP(appleEventProcessor);
    AEInstallEventHandler(kCoreEventClass, kAEReopenApplication,
                          m_appleEventProcessorUPP, (long) this, true);
#endif
}

QWidget *Application::mainWindow (void) const {
    return(m_mainWindow);
}</pre>
<p>Thats all folks! Run the app, Click on close button and then click on the dock icon to see the result.</p>
]]></content:encoded>
			<wfw:commentRss>http://th30z.netsons.org/2008/08/123/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
