<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- addressbook.qdoc --> <title>Qt 4.8: Part 7 - Additional Features</title> <link rel="stylesheet" type="text/css" href="style/style.css" /> <script src="scripts/jquery.js" type="text/javascript"></script> <script src="scripts/functions.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="style/superfish.css" /> <link rel="stylesheet" type="text/css" href="style/narrow.css" /> <!--[if IE]> <meta name="MSSmartTagsPreventParsing" content="true"> <meta http-equiv="imagetoolbar" content="no"> <![endif]--> <!--[if lt IE 7]> <link rel="stylesheet" type="text/css" href="style/style_ie6.css"> <![endif]--> <!--[if IE 7]> <link rel="stylesheet" type="text/css" href="style/style_ie7.css"> <![endif]--> <!--[if IE 8]> <link rel="stylesheet" type="text/css" href="style/style_ie8.css"> <![endif]--> <script src="scripts/superfish.js" type="text/javascript"></script> <script src="scripts/narrow.js" type="text/javascript"></script> </head> <body class="" onload="CheckEmptyAndLoadList();"> <div class="header" id="qtdocheader"> <div class="content"> <div id="nav-logo"> <a href="index.html">Home</a></div> <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a> <div id="narrowsearch"></div> <div id="nav-topright"> <ul> <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li> <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li> <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/"> DOC</a></li> <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li> </ul> </div> <div id="shortCut"> <ul> <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li> <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS </a></li> </ul> </div> <ul class="sf-menu" id="narrowmenu"> <li><a href="#">API Lookup</a> <ul> <li><a href="classes.html">Class index</a></li> <li><a href="functions.html">Function index</a></li> <li><a href="modules.html">Modules</a></li> <li><a href="namespaces.html">Namespaces</a></li> <li><a href="qtglobal.html">Global Declarations</a></li> <li><a href="qdeclarativeelements.html">QML elements</a></li> </ul> </li> <li><a href="#">Qt Topics</a> <ul> <li><a href="qt-basic-concepts.html">Programming with Qt</a></li> <li><a href="qtquick.html">Device UIs & Qt Quick</a></li> <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li> <li><a href="supported-platforms.html">Supported Platforms</a></li> <li><a href="technology-apis.html">Qt and Key Technologies</a></li> <li><a href="best-practices.html">How-To's and Best Practices</a></li> </ul> </li> <li><a href="#">Examples</a> <ul> <li><a href="all-examples.html">Examples</a></li> <li><a href="tutorials.html">Tutorials</a></li> <li><a href="demos.html">Demos</a></li> <li><a href="qdeclarativeexamples.html">QML Examples</a></li> </ul> </li> </ul> </div> </div> <div class="wrapper"> <div class="hd"> <span></span> </div> <div class="bd group"> <div class="sidebar"> <div class="searchlabel"> Search index:</div> <div class="search" id="sidebarsearch"> <form id="qtdocsearch" action="" onsubmit="return false;"> <fieldset> <input type="text" name="searchstring" id="pageType" value="" /> <div id="resultdialog"> <a href="#" id="resultclose">Close</a> <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span> results:</p> <ul id="resultlist" class="all"> </ul> </div> </fieldset> </form> </div> <div class="box first bottombar" id="lookup"> <h2 title="API Lookup"><span></span> API Lookup</h2> <div id="list001" class="list"> <ul id="ul001" > <li class="defaultLink"><a href="classes.html">Class index</a></li> <li class="defaultLink"><a href="functions.html">Function index</a></li> <li class="defaultLink"><a href="modules.html">Modules</a></li> <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li> <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li> <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li> </ul> </div> </div> <div class="box bottombar" id="topics"> <h2 title="Qt Topics"><span></span> Qt Topics</h2> <div id="list002" class="list"> <ul id="ul002" > <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> <li class="defaultLink"><a href="qtquick.html">Device UIs & Qt Quick</a></li> <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li> <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> </ul> </div> </div> <div class="box" id="examples"> <h2 title="Examples"><span></span> Examples</h2> <div id="list003" class="list"> <ul id="ul003"> <li class="defaultLink"><a href="all-examples.html">Examples</a></li> <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li> <li class="defaultLink"><a href="demos.html">Demos</a></li> <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li> </ul> </div> </div> </div> <div class="wrap"> <div class="toolbar"> <div class="breadcrumb toolblock"> <ul> <li class="first"><a href="index.html">Home</a></li> <!-- Breadcrumbs go here --> <li><a href="all-examples.html">Examples</a></li> <li>Part 7 - Additional Features</li> </ul> </div> <div class="toolbuttons toolblock"> <ul> <li id="smallA" class="t_button">A</li> <li id="medA" class="t_button active">A</li> <li id="bigA" class="t_button">A</li> <li id="print" class="t_button"><a href="javascript:this.print();"> <span>Print</span></a></li> </ul> </div> </div> <div class="content mainContent"> <div class="toc"> <h3><a name="toc">Contents</a></h3> <ul> <li class="level1"><a href="#defining-the-addressbook-class">Defining the AddressBook Class</a></li> <li class="level1"><a href="#implementing-the-addressbook-class">Implementing the AddressBook Class</a></li> </ul> </div> <h1 class="title">Part 7 - Additional Features</h1> <span class="subtitle"></span> <!-- $$$tutorials/addressbook/part7-description --> <div class="descr"> <a name="details"></a> <p>Files:</p> <ul> <li><a href="tutorials-addressbook-part7-addressbook-cpp.html">tutorials/addressbook/part7/addressbook.cpp</a></li> <li><a href="tutorials-addressbook-part7-addressbook-h.html">tutorials/addressbook/part7/addressbook.h</a></li> <li><a href="tutorials-addressbook-part7-finddialog-cpp.html">tutorials/addressbook/part7/finddialog.cpp</a></li> <li><a href="tutorials-addressbook-part7-finddialog-h.html">tutorials/addressbook/part7/finddialog.h</a></li> <li><a href="tutorials-addressbook-part7-main-cpp.html">tutorials/addressbook/part7/main.cpp</a></li> <li><a href="tutorials-addressbook-part7-part7-pro.html">tutorials/addressbook/part7/part7.pro</a></li> </ul> <p>This part covers some additional features that make the address book more convenient for the frequent user.</p> <p class="centerAlign"><img src="images/addressbook-tutorial-part7-screenshot.png" alt="" /></p><p>Although our address book is useful in isolation, it would be better if we could exchange contact data with other applications. The vCard format is a popular file format that can be used for this purpose. Here we extend our address book client to allow contacts to be exported to vCard <tt>.vcf</tt> files.</p> <a name="defining-the-addressbook-class"></a> <h2>Defining the AddressBook Class</h2> <p>We add a <a href="qpushbutton.html">QPushButton</a> object, <tt>exportButton</tt>, and a corresponding public slot, <tt>exportAsVCard()</tt> to our <tt>AddressBook</tt> class in the <tt>addressbook.h</tt> file.</p> <pre class="cpp"> <span class="type">void</span> exportAsVCard(); ... <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>exportButton;</pre> <a name="implementing-the-addressbook-class"></a> <h2>Implementing the AddressBook Class</h2> <p>Within the <tt>AddressBook</tt> constructor, we connect <tt>exportButton</tt>'s <a href="qabstractbutton.html#clicked">clicked()</a> signal to <tt>exportAsVCard()</tt>. We also add this button to our <tt>buttonLayout1</tt>, the layout responsible for our panel of buttons on the right.</p> <p>In our <tt>exportAsVCard()</tt> function, we start by extracting the contact's name into <tt>name</tt>. We declare <tt>firstName</tt>, <tt>lastName</tt> and <tt>nameList</tt>. Next, we look for the index of the first white space in <tt>name</tt>. If there is a white space, we split the contact's name into <tt>firstName</tt> and <tt>lastName</tt>. Then, we replace the space with an underscore ("<a href="index.html">_</a>"). Alternately, if there is no white space, we assume that the contact only has a first name.</p> <pre class="cpp"> <span class="type">void</span> AddressBook<span class="operator">::</span>exportAsVCard() { <span class="type"><a href="qstring.html">QString</a></span> name <span class="operator">=</span> nameLine<span class="operator">-</span><span class="operator">></span>text(); <span class="type"><a href="qstring.html">QString</a></span> address <span class="operator">=</span> addressText<span class="operator">-</span><span class="operator">></span>toPlainText(); <span class="type"><a href="qstring.html">QString</a></span> firstName; <span class="type"><a href="qstring.html">QString</a></span> lastName; <span class="type"><a href="qstringlist.html">QStringList</a></span> nameList; <span class="type">int</span> index <span class="operator">=</span> name<span class="operator">.</span>indexOf(<span class="string">" "</span>); <span class="keyword">if</span> (index <span class="operator">!</span><span class="operator">=</span> <span class="operator">-</span><span class="number">1</span>) { nameList <span class="operator">=</span> name<span class="operator">.</span>split(<span class="type"><a href="qregexp.html">QRegExp</a></span>(<span class="string">"\\s+"</span>)<span class="operator">,</span> <span class="type"><a href="qstring.html">QString</a></span><span class="operator">::</span>SkipEmptyParts); firstName <span class="operator">=</span> nameList<span class="operator">.</span>first(); lastName <span class="operator">=</span> nameList<span class="operator">.</span>last(); } <span class="keyword">else</span> { firstName <span class="operator">=</span> name; lastName <span class="operator">=</span> <span class="string">""</span>; } <span class="type"><a href="qstring.html">QString</a></span> fileName <span class="operator">=</span> <span class="type"><a href="qfiledialog.html">QFileDialog</a></span><span class="operator">::</span>getSaveFileName(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">"Export Contact"</span>)<span class="operator">,</span> <span class="string">""</span><span class="operator">,</span> tr(<span class="string">"vCard Files (*.vcf);;All Files (*)"</span>)); <span class="keyword">if</span> (fileName<span class="operator">.</span>isEmpty()) <span class="keyword">return</span>; <span class="type"><a href="qfile.html">QFile</a></span> file(fileName);</pre> <p>As with the <tt>saveToFile()</tt> function, we open a file dialog to let the user choose a location for the file. Using the file name chosen, we create an instance of <a href="qfile.html">QFile</a> to write to.</p> <p>We attempt to open the file in <a href="qiodevice.html#OpenModeFlag-enum">WriteOnly</a> mode. If this process fails, we display a <a href="qmessagebox.html">QMessageBox</a> to inform the user about the problem and return. Otherwise, we pass the file as a parameter to a <a href="qtextstream.html">QTextStream</a> object, <tt>out</tt>. Like <a href="qdatastream.html">QDataStream</a>, the <a href="qtextstream.html">QTextStream</a> class provides functionality to read and write plain text to files. As a result, the <tt>.vcf</tt> file generated can be opened for editing in a text editor.</p> <pre class="cpp"> <span class="keyword">if</span> (<span class="operator">!</span>file<span class="operator">.</span>open(<span class="type"><a href="qiodevice.html">QIODevice</a></span><span class="operator">::</span>WriteOnly)) { <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">"Unable to open file"</span>)<span class="operator">,</span> file<span class="operator">.</span>errorString()); <span class="keyword">return</span>; } <span class="type"><a href="qtextstream.html">QTextStream</a></span> out(<span class="operator">&</span>file);</pre> <p>We then write out a vCard file with the <tt>BEGIN:VCARD</tt> tag, followed by the <tt>VERSION:2.1</tt> tag. The contact's name is written with the <tt>N:</tt> tag. For the <tt>FN:</tt> tag, which fills in the "File as" property of a vCard, we have to check whether the contact has a last name or not. If the contact does, we use the details in <tt>nameList</tt> to fill it. Otherwise, we write <tt>firstName</tt> only.</p> <pre class="cpp"> out <span class="operator"><</span><span class="operator"><</span> <span class="string">"BEGIN:VCARD"</span> <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>; out <span class="operator"><</span><span class="operator"><</span> <span class="string">"VERSION:2.1"</span> <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>; out <span class="operator"><</span><span class="operator"><</span> <span class="string">"N:"</span> <span class="operator"><</span><span class="operator"><</span> lastName <span class="operator"><</span><span class="operator"><</span> <span class="string">";"</span> <span class="operator"><</span><span class="operator"><</span> firstName <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>; <span class="keyword">if</span> (<span class="operator">!</span>nameList<span class="operator">.</span>isEmpty()) out <span class="operator"><</span><span class="operator"><</span> <span class="string">"FN:"</span> <span class="operator"><</span><span class="operator"><</span> nameList<span class="operator">.</span>join(<span class="string">" "</span>) <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>; <span class="keyword">else</span> out <span class="operator"><</span><span class="operator"><</span> <span class="string">"FN:"</span> <span class="operator"><</span><span class="operator"><</span> firstName <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>;</pre> <p>We proceed to write the contact's address. The semicolons in the address are escaped with "\", the newlines are replaced with semicolons, and the commas are replaced with spaces. Lastly, we write the <tt>ADR;HOME:;</tt> tag, followed by <tt>address</tt> and then the <tt>END:VCARD</tt> tag.</p> <pre class="cpp"> address<span class="operator">.</span>replace(<span class="string">";"</span><span class="operator">,</span> <span class="string">"\\;"</span><span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>CaseInsensitive); address<span class="operator">.</span>replace(<span class="string">"\n"</span><span class="operator">,</span> <span class="string">";"</span><span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>CaseInsensitive); address<span class="operator">.</span>replace(<span class="string">","</span><span class="operator">,</span> <span class="string">" "</span><span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>CaseInsensitive); out <span class="operator"><</span><span class="operator"><</span> <span class="string">"ADR;HOME:;"</span> <span class="operator"><</span><span class="operator"><</span> address <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>; out <span class="operator"><</span><span class="operator"><</span> <span class="string">"END:VCARD"</span> <span class="operator"><</span><span class="operator"><</span> <span class="string">"\n"</span>; <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">"Export Successful"</span>)<span class="operator">,</span> tr(<span class="string">"\"%1\" has been exported as a vCard."</span>)<span class="operator">.</span>arg(name)); }</pre> <p>In the end, a <a href="qmessagebox.html">QMessageBox</a> is displayed to inform the user that the vCard has been successfully exported.</p> <p><i>vCard is a trademark of the <a href="http://www.imc.org">Internet Mail Consortium</a></i>.</p> </div> <!-- @@@tutorials/addressbook/part7 --> </div> </div> </div> <div class="ft"> <span></span> </div> </div> <div class="footer"> <p> <acronym title="Copyright">©</acronym> 2013 Digia Plc and/or its subsidiaries. Documentation contributions included herein are the copyrights of their respective owners.</p> <br /> <p> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.</p> <p> Documentation sources may be obtained from <a href="http://www.qt-project.org"> www.qt-project.org</a>.</p> <br /> <p> Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide. All other trademarks are property of their respective owners. <a title="Privacy Policy" href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p> </div> <script src="scripts/functions.js" type="text/javascript"></script> </body> </html>