The application must be distributed toits various users, and those users must be able to install and update the application as needed.. First, install the packageusing the PEAR installer
Trang 1Listing 16-5. Setting the Background Pixmap for a GtkStyle
<?php
// Create a window and set it up to shut down
// cleanly
$window = new GtkWindow();
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
// Create a new style object
$style = new GtkStyle();
// Create two buttons
$button1 = new GtkButton('Active');
$button2 = new GtkButton('Inactive');
// Set the style for both buttons
$button1->set_style($style);
$button2->set_style($style);
// Make button two inactive
$button2->set_sensitive(false);
// Add a button box to the window
$buttonBox = new GtkHButtonBox();
Trang 2Figure 16-4. Using GtkStyle to Change a Background Pixmap
Summary
Even the most unique application can end up with an appearance that is ordinary and tine Modifying the look and feel of an application can not only give it life, but also improve itsusability Changing a widget’s appearance by using RC files or GtkStyle objects can make
rou-a widget strou-and out, so throu-at it is more noticerou-able, or crou-an give the user clues rou-about the strou-ate ofthe widget
In an RC file, definitions and rules are set up similar to a CSS file in an HTML page Therules determine which styles will be applied to each widget GtkStyle objects are similar, butare used for real-time style modifications Using a GtkStyle object allows a widget to changecolors or fonts based on an event Regardless of how styles are applied, they provide a level ofcustomization that can enhance the application
This and the previous chapters have taken you through the process of building an tion But simply creating an application is not enough The application must be distributed toits various users, and those users must be able to install and update the application as needed
applica-In the next, and final, chapter we will look at ways to distribute the application to many userseven if they don’t have PHP-GTK installed You will also learn a few strategies for automaticallyupdating the application behind the scenes
Trang 3purely for individual use, it will also need to be distributed to the end user After all, an
appli-cation cannot be considered successful unless someone is making good use of it
When you’re considering how to offer an application to the end user, the deciding factorshould be which method will allow the most people to install it with a minimum of fuss By far,
the most widely available means to distribute a PHP application is using PEAR While it may not
be the best solution for all applications, it is available to almost everyone who uses PHP-GTK
applications and therefore will be the focus of this chapter At the end of the chapter, we’ll take
a quick look at using a PHP-GTK “compiler” to distribute a single executable file
Downloading and Installing an Application
These days, simply offering a zip file for the user to download may not be enough While it is
the simplest way to distribute an application, it requires the end user to select the right location
and move files around Users want, and in some cases need, applications that are easily
instal-lable without requiring them to move files from place to place or extract archives
Another issue that many users struggle with is dependencies Requiring the user toinstall a long chain of dependencies will almost surely result in some level of frustration
While depending on other packages can make a developer’s life much easier, asking the
user to manually download and install the dependencies could discourage widespread
adoption of your application
To hide much of the installation tedium, consider using PEAR, available for both Windowsand Linux environments and bundled with most PHP installations Any application can be
packaged using PEAR and distributed using the Chiara_PEAR_Server package The flexibility of
the PEAR package format allows the application to be installed painlessly, while at the same
time letting users customize the application to fit their preferences Users can specify where
the application will be installed and can even make substitutions in the installed code This
gives the users control over the installation process without requiring them to do a lot of work
Trang 4Setting Up the Channel Server
The first step in distributing an application using PEAR is to configure a channel server A channel
server is a web interface that allows the user to browse, download, and install packages It alsoprovides an interface for the PEAR installer that helps to make sure the user installs the mostrecent version of a package
A channel server consists of two components: a MySQL database and a web server Oncethese two requirements are met, installation is a simple two-step process First, install the packageusing the PEAR installer, using the following commands:
$> pear channel-discover pear.chiaraquartet.com
$> pear install -a chiara/Chiara_PEAR_Server
The first command gathers information from the Chiara channel server and makes itspackages available to the local PEAR installer The Chiara channel server is a PEAR channelserver maintained by Greg Beaver, the maintainer of the PEAR installer This server is used todistribute the channel server application The second command installs the Chiara_PEAR_
depend-encies needed for the channel server package These two steps are similar to those users willneed to follow to download packages on your channel server
■ Note The -aflag should have triggered the installation of the CRTX_PEAR_Server_Frontendpackage.This package provides a web interface for the channel server If it was not installed automatically, you shouldinstall it
Next, you’ll need to configure the server by running the post-install scripts As the name
implies, post-install scripts are PHP scripts that are run after the package is installed Thesescripts are often used to configure a package specifically for the user who has installed thepackage In the case of the channel server, post-install scripts are used to configure the data-base and set up the file that describes the new server To run the post-install scripts, issue thefollowing command:
$> pear run-scripts chiara/Chiara_PEAR_Server
You will then be prompted to answer about a dozen questions When all of the questionshave been answered, the new channel server will be ready You will be able to reach the adminis-tration pages via a web browser on your local host
Trang 5Creating the Package
The package is the file that the users will download and install on their computer A package
contains all of the files needed for the application in addition to an XML file that tells the PEARinstaller where to place each file When a user installs a package, the PEAR installer downloads
and unpacks the package file Then it reads the XML file and moves the files to their proper
location according to the instructions found in the XML file After that, the application is
ready for use
To package the application, you need to create the XML file that tells the PEAR installer where
to place each file, called the package.xml file You can create this file in a few different ways:
• Write it by hand This can be a long process even for applications that consist of only
a few files If an application has many files, creating the XML by hand quickly becomesimpractical
• Use the PEAR_PackageFileManager class This PEAR package provides a class to helpcreate and update package.xml files While this approach is definitely easier than cre-ating the XML by hand, it requires a new script to be written for each application that ispackaged Creating the individual scripts saves only a little time over writing the XML
by hand
• Use one of the GUI front ends for the PEAR_PackageFileManager The PEAR_
Package Output Directory fields to browse to the correct directories Next, enter the name of
the package This is the name by which users will download and install the application The
third piece of information you need to supply is the base installation directory This is the
directory where the files will be installed The final two fields on this page are for a summary
and a description of the package The channel server will display these pieces of information
when the user is browsing the website
Trang 6Figure 17-1. The first page of the PEAR_PackageFileManager_GUI_Gtk2 application
The next step in creating a package.xml file is to provide a list of maintainers A maintainer
is someone who has in some way contributed to the package To add a maintainer, simply enter
a handle (or user name), a real name, an email address, and a role for the maintainer, as shown
in Figure 17-2 Those maintainers who are designated as leads can release new versions of thepackage Other roles are used to give credit to and provide contact information for those peoplewho have helped develop the package
Once you’ve added all of the maintainers, there are only a few remaining steps to complete.The first is to save the XML (select File ➤ Save) This will create two files: package.xml andpackage2.xml The package.xml file is used by earlier versions of PEAR and allows for relativelysimple installations package2.xml is used by newer versions of PEAR and allows for greater flexi-bility, including handling dependencies from other channel servers
Trang 7Figure 17-2. The Maintainers page of the PEAR_PackageFileManager_GUI_Gtk application
Next, the application needs to be packaged Packaging the file is a simple matter of issuingthe following command:
$> pear package package2.xml
This command will create a gzipped tar archive (.tgz) This file is called a package file and
contains all of the information PEAR needs to install the application
The last step is to upload the new package file to the channel server using the tor interface provided by Chiara_PEAR_Server Once the package has been uploaded, users can
administra-download and install the application
■ Note The PEAR package XML format is very powerful You can use different elements and attributes to
control how an individual file is handled at installation The PEAR_PackageFileManager_GUI_Gtk2
appli-cation can create the XML needed for most of these customizations For more details, refer to the PEAR
manual (http://pear.php.net/manual/en/guide.developers.package2.php)
Users can now install the application by first discovering your channel server and thentelling PEAR to install the application:
$> pear channel-discover <your channel server>
$> pear install <your channel server>/<application>
■ Tip The Gnope installer (http://www.gnope.org) is an open source application used to install PHP-GTK
Because this application is open source, anyone is free to take the code and modify it to suit their needs
Visit the forums on the Gnope website for more information
Trang 8Updating an Application
Most applications will need to be updated at some point in their life cycle Even if an tion is completely bug-free on its first release, new features will probably need to be addedsomewhere down the road Providing a way for the user to easily update the application willhelp to ensure that the user always has the latest and greatest version of the application.You can handle application updates in two ways First, an application can simply requirethe user to manually install the latest version For instance, if PEAR was used to install theapplication, the user can simply type:
applica-$> pear upgrade <channel>/<application>
The other method for updating an application is to automate the process and upgrade theapplication behind the scenes Applications that require a manual update process are muchless likely to remain up-to-date than those that are updated automatically Automating theupdate process not only makes life easier on the user, but also makes life easier on the supportteam, because there are likely to be fewer versions of an application in wide distribution atone time
Automatically updating an application is a four-step process:
Just as PEAR is the easiest way to reliably distribute an application, it is also the easiestway to automatically update an application Here, we’ll look at how to use PEAR to check for
a new version of the application and download and install it if needed
Checking for Updates
Checking to see if the application needs to be updated is normally done when the application
is started At some point during the startup process (usually the very beginning), a request can
be made to the channel server to see if an upgrade is needed If the package is listed on a PEARchannel server, then the tools for checking for an upgrade are already in place Using them isjust a matter of knowing which classes are needed and which methods to call
Listing 17-1 shows just how easy it is to check for a new version of the Crisscott PIMSapplication This code is added to the splash screen to ensure that the new version check isdone every time the application is started
Trang 9// Update the GUI.
while (gtk::events_pending()) gtk::main_iteration();
// Give the user enough time to at least see the message
// Check for a new version first
$this->status->set_text($newVersion);
}//
}public function checkNewVersion(){
// Create a config object
require_once 'PEAR/Config.php';
$config = new PEAR_Config();
// Get the config's registry object
}// Get a PEAR_Remote instance
$r = $config->getRemote();
// Get the package info
$info = $r->call('package.info', $parsed['package']);
// Check to make sure the package was found
if (PEAR::isError($info)) {return 'Could not find package on server Unable to ' 'automatically update.';
}
Trang 10Figure 17-3. A dialog window requesting permission to upgrade the application
// Get the installed version of the package
$instVersion = $reg->packageInfo($parsed['package'], 'version',
$parsed['channel']);
if (version_compare(reset(array_keys($info['releases'])),
$instVersion,'>')
) {return true;
} else {return 'No updates found.';
}}//
}
?>
This small piece of code uses the same classes that the PEAR installer uses to upgradepackages The first step is to create a PEAR_Config instance PEAR_Config manages the user’spreferences and helps to instantiate other classes properly
Once the PEAR_Config object is created, it is used to create a PEAR_Registry object usinggetRegistry You can use the PEAR_Registry object to access information about packages thatare already installed on the user’s computer In this case, it is used to verify that the name ofthe package to be updated is valid and parse it into different segments
After parsing the package name (crisscott/Crisscott_PIMS) into a channel and packagename, a PEAR_Remote object is created by calling the PEAR_Config object’s getRemote method
Passing package.info to the remote object’s call method returns a host of information aboutthe package The relevant information in this case is the version number If the version number
on the channel server is greater than the installed version (which is returned from the registryobject’s packageInfo method), then a new version of the package is available
Obtaining the User’s Permission to Upgrade
If a new version of the application is available, the responsible thing to do is to ask the user forpermission before upgrading the application As you may have guessed, the best way to askpermission is to use a GtkDialog, as shown in Figure 17-3 The dialog window displays a mes-sage and two buttons If the user clicks the Yes button, the application will be upgraded If theuser clicks No or closes the dialog window, the application is not updated and will be loaded
as usual
Trang 11Listing 17-2 shows the code used to create the dialog window shown in Figure 17-3.
// Set up the buttons for the action area
// We only want one button, close
$buttons = array(Gtk::STOCK_NO, Gtk::RESPONSE_NO,
Gtk::STOCK_YES, Gtk::RESPONSE_YES);
// Call the parent constructor
$dialog = new GtkDialog('New Version Available', null, $flags, $buttons);
// Set a message as the dialog label
$dialog->vbox->add(new GtkLabel("A new version is available \n"
'Would you like to download and install it now?'));
// Show the dialog
$dialog->show_all();
// Any response should close the dialog
$dialog->connect_simple_after('response', array($dialog, 'destroy'));
// If the user clicks the X in the corner, close the dialog
$dialog->connect_simple('destroy', array($dialog, 'destroy'));
// Run the dialog and check the response
if ($dialog->run() === Gtk::RESPONSE_YES) {// The user wants to update the application
if ($this->doUpdate()) {// Let the user know that the application must be restarted
$this->status->set_text('The application must be restarted.');
// Update the message and give the user some time to read it
while (gtk::events_pending()) gtk::main_iteration();
sleep(2);
Trang 12// Quit the application so that the user must restart.
exit;
} else {// There was a problem
// Let the user know but continue with the startup
$this->status->set_text('Error uploading application.');
while (gtk::events_pending()) gtk::main_iteration();
}}}//
?>
Performing the Upgrade
The final step is to actually upgrade the application, as shown in Listing 17-3 Just as with thetwo previous listings, Listing 17-3 takes advantage of the classes and methods provided by PEAR
$config = new PEAR_Config();
// Create a command object to do the upgrade
require_once 'PEAR/Command.php';
$upgrade = PEAR_Command::factory('upgrade', $config);
// Try to upgrade the application
$result = $upgrade->doInstall('upgrade', array(),
array('crisscott/Crisscott_PIMS'));
// Return true if the upgrade was successful
return !PEAR::isError($result);
}}
?>
The first step in upgrading the application is to create a PEAR_Config instance Again, thisclass holds user-defined configuration settings Next, a PEAR_Command instance is created withthe PEAR_Command::factory methods This method requires the name of a command and theconfiguration object created earlier It will return an object capable of completing the upgrade
Trang 13The call to the doInstall method tells the command object to upgrade the application If the
process is successful, the doInstall method will return true If an error occurs, the method
will return a PEAR_Error object
Uninstalling an Application
Part of being a responsible developer is not only providing an easy way to install an application,
but also providing an easy way to uninstall an application Regardless of how wonderful an
application is, people may need to remove it from their computer Unfortunately, in too many
cases, this requires the users to manually remove all of the files associated with the application
To make life easier on the end user, all applications should come with a way to uninstall them
The method used for uninstalling an application usually depends on the method that wasused to install it in the first place Some installation tools have the ability to remove a previouslyinstalled package For example, any package installed with PEAR can be uninstalled by simply
issuing an uninstall command, like this:
$> pear uninstall crisscott/Crisscott_PIMS
This command will remove all files that came in the original package Files that were added
by the application later, such as data files or custom resource files, will not be removed
Of course, as with the upgrade step, this simple PEAR command can be integrated into theapplication Alternatively, you can create a separate smaller application as an uninstaller
Listing 17-4 is a simple yet effective application that prompts the user for confirmation and
then uninstalls the application if requested, by using the classes provided by PEAR
<?php
class Uninstall extends GtkDialog {
public function construct(){
// Set up the flags for the dialog
$flags = Gtk::DIALOG_NO_SEPARATOR;
// Set up the buttons for the action area
// We only want one button, close
$buttons = array(Gtk::STOCK_NO, Gtk::RESPONSE_NO,
Gtk::STOCK_YES, Gtk::RESPONSE_YES);
// Call the parent constructor
parent:: construct('Uninstall Crisscott PIMS', null, $flags, $buttons);
// Any response should close the dialog
$this->connect_simple('response', array($this, 'destroy'));
// The static properties must also be unset
$this->connect_simple('destroy', array($this, 'destroy'));
Trang 14// Add an image and a question to the top part of the dialog.
$hBox = new GtkHBox();
$message = new GtkLabel('Are you sure you want to remove the '
'Crisscott PIMS application?');
$message->set_line_wrap();
$hBox->pack_start($message);
}public function run(){
// Show the dialog
$this->show_all();
// Run the dialog and wait for the response
if (parent::run() === Gtk::RESPONSE_YES) {// Uninstall the application
$this->_doUninstall();
}}private function _doUninstall(){
// Create a config object
require_once 'PEAR/Config.php';
$config = new PEAR_Config();
// Create a command object
require_once 'PEAR/Command.php';
$uninstall = PEAR_Command::factory('uninstall', $config);
// Uninstall the application
$result = $uninstall->doInstall('uninstall', array(),
array('crisscott/Crisscott_PIMS'));// Report any errors
if (PEAR::isError($result)) {echo $result->getMessage() "\n";
}}}
Trang 15// Create an uninstall instance
$unInst = new UnInstall();
// Run the dialog
$unInst->run();
?>
Using PHP Compilers
All PHP-GTK applications have one thing in common: they need PHP-GTK in order to work
This can make it difficult to distribute an application to users who do not have PHP-GTK
installed on their computers The users must download and install PHP-GTK before
attempt-ing to run a PHP-GTK application As you saw in Chapter 2, this can sometimes be a difficult
process One solution is to use a PHP “compiler.”
A PHP compiler is an application that takes PHP code and turns it into an executable gram Once compiled, a PHP script can be run by any user, regardless of whether or not they
pro-have PHP installed
A few different PHP compilers are available Some are commercial applications such asRoadsend’s Compiler for PHP (http://www.roadsend.com) and PriadoBlender, but there is one
open source, freely available PHP compiler called bcompiler (http://pecl.php.net)
Unfortunately, as of the time of this writing, most of these applications or extensions donot work well enough with PHP-GTK 2 to allow a thorough description of their use However,
Roadsend’s Compiler for PHP does allow a majority of applications to be compiled into
executables
Roadsend’s Compiler for PHP is available as a command-line application on Linux and asboth a command-line application and GUI front end on Windows Since the command-line
application is available on both major platforms, we will focus on that version here PHP
Compiler can turn PHP-GTK source code into an executable with one command:
$> pcc gui static Crisscott/run.php
This command produces a file with the same name However, this file, which is much largerthan the previous version, includes the PHP and GTK binaries necessary to run without PHP-GTK
being installed
■ Note I strongly encourage everyone to give these compilers a try and provide as much feedback for the
developers as possible A fully functioning PHP-GTK 2 compiler will allow applications to reach a much
greater audience In the end, a little time spent testing can help to create a better product for everyone
Trang 16Distribution of an application is arguably just as critical as its development and testing Thedecision to use one distribution method over another depends greatly on the target users andthe goals of the project If the target users are PHP-GTK developers, then a relatively simpledistribution method, such as a channel server, is appropriate, because PHP-GTK does not need
to be distributed along with the package Other groups of users are likely to need PHP-GTK to
be distributed and installed along with the application With any luck, these users will not have
to wait much longer for a fully functional PHP compiler
Trang 17■ Symbols
# (comments), using with RC files, 326
& (ampersand), using with PHP-GTK
applications, 23
* (asterisk) wildcard, using with style rules,
322_ (underscore), using with mnemonics,
131
■ A
-a flag, using with PEAR installer, 334
about dialogs, using, 300–301
action area of dialogs, adding items to,
287, 289ACTIVE value, using with style definitions,
321Activity mode
putting progress bars into, 304using progress bars with, 303add method
vs pack_start and pack_end methods,93
using with tags and tag tables, 164using with tool buttons, 251using with widgets, 34add signal, emitting, 45
add_action_widget, adding buttons to
GtkDialog with, 288add_attribute, using with cell renderers
and view columns, 202add_events method
calling in PHP-GTK 1, 61using with widgets, 58, 60adjustments, applying to scrollbars, 227aligning labels, 134
allocation property, using with widgets in
realized state, 29alpha channel, creating for GdkPixbuf, 264
ampersand (&), using with PHP-GTK
applications, 23angled text, creating in complex labels,
132, 134animations, working with, 265
append method, using with GtkListStore
applications See also Crisscott PIMS
applicationapplying RC (resource) files to, 322,328
downloading and installing, 333, 337laying out with tables, 98, 100minimizing and closing, 76uninstalling, 343, 345updating, 338, 342apply_tag method, using, 166apply_tag_by_name method, using, 166arrays
for GtkDialog constructor, 283representing properties with multiplestates with, 330
returning for signal data, 58using with signal handlers, 44article, selecting with news article tool,
212, 215asterisk (*) wildcard, using with style rules,322
ATK (Accessibility Toolkit) package,description of, 18
attach methodarguments for, 101using with GtkMenu, 233
■ B
background pixmapschanging with GtkStyle, 331setting for styles, 330, 332backward_chars method, moving iteratorswith, 160
base[state] property, using with resourcefiles, 321
bcompiler packageusing with PECL, 22website, 345
Index
347
Trang 18bg[state] property, using with resource
files, 321bg_pixmap[state] property, using with
resource files, 321bin containers
examples of, 32turning GtkHBox into, 47using set_child method with, 34bitmask, GdkBitmap as, 266
block method, using with signalhandlers, 50, 52
border type, setting for frames, 90borders
adjusting for tabs, 116manipulating for windows, 68–69box containers
behavior of widgets in, 93button boxes, 97
creating vertical and horizontal boxes, 91examples of, 32
nesting, 94, 96–97packing widgets into, 91, 94sizing, 96
vs tables, 103types of, 91using set_homogeneous method with,94
Browse mode, setting for row selection,
208buffer text, using tags with, 161buffers, creating text buffers withmarks, 155
buffers See also text buffers
buildconf command, buildingconfigure utility for Linux with, 19button boxes, features of, 97
button masks, using with drag sources,
276button-press-event signal, emitting, 246
buttons See also GtkButton widgets
adding to GtkDialog usingadd_action_widget, 288adding toGtkDialog, 288connecting clicked signal of button toquit method of container, 47connecting signal handlers to, 290connecting to signal handlers, 148, 150for file operation, 298–299
naming with get_name, 120parent of, 35
passing to callbacks, 54setting styles for, 330using callback method with, 43–44using signal handlers with, 54
■ C
callback arguments, reducing withconnect_simple, 45, 47callback method, using with two buttons,43–44
callbackscalling in timeouts, 315passing buttons to, 54catch blocks, using with try blocks, 7CategorySummary tool, using angled text
in, 132, 134c:\php5 directory, creating in Windows, 16cell renderers
adding to view columns, 202, 205using with views, 196–197cells
assigning widgets to, 102setting cursors on, 207setting padding for, 103CGI mode, disabling, 18changed signal
connecting to setScrollValue, 228using with selected rows, 210changeLabel method, adding toGtkButton class, 44ChangingLabel class, using with events,57
channel servers, setting up for applicationdistribution, 334
channels, relationship to PEAR packages,21
check menu item, explanation of, 240checkClicked method, calling for signalhandler, 52
Chiara channel server, gatheringinformation from, 334child argument, using with attachmethod, 102
child placement, controlling forscrollbars, 222–223child widgets
defining padding for, 94explanation of, 32managing with containers, 32children, attaching to tables, 101, 103children method, using with containerwidgets, 34
class rule type, using with style rules, 322class:: property, using with resource files,321
clearError method, removing markupfrom complex labels with, 128CLI (command-line interface),relationship to PHP, 5, 18
Trang 19handlers, 52cmd, bringing up DOS prompt with, 16
color palette, adding, 290
color selection interface
creating signal handlers for, 290using, 289
colors, assigning to GtkStyle property,
329colorsel property, accessing color
selection with, 290column display properties, setting with
view columns, 198, 201column headers, setting with
GtkTreeViewColumn, 197column headings, using angled text in,
132, 134column size, controlling in view columns,
200column types, using with GtkListStore
model, 181
columns, 197 See also view columns
creating within rows, 94reordering, 206
sorting by, 201columns parameter, using with GtkTable
widget, 101 See also view
columnscol_start argument, using with attach
method, 102
combo boxes See GtkComboBox widgets
command line, running PHP-GTK
applications from, 22command-line prompt, bringing up, 16
comments (#), using with RC files, 326
compilers, using PHP compilers, 345
complex labels See also simple labels
adding mnemonics to, 129, 131converting simple labels to, 128creating angled text in, 131–132, 134ellipsizing text in, 129
removing markup from, 128using GtkLabel with, 125using Pango with, 125, 128configure command, running in Linux,
18–19connect call, passing extra parameters to,
45
connect methodscreating signal handlers with, 42, 49using with add signal, 45
using with signal handlers, 41connect_after method, using with signalhandlers, 47, 49
connect_simple method, using with signalhandlers, 45, 47
connect_simple_after method, using withsignal handlers, 47
console window, freezing with PHP-GTKapplications, 23
Console_Getargs package, installing, 21container methods, controlling parent-child relationship with, 34container widgets
overview of, 32–33removing contents of, 34using signal handlers with, 41using testForParent function with, 35containers
fixed containers, 103, 105relationship to GtkObject class, 27content of notebook pages, explanation
of, 111context menus, creating, 245–246contributor editing tool, using GtkEntryfields with, 137
ContributorEdit classadding Submit and Undo buttons to,148
expanding for Submit and Undobuttons, 147–148
ContributorEdit tooladding buttons to, 148creating with Pango, 126, 128using GtkEntry fields with, 135createStateList method, using with entryfields, 139
createTreePathArray method, connectingsignals to, 229
create_mark method of GtkTextBuffer,using with marks, 155
Crisscott PIMS application See also
applicationsadding GtkNotebook widget to, 107adding menu to, 231, 234
adding Submit and Undo buttons to,147–148
basis for, 79checking for new version of, 338, 340GtkAboutDialog for, 300–301
main-window elements for, 87–88overview of, 1–2