TweetFollow Us on Twitter

BBEdit Plug-In Programming

Volume Number: 14 (1998)
Issue Number: 6
Column Tag: Tools Of The Trade

BBEdit Plug-In Programming

by Steve Sheets

Creating Extensions for Bare Bones Software's BBEdit Text Editor

The Right Tool for the Right Job

As a well known starship engineer would say, "always use the right tool for the right job". It's true for dilithium chambers and it is true for Macintosh development. When working with resources, ResEdit and Resorcerer are the best tools available. Hypercard and Macromedia Director have been the favorites of two generations of multimedia authors. Part of what makes these tools so powerful is the potential to customize them through ResEdit templates, Resorcerer "apprentice" plug-ins, Hypercard XCMDs, and Director Xtras. This plug-in extendibility let's you customize and focus their features to turn a great tool into the perfect tool for your job. The text editor BBEdit is one of the best at what it does and its basic functions can also be extended with third party BBEdit extensions. This article will describe how to create your own BBEdit extensions so you can apply the power of BBEdit to the unique challenges in your projects.

The Right Tool for the Right Editing

Bare Bones Software's BBEdit is a powerful text editor. A text editor is not a word processor (where the output is intended to be a printed page). BBEdit is just for text files -- the source file format for almost all compilers and interpreters. Many developers prefer using BBEdit or another third party editor instead of the text tool built into standard development environments (like Apple's MPW, Metrowerk's CodeWarrior, Symantec C++ or Symantec's Visual Cafe). This preference has become wide spread enough that most IDEs now have explicit support for external editors. BBEdit is also a popular tool for web page design (text being the source format of all HTML web pages) or any other job that requires text manipulation.

While the built in features of BBEdit are impressive to begin with, BBEdit has an additional method to add functions -- the extensions API. Each plug-in is a code resource, of type 'BBXT', that is loaded in, executed and unloaded when the user selects the corresponding item in the extension menu. Bare Bones Software uses the API themselves and BBEdit ships with a couple dozen plug-ins.

When executed, the plug-ins can do any number of text manipulation tasks. The plug-in can even have limited user interaction, as in the case of modal dialogs or Standard File dialogs. However, the plug-in does not have access to any global memory nor to any settings of the BBEdit application itself.

A plug-in also has access to a large list of callback services. These services are functions that Bare Bones Software provides to do common tasks such as accessing or changing the currently selected text, creating or opening new windows, and creating message, progress or error windows. Additional functions make it easy to handle undo, AppleEvents and grep type commands.

Beyond these user interface and single use limitations, BBEdit plug-ins can do almost anything with or to a text file. A plug-in can be a simple tool to automate some changes in the selected text, or it can be a sophisticated compiler (C++, Java, or Resource) that processes a text file into another format. The only limit is the developers imagination.

This article will explain the format of a BBEdit plug-in (resource and file). The extension interface will be described, as will the plug-in control flags resource. Several, but not all, of the callback services will be described. Two examples of BBEdit plug-ins are included for you to learn from. Bare Bones Software provides a complete SDK with all commercial versions of their software and you can download this kit from the BareBones web site at http://www.barebones.com/. The SDK includes a manual explaining all the calls, as well as the required interface files.

Extension Resource and File

A BBEdit plug-in is an old fashion code resource, like an desk accessory, FKEY or menu proc. The code resource can be a traditional 68K resource or an accelerated PowerPC code resource. The code resource can even be a 'fat' code resource that contains both. For most developers, a 68K version of their plug-in is best since it can run on both platforms. You only need to create a PowerPC version to take advantage of the increased speed of native code.

Any number of plug-ins can exist inside a single BBEdit plug-in file. This file must reside inside the "BBEdit Plug-Ins" folder, which is located beside the BBEdit Application. The file can also reside in a sub folder in the BBEdit Plug-ins folder, which would cause the plug-in to appear inside a submenu in the application. This is a good way to group plug-ins. This nesting only goes down one level. The BBEdit file must be of file type 'BBXT'. It's creator type can be anything (allowing custom icon bundles) but if the type is 'R*ch', then the file will have the generic BBEdit plug-in icon. BBEdit will work correctly if aliases to the actual plug-in file are placed in the plug-ins folder.

A BBEdit plug-in is a code resource of type 'BBXT'. The ID can be any number, while the name should describe the plug-in. BBEdit will use this name when placing the plug-in in the extension menu. BBEdit opens the plug-in file as a resource file when the call is executing, so the plug-in can access other resources in the file.

Along with the code resource, the plug-in file can contain an optional "plug-in control flags" resource. This resource is of type 'BBXF' and has the same ID as the plug-in it is associated with. The resource contains 4 bytes of data, each bit signifying a specific flag. The easiest way to create and modify this resource is with the "BBXF" resource template provided by Bare Bones Software in their SDK. A Rez resource header would have been nice, but is not currently available. The flags resource provides the BBEdit application with information about what the plug-in does, and when it can be invoked. These flags will be explained in more detail below. Technically, this flag resource is not required for an old style plug-in, but is necessary if you wish to signify that your plug-in is a new style one.

Calling Conventions

The original or old calling convention had a pascal style function as the main entry point. The function was passed a callback pointer, and the window pointer of the top most window. BBEdit version 3.5 and later support a newer calling convention. While the older convention remains, it has all but been replaced by the new format. The new format provides more information, as well as supporting Apple Events. The new style does require the BBEdit application to run under System 7.0, but this is no longer very limiting. The new style calling convention has a main entry point defined as:

pascal OSErr main(ExternalCallbackBlock *callbacks, 
WindowPtr w, long flags, AppleEvent *event, AppleEvent *reply);

The routine returns an OSErr result indicating the errors, if any. If the plug-in runs successfully, this should be set to noErr (0). The callback parameter points to a structure used by the BBEdit application and the BBEdit callback routines. While the plug-in has access to the structure directly, the structure may change in future revisions of the application. Therefore, it is strongly recommend you only access the callback using the callback services routines or macros.

The w parameter is the WindowPtr of the top most window, while the flags parameter provides information about the applications current state. The flag parameter is a combination of logically ORed flags, each flag having an associated mask defined for it. The xfWindowOpen flag will be set if the front window is a edit or text window. If the xfWindowChangable flag is set, the text in the front window can be modified. If the xfHasSelection window is set, then the front window has some text selected. This text can be accessed directly from the callback services routines. The xfUseDefault flag allows the plug-in to invoke a non-user version of the plug-in. It will only be set if the correct plug-in control flag is set, and the user holds down the option key when invoking the plug-in. In this case, the plug-in should not place up a dialog or provide any other user interface. If settings are required, use the default setting of the plug-in (what ever you want to make them). The xfIsBBEditLite and the xfIsBBEditDemo flags indicate if the BBEdit application is a Lite version (non-commercial) or a demo version. The last two flags, xfWindowHasMailer and xfWindowHasActiveMailer relate to the unsuccessful Apple PowerTalk Mail system. If the xfWindowHasMailer flag is set, then the front window contains an PowerTalk mailer. In that case, if the xfWindowHasActiveMailer flag is also set, then the mailer is currently active.

If the plug-in is invoked from an AppleEvent (or OSA Script), then the event and reply parameters are the standard AE Event Handler parameters. If the AE parameters are not NIL (for example, if an Apple Event was used to invoke the plug-in), then the plug-in does not require user interaction (no modal dialog). The script may be invoked by someone across the network. To allow the plug-in to be scriptable, a standard 'aete' resource with the same ID as the plug-in is needed in the plug-in file. This 'aete' resource can only support one AE suite, but can have any number of events as you want. Bare Bones Software suggests using their BBEdit extension suite.

Extension Control Flags

The plug-in control flags provides information to the BBEdit application about your plug-in. This information allows BBEdit to determine whether to enable or disable your extensions menu item depending on the state of the application. For example, if the plug-in requires PowerPC flag is set, then the plug-in will be disabled when it is run on a 68K Macintosh.

The first three flags deal with handling an undoable plug-in. Bare Bones Software provides several callback services that make undoing most text editing plug-ins trivial. To signify that the extension know about undoing it's actions, the undo-savvy flag needs to be set. If the Can Be Undone flag is also set, then BBEdit expects your plug-in to use the callback routines to handle this. Otherwise, if this flag is not set, when the user selects the menu item, an "This action can not be undone -- do you wish to continue?" alert will appear when the menu item is selected. The plug-in is only called if the user then clicks "Yes". To disable this alert, set the "Can't Undo" alert flag.

The next five flags control whether or not the plug-in is active in the menu. The Requires Non-Empty Window flag indicates the plug-in is disabled if there is no top most window, or if the top most window has no text in it. The Requires Changeable Window indicates the plug-in is disabled if there is no top most window, or if the window is read only. The Requires Edit Window requires exactly that before the plug-in is enabled. The Requires Selection flag indicates the top most window is there, and some text is selected. The Requires PowerPC flag was already explained.

The last four flags are miscellaneous ones. The Support New Interface flag tells the BBEdit application if the plug-in support the new or old conventions. For this article, I strongly recommend setting this flag, and only using the new style. The Use Option Key for Default flag means the user can hold the option key down to invoke the plug-in with the default setting. This flag is only supported on the new style interface. The Place on "Internet" Menu flag indicates where the plug-in wishes to be placed in the menubar. Assuming the user has an Internet menu and this flag is set, the plug-in is place on the Internet menu. The Is a Tool flag indicates the BBEdit plug-in is a BBEdit Tool

BBEdit Tools are beyond the scope of this article. Tools are special plug-ins that function very similarly to old fashion desk accessories. They provide dragable, resizeable, floating windows that are drawn by the plug-in, and can handle mouse down events in the window. BBEdit Tools also support Drag and Drop. Finally, they have access to global memory and are persistent. The Bare Bones Software's SDK provides more information, including examples, of BBEdit Tools.

Callback Services

BBEdit callback services are an essential part of the API. If the callback services routines did not exist, then the BBEdit plug-ins would not be more than application specific FKEYs. Using callbacks gives a plug-in complete control of the text in the application. All callback routines begin with 'bbxt', making them easy to identify in your code. These routines use the Pascal calling conventions and pass the main function's callback parameter as their first parameter. For example, you pass the bbxtGetCallbackVersion routine the single callback parameter, and it returns the version number of the BBEdit API. Using this, you can insure which callback routine is available for a given version of the application (check the header and documentation).

Several routines use either windowptrs as parameters or pass them as results. These are standard Macintosh windowptrs. The plug-in itself receives the windowptr of the top most active window. If the window's Kind field is of type userKind, then the window is a standard BBEdit text window. Be aware that there are a number of other window kinds. Use the callback routines, or the control flags, to make sure your plug-in is only invoked when the correct window is on top.

The first set of callback routines duplicate the standard feature of the Edit window. Since an plug-in can both pass data into and take data out of the clipboard, this is a good method to modify the text in a window. These routines include bbxtCopy, bbxtPaste, and bbxtDelete. Other text editing routines include bbxtGetSelection and bbxtSetSelection which can be used to get and set the selection of the text in a window. The bbxtGetWindowContent call can used to directly access the text in a window, while bbxtSetWindowContent can be used to change it. If you use the bbxtGetWindowContent call to examine the text handle, and then change the content of that text handle, then you should call the bbxtContentsChanged routine to inform the application of the changes. The bbxtInsert call can be used to place text into the current selection space of a window. Between these routines, you can control of changes to the text in a window.

The routines bbxtGetLastLine, bbxtGetLineNumber, bbxtGetLinePos, bbxtGetLineStart, and bbxtGetLineEnd can be used to find the number of lines in a window, the line number of a specific character, the offset of a specific line and the offset of a given character from the beginning or end of it's line. These functions can be useful in formatting lines of text.

Bare Bones Software also provides several file io routines. Given the file name, volume id and directory id, bbxtGetFileText will load that file into a given handle. The bbxtOpenFile call loads a text file into a standard edit window, and returns the windowptr of that window. The bbxtGetFolder call displays a Standard File dialog for choosing a folder (I wish the Mac OS would provide that call). The bbxtOpenSeveral call provides a Standard File dialog for multiple selections of files (another one Apple could do to duplicate). The bbxtNewDocument, bbxtOpenDocument and bbxtSave calls invoke the same actions as if the user had selected the items from the File menu. Many of these calls return the WindowPtr of the created window, which can be then used to view or modify the text. You may also want information about a given window/file. The bbxtGetDocInfo call can return the name, volume id and directory id of a window/file, while bbxtGetModDate returns the last modification date of the file/window. For those who wish to use CodeWarrior or Think project files, bbxtGetProjectList will parse these files for you, while bbxtProjectTextList will generate a textual listing of the project document's content. Finally, bbxtOpenFileByName will open the specified file, using the same search logic as the "Open Selection Command".

Several user interface calls are available for plug-in developers. The simplest is bbxtReportOSError which puts up an alert box with the proper OS Error message, based on the OSErr parameter. Dialog management can be handled by bbxtStandardFilter (which can be used as a filter proc for modal dialogs), bbxtFrameDialogItem (which draws a rectangle around the dialog item), and bbxtCenterDialog (which centers the dialog). For those who need to place a Progress Bar window on the screen, bbxtStartProgress, bbxtDoProgress and bbxtDoneProgress provide exactly that. The bbxttConfirmSave provides the standard "Do you want to save?" Alert to the plug-in. BareBones Software provided this long before Apple thought to add it as a standard call to System 8.0. Finally, bbxtCreateResults will provide an error browser similar to a compiler error window. This is the perfect feedback for errors if your extension is come sort of compiler

The BBEdit API provides a way for plug-ins to store and retrieve plug-in-specific preference data. Using bbxtGetPreference and bbxtSetPreference, a plug-in stores its own persistent preference data in the BBEdit preferences file.

As mentioned previously, BBEdit provides a built-in Undo feature for plug-ins. If you are going to change a range of text in the current window, BBEdit keeps track of the old and new states of the text. First, call the bbxtPresetUndo or bbxtPrepareUndo routines before the changes start, and then call the bbxtSetUndo or bbxtCommitUndo routines after the changes are done. BBEdit will then handle undoing and/or redoing the text. One set of routines is based on the current selection of text, while the other set is based on a given selection range.

Other Apple Event, AppleScript and Process manager calls are available. The bbxtRunScript provides a simple way to execute a given AppleScript file. The bbxtSendAppleEvent call allows you to send the AE, and BBEdit application will handle the idling phase of the transaction. Simpler Apple Events can be generated by bbxtSendOpenDoc and bbxtOpenWithFinder which cause an application or the Finder to open a document. The bbxtFindApplication call uses the Desktop manager to locate an application, while the bbxtLaunchApplication call can be used to launch it. The bbxtApplicationRunning call can tell you if that application is already running.

Finally, several routines provide pattern searching and Grep feature for the plug-in. The bbxtFindPattern call does exactly that; it searches some text for the given text pattern. A host of Grep calls (bbxtPrepareGrep, bbxtDoneGrep, bbxtReportGrepError, bbxtGrepSearch, bbxtGrepRepleace) provide direct control of all the features of a standard Grep search and replace.

The list of callback routines evolved over time, and it shows. These are routines that real plug-in developers needed, requested and received. Bare Bones Software has been successful with marketing their product as web designer tool based on how well the HTML plug-ins are designed. They could not have done this, unless the SDK that comes with BBEdit was also a success.

Examples

The first example provided here demonstrates a good way to display about or help information for your plug-in. After a text resource is loaded and detached, the bbxtNewDocument call creates an edit window. Then the bbxtSetWindowContents call sets the window content to a given text handle. This will place a simple window, containing the text, for the user to view. ResEdit was used to create the required resource with the given flags set. Notice the EnterCodeResource and the ExitCodeResource calls, which are required for code resource.

Listing 1: About MacTech Examples.c

Main
//      About MacTech Examples.c
//      by Steve Sheets for MacTech Magazine
//      Sample of BBEdit extension
//      
//      Requires 'BBXF' Resource 128 with Support New Interface, 
//      and Undo-Savy flags set.
//      Also requires 'TEXT' Resource 128 which contains
//      "MacTech BBEdit Examples by Steve Sheets".

//   Required includes

#include <ExternalInterface.h>
#include <A4Stuff.h>

//   Main entry point of extension

pascal OSErr main(ExternalCallbackBlock *callbacks, 
                  WindowPtr w, 
                  long flags, 
                  AppleEvent *event, 
                  AppleEvent *reply)
{
   OSErr a_result = noErr;
   WindowPtr a_window_ptr;
   Handle a_text_hdl;
   
//   Start Call

   EnterCodeResource();
   
//   Load Text

   a_text_hdl = GetResource('TEXT', 128);
   
//   If have Text, detatch it

   if (a_text_hdl!=NULL) {
   
//   Detatch Text

      DetachResource(a_text_hdl);
   
//   Create new window

      a_window_ptr = bbxtNewDocument(callbacks);
   
//   If Window correct
   
      if (a_window_ptr!=NULL) {

//   Set Content (must not dispose handle then!)

      bbxtSetWindowContents(callbacks, a_window_ptr, a_text_hdl);
      }
      
//   Dispose Text (if can not create new Doc)

      else
         DisposeHandle(a_text_hdl);
   }
   
//   Finish call

   ExitCodeResource();
   
   return a_result;
}

The second example demonstrates how to examine, and then modify the selected text inside an editable text window. The routine copies the selected text using bbxtCopy, then the copy is modified. Modification for this extension consists of stepping through each character, shifting it to upper or lower case. The first shift decides whether or not to change the remaining text up or down. Then the bbxtPaste changes the text in the current selected window. Notice the bbxtPresetUndo and bbxtSetUndo calls are used to allow this plug-in to be undoable.

Listing 2: Shift Uppercase/Lowercase.c

Main
//   Shift Uppercase/Lowercase.c
//   by Steve Sheets for MacTech Magazine
//   Sample of BBEdit extension
//      
//   Requires 'BBXF' Resource 128 with Support New Interface,
//   Undo-Savy, Requires Changeable Window, Can Be Undone,
//   and Requires Selection flags set.

//   Required includes

#include <ExternalInterface.h>
#include <A4Stuff.h>
#include <Sound.h>

//   Main entry point of extension

pascal OSErr main(ExternalCallbackBlock *callbacks, 
                  WindowPtr w, 
                  long flags, 
                  AppleEvent *event, 
                  AppleEvent *reply)
{
   OSErr a_result = noErr;
   Handle a_text_hdl;
   long a_length;
   char a_char;
   long a_count;
   short a_status = 0;   
// 0 - Case Unknown, 1 - shift to Upper, 2 - shirt to Lower
   
//   Start Call

   EnterCodeResource();
   
//   Copy Selection

   a_text_hdl = bbxtCopy(callbacks);   
   
//   Check it is not null

   if (a_text_hdl!=NULL) {
      a_length = GetHandleSize(a_text_hdl);
      
      if (a_length>0) {

//   Set Undoable

         if (bbxtPresetUndo(callbacks)) {
         
//   Set status to 0 (unknown)
//      1 indicates to shift lower case to upper
//      2 indicates to shift upper case to lower

            a_status = 0;

//   Loop through all the text, char at time
            HLock(a_text_hdl);
         
            for (a_count = 0; a_count<a_length; a_count++) {
               a_char = *(*a_text_hdl+a_count);
            
//   If status is not set

               if (a_status==0) {

//   If char is lower case, set status to Upper

                  if ((a_char>='a') && (a_char<='z'))
                     a_status = 1;

//   If char is upper case, set status to Lower

                  else if ((a_char>='A') && (a_char<='Z'))
                     a_status = 2;
               }
            
//   If char is lower & state is Upper, shift it

               if (a_status==1) {
                  if ((a_char>='a') && (a_char<='z'))
                     *(*a_text_hdl+a_count) = a_char - 'a' + 'A';
               }

//   If char is upper & state is lower, shift it

               else if (a_status==2) {
                  if ((a_char>='A') && (a_char<='Z'))
                     *(*a_text_hdl+a_count) = a_char - 'A' + 'a';
               }
            }
         
            HUnlock(a_text_hdl);

//   Return results

            bbxtPaste(callbacks, a_text_hdl);
         
//   Set Undoable

            bbxtSetUndo(callbacks);
         }
      }
      
//   Dispose Text

      DisposeHandle(a_text_hdl);
   }
   
//   Finish call

   ExitCodeResource();
   
   return a_result;
}

The Last Word

While BBEdit is a tremendously powerful and feature rich tool, perhaps it's finest selling point is the insight and humility of the Bare Bones team in realizing that they couldn't imagine or provide all the features every user would require -- so they provided us with the option to add our own features. They've given us the chance to make BBEdit the perfect tool for each of us. Hopefully, this brief survey of the plug-in architecture for BBEdit will help you to begin the challenge of tuning the power of BBEdit to the demands of your own work.


Steve Sheets has been happily programming the Macintosh since 1983, which makes him older than he wishes, but not as young as he acts. A native Californian, his wanderings have led him to northern Virginia. For those interested, his non-computer interests involve his family (wife and two daughters), the Society for Creative Anachronism (medieval reenactment) and the martial arts (Fencing, Tai Chi). Steve is currently an independent developer, taking on any and all projects and can be reached at MageSteve@aol.com.

 
AAPL
$116.47
Apple Inc.
+0.16
MSFT
$47.98
Microsoft Corpora
-0.72
GOOG
$537.50
Google Inc.
+2.67

MacTech Search:
Community Search:

Software Updates via MacUpdate

Cobook 3.0.7 - Intelligent address book....
Cobook Contacts is an intuitive, engaging address book. Solve the problem of contact management with Cobook Contacts and its simple interface and powerful syncing and integration possibilities.... Read more
StatsBar 1.9 - Monitor system processes...
StatsBar gives you a comprehensive and detailed analysis of the following areas of your Mac: CPU usage Memory usage Disk usage Network and bandwidth usage Battery power and health (MacBooks only)... Read more
Cyberduck 4.6 - FTP and SFTP browser. (F...
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Evernote 6.0.1 - Create searchable notes...
Evernote allows you to easily capture information in any environment using whatever device or platform you find most convenient, and makes this information accessible and searchable at anytime, from... Read more
calibre 2.11 - Complete e-library manage...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital... Read more
Herald 5.0.1 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
Firetask 3.7 - Innovative task managemen...
Firetask uniquely combines the advantages of classical priority-and-due-date-based task management with GTD. Stay focused and on top of your commitments - Firetask's "Today" view shows all relevant... Read more
TechTool Pro 7.0.6 - Hard drive and syst...
TechTool Pro is now 7, and this is the most advanced version of the acclaimed Macintosh troubleshooting utility created in its 20-year history. Micromat has redeveloped TechTool Pro 7 to be fully 64... Read more
PhotoDesk 3.0.1 - Instagram client for p...
PhotoDesk lets you view, like, comment, and download Instagram pictures/videos! (NO Uploads! / Image Posting! Instagram forbids that! AND you *need* an *existing* Instagram account). But you can do... Read more

Latest Forum Discussions

See All

Ubisoft Gives Everyone Two New Ways to E...
Ubisoft Gives Everyone Two New Ways to Earn In-Game Stuff for Far Cry 4 Posted by Jessica Fisher on November 21st, 2014 [ permalink ] | Read more »
Golfinity – Tips, Tricks, Strategies, an...
Dig this: Would you like to know what we thought of being an infinite golfer? Check out our Golfinity review! Golfinity offers unlimited ways to test your skills at golf. Here are a few ways to make sure your score doesn’t get too high and your... | Read more »
Dark Hearts, The Sequel to Haunting Meli...
Dark Hearts, The Sequel to Haunting Melissa, is Available Now Posted by Jessica Fisher on November 21st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Meowza! Toyze Brings Talking Tom to Life...
Meowza! | Read more »
Square Enix Announces New Tactical RPG f...
Square Enix Announces New Tactical RPG for Mobile, Heavenstrike Rivals. Posted by Jessica Fisher on November 21st, 2014 [ permalink ] With their epic stories and gorgeous graphics, | Read more »
Quest for Revenge (Games)
Quest for Revenge 1.0.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0.0 (iTunes) Description: The great Kingdom of the west has fallen. The gods ignore the prayers of the desperate. A dark warlord has extinguished... | Read more »
Threadz is a New Writing Adventure for Y...
Threadz is a New Writing Adventure for You and Your Friends Posted by Jessica Fisher on November 21st, 2014 [ permalink ] In the tradition of round-robin storytelling, | Read more »
SteelSeries Stratus XL Hardware Review
Made by: SteelSeries Price: $59.99 Hardware/iOS Integration Rating: 4 out of 5 stars Usability Rating: 4.5 out of 5 stars Reuse Value Rating: 4.25 out of 5 stars Build Quality Rating: 4.5 out of 5 stars Overall Rating: 4.31 out of 5 stars | Read more »
ACDSee (Photography)
ACDSee 1.0.0 Device: iOS iPhone Category: Photography Price: $1.99, Version: 1.0.0 (iTunes) Description: Capture, perfect, and share your photos with ACDSee. The ACDSee iPhone app combines an innovative camera, a powerful photo... | Read more »
ProTube for YouTube (Entertainment)
ProTube for YouTube 2.0.2 Device: iOS Universal Category: Entertainment Price: $1.99, Version: 2.0.2 (iTunes) Description: ProTube is the ultimate, fully featured YouTube app. With it's highly polished design, ProTube offers ad-free... | Read more »

Price Scanner via MacPrices.net

Save up to $400 with Apple refurbished 2014 1...
The Apple Store has restocked Apple Certified Refurbished 2014 15″ Retina MacBook Pros for up to $400 off the cost of new models. An Apple one-year warranty is included with each model, and shipping... Read more
New 13-inch 1.4GHz MacBook Air on sale for $8...
 Adorama has the 2014 13″ 1.4GHz/128GB MacBook Air on sale for $899.99 including free shipping plus NY & NJ tax only. Their price is $100 off MSRP. B&H Photo has the 13″ 1.4GHz/128GB MacBook... Read more
Apple Expected to Reverse Nine-Month Tablet S...
Apple and Samsung combined accounted for 62 percent of the nearly 36 million branded tablets shipped in 3Q 2014, according to early vendor shipment share estimates from market intelligence firm ABI... Read more
Stratos: 30 Percent of US Smartphone Owners t...
Stratos, Inc., creator of the Bluetooth Connected Card Platform, has announced results from its 2014 Holiday Mobile Payments Survey. The consumer survey found that nearly one out of three (30 percent... Read more
2014 1.4GHz Mac mini on sale for $449, save $...
 B&H Photo has lowered their price on the new 1.4GHz Mac mini to $449.99 including free shipping plus NY tax only. Their price is $50 off MSRP, and it’s the lowest price available for this new... Read more
Check Apple prices on any device with the iTr...
MacPrices is proud to offer readers a free iOS app (iPhones, iPads, & iPod touch) and Android app (Google Play and Amazon App Store) called iTracx, which allows you to glance at today’s lowest... Read more
64GB iPod touch on sale for $249, save $50
Best Buy has the 64GB iPod touch on sale for $249 on their online store for a limited time. Their price is $50 off MSRP. Choose free shipping or free local store pickup (if available). Sale price for... Read more
15″ 2.2GHz Retina MacBook Pro on sale for $17...
 B&H Photo has the 2014 15″ 2.2GHz Retina MacBook Pro on sale for $1799.99 for a limited time. Shipping is free, and B&H charges NY sales tax only. B&H will also include free copies of... Read more
New Logitech AnyAngle Case/Stand Brings Flexi...
Logitec has announced the newest addition to its suite of tablet products — the Logitech AnyAngle. A protective case with an any-angle stand for iPad Air 2 and all iPad mini models, AnyAngle is the... Read more
Notebook PC Shipments Rise Year-Over-Year as...
According to preliminary results from the upcoming DisplaySearch Quarterly Mobile PC Shipment and Forecast Report, the global notebook PC market grew 10 percent year-over-year in Q3’14 to 49.4... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC)- Retail S...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Project Manager, *Apple* Financial Services...
**Job Summary** Apple Financial Services (AFS) offers consumers, businesses and educational institutions ways to finance Apple purchases. We work with national and Read more
*Apple* Store Leader Program - College Gradu...
Job Description: Job Summary As an Apple Store Leader Program agent, you can continue your education as you major in the art of leadership at the Apple Store. You'll Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.