TweetFollow Us on Twitter

MACINTOSH C CARBON
MACINTOSH C CARBON: A Hobbyist's Guide To Programming the Macintosh in C
Version 1.0
2001 K. J. Bricknell
Go to Contents Go to Program Listing

CHAPTER 20

CARBON SCRAP

The Carbon Scrap Manager and the Scrap

Introduction

The inclusion of the word "Carbon" in the title of this chapter is quite deliberate, reflecting the fact that, in Carbon, the original Scrap Manager has been redesigned to fully support the needs of the preemptively scheduled Mac OS X.

Applications which support cut, copy, and paste operations write data to, and read data from, the scrap. The scrap is a storage area, maintained by the Scrap Manager, which holds the last text, graphics, sounds, etc., cut or copied by the user.

The various data formats in which data may be written to, and read from, the scrap are called scrap flavours. A scrap flavour is a self-contained, self-describing stream of bytes which represent a discreet object such as a picture or text selection. Each scrap flavour has a scrap flavour type and a set of scrap flavour flags. The scrap may contain data in one or more flavours, each flavour being a different representation of the same object.

Your application specifies the scrap flavour, or flavours, to be read from, and written to, the scrap. The ultimate aim is to allow the user to copy and paste documents:

  • Within a document created by your application.

  • Between different documents created by your application.

  • Between documents created by your application and documents created by other applications.

Location of the Scrap

On Mac OS 8/9, space is allocated for the scrap in each application's heap. The system software stores a handle to the scrap of the current process in the system global variable ScrapHandle. When an application is launched, data is copied to the newly activated application's heap from the previously active application's heap. If the scrap is too large to fit in the application's heap, the scrap is copied to disk. In this event, the handle to the scrap is set to NULL to indicate that the scrap is on disk.

On Mac OS X, the scrap is held by the pasteboard server.

Scrap Reference

A scrap is referred to by a scrap reference. The data type ScrapRef is defined as a pointer to a scrap reference:

     typedef struct OpaqueScrapRef *ScrapRef;

Note that, although there is only one scrap, there may be multiple ScrapRef values. A ScrapRef value is valid only until the scrap is cleared.

Scrap Flavours

Standard Scrap Flavours

Your application should be capable of writing at least one of the following standard scrap flavours to the scrap and should be capable of reading both:

  • 'TEXT' (that is, a series of ASCII characters).

  • 'PICT' (a QuickDraw picture).

Optional Flavours

Your application may also choose to support the following optional scrap format types:

  • 'styl' (a series of bytes which have the same format as a TextEdit 'styl' resource, and which describe styled text data).

  • 'movv' (a series of bytes which define a movie, and which have the same format as a 'movv' resource).

Private Flavours

It is also possible for your application to use its own private flavour, or flavours, but this should be in addition to at least one of the standard flavours.

Preferred Flavour

Recall that each flavour in the scrap (assuming there is more than one) is simply a different representation of the same object.

Your application should have a preferred scrap flavour. When reading data from the scrap, your application should request its preferred flavour first and only request its next preferred flavour if the preferred flavour does not exist in the scrap. When writing data to the scrap, your application should write its preferred flavour first. Any additional flavours should be written in the preferred order.

Implementing Edit Menu Commands

You use the Edit menu Cut, Copy, and Paste commands to implement cutting, copying, and pasting of data within or between documents. The following are the actions your application should perform to support these three commands:

Edit Command

Actions Performed by Your Application

Cut

If there is a current selection range, copy the data in the selection range to the desk scrap and remove the data from the document.

Copy

If there is a current selection range, copy the data in the selection range to the desk scrap.

Paste

Read the desk scrap and insert the data (if any) at the insertion point, replacing any current selection.

The insertion point in a text document is represented by the blinking vertical bar known as the caret. There is a close relationship between the selection range and the insertion point in that the insertion point is, in effect, an empty selection range.

If your application implements a Clear command, it should remove the data in the current selection range but should not save the data to the desk scrap.

Cut and Copy - Putting Data in the Scrap

A typical approach to implementing the Cut and Copy commands is as follows:

  • Determine whether the frontmost window is a document window or a dialog.

  • If the frontmost window is a document window:

    • Call ClearCurrentScrap to purge the current contents of the scrap.

    • Call GetCurrentScrap to obtain a reference to the current scrap.

    • Determine whether the current selection contains text or a picture.

    • If the current selection is text, get a pointer to the selected text and get the size of the selection. If the current selection is a picture, get a pointer to the picture structure and get the size of that structure.

    • Call PutScrapFlavor to write the data to the scrap, passing the appropriate flavour type in the flavorType parameter.

    • If the command was the Cut command, delete the selection from the current document.
    
    

  • If the frontmost window is a dialog, use the Dialog Manager functions DialogCut or DialogCopy, as appropriate, to write the selected data to the scrap.

Paste - Getting Data From the Scrap

When you read the data from the scrap, your application should request the data in the application's preferred flavour type. If your application determines that that flavour does not exist in the scrap, it should then request the data in another flavour. If your application does not have a preferred flavour type, it should read each flavour type that your application supports.

If you request a scrap format that is not in the scrap, the Scrap Manager uses the Translation Manager to convert any one of the scrap flavour types currently in the scrap into the scrap flavour requested by your application. The Translation Manager looks for a translator that can perform one of these translations. If such a translator is available, the Translation Manager uses the translator to translate the data in the scrap into the requested flavour.

A typical approach to an implementation of the Paste command, for an application that prefers a flavour type of 'TEXT' as its first preference, is as follows:

  • Determine whether the frontmost window is a document window or a dialog.

  • If the frontmost window is a document window:

    • Call GetCurrentScrap to obtain a reference to the current scrap.

    • Call GetScrapFlavorFlags to determine whether the preferred flavour exists in the scrap.

    • If the preferred flavour type ('TEXT') does exist, call GetScrapFlavorSize to get the size of the text data, allocate a relocatable block of that size, and call GetScrapFlavorData to read the data into that block. Copy the data in the relocatable block to the current document at the insertion point.

    • If the preferred flavour type does not exist, call GetScrapFlavorFlags again to determine whether the next preferred flavour (say, 'PICT') exists in the scrap. If it does, call GetScrapFlavorSize to get the size of the picture data, allocate a relocatable block of that size, and call GetScrapFlavorData to read the data into that block. Call DrawPicture to draw the picture described by the data in the relocatable block in the current document at the insertion point.

  • If the frontmost window is a dialog, use the Dialog Manager function DialogPaste to paste the text from the scrap in the dialog.

Enabling the Paste Menu Item

Your application can determine whether to enable the Paste item in the Edit menu by calling GetScrapFlavorFlags to determine whether the scrap contains data of the flavour type specified in that call. GetScrapFlavorFlags returns noErr if the specified flavour exists.

Example

Fig 1 illustrates two cases, both of which deal with a user copying a picture consisting of text from a source document created by one application to a destination document created by another application.

In the first case, the source application has chosen to write only the 'PICT' flavour to the scrap, and the destination application has pasted the data, in that flavour, to its document.

In the second case, the source application has chosen to write both the 'TEXT' and 'PICT' flavours to the scrap, and the destination application has chosen the 'TEXT' flavour as the preferred flavour for the paste. The data is thus inserted into the document as editable text.

Clipboard Windows

Your application can provide a Show Clipboard command in the Edit menu which, when chosen, shows a window which displays the current contents of the scrap. Such a window is known as a Clipboard window. The Show Clipboard command should be toggled with a Hide Clipboard command to allow the user to hide the Clipboard window when required.

Although the scrap may contain multiple scrap flavours, your Clipboard window should ordinarily display the data in the application's preferred flavour only.

If the user has chosen to open the Clipboard window, your application should hide the window on receipt of a suspend event and show it when a resume event is received. This is necessary because the contents of the scrap could change while the application is in the background.

Transferring the Desk Scrap to Disk - Mac OS 8/9

Although, on Mac OS 8/9, the scrap is usually located in memory, your application can write the contents of the scrap in memory to a scrap file using UnloadScrap. You should do this only if memory is not large enough to hold the data you need to write to the scrap. After writing the contents of the scrap to disk, UnloadScrap releases the memory previously occupied by the scrap. Thereafter, any operations your application performs on data in the scrap affect the scrap as stored in the scrap file on disk. You can use LoadScrap to read the contents of the scrap file back into memory.

On Mac OS X, calls to LoadScrap and UnloadScrap are ignored.

Main Carbon Scrap Manager Functions

The main Carbon Scrap Manager functions are as follows:

Function

Description

GetCurrentScrap

Gets a reference to the current scrap. (Note that this reference will become invalid and unusable after the scrap is cleared.)

GetScrapFlavorFlags

Determines whether the scrap contains data for a particular flavour and provides information about that flavour if it exists. (Amongst other things, this function is useful for deciding whether to enable the Paste item in your Edit menu.)

GetScrapFlavorSize

Gets the size of the data of the specified flavour from the specified scrap.

GetScrapFlavorData

Gets the data of the specified flavour from the specified scrap.

ClearCurrentScrap

Clears the current scrap. This function should be called immediately the user requests a Copy or Cut operation.

PutScrapFlavor

Puts data on the scrap. Also promises data to the specified scrap (see below).

Associated Constants and Data Types

The following constants and data types are associated with the main Scrap Manager functions:

Scrap Flavour Type Constants

Constant

Flavour Type

Description

kScrapFlavorTypePicture 'PICT'

Picture

kScrapFlavorTypeText 'TEXT'

Text

kScrapFlavorTypeTextStyle 'styl'

Text style

kScrapFlavorTypeMovie 'moov'

Movie

Scrap Flavour Flag Constants

In the following, the first two constants may be passed in the flavorFlags parameter in calls to PutScrapFlavour, and the third is received in the flavorFlags parameter in calls to GetScrapFlavorFlags:

Constant

Meaning

kScrapFlavorMaskNone

No flags required.

kScrapFlavorMaskSenderOnly

Only the process which puts the flavour on the scrap can see it.

If another process puts a flavour with this flag on the scrap,your process will never see the flavour. Accordingly, there is no point in testing for this flag.

This flag is typically used to save a private flavour to the scrap so that other promised (see below) public flavours can be derived from it on demand.

kScrapFlavorMaskTranslated

The flavour was translated, by the Translation Manager, from some other flavour in the scrap. (Most callers should not care about this flag.) (Most callers should not care about this flag.)

ScrapFlavorInfo Data Type

The ScrapFlavorInfo data type describes a single flavour within a scrap and is used by those functions which get information about the current scrap (GetScrapFlavorFlags, GetScrapFlavorSize, and GetScrapFlavorData):
     struct ScrapFlavorInfo 
     {
       ScrapFlavorType  flavorType;
       ScrapFlavorFlags flavorFlags;
     };
     typedef struct ScrapFlavorInfo ScrapFlavorInfo;

Private Scrap

As an alternative to writing to and reading from the scrap whenever the user cuts, copies and pastes data, your application can choose to use its own private scrap. An application which uses a private scrap copies data to its private scrap when the user chooses the Cut or Copy command and pastes data from the private scrap when the user chooses the Paste command.

Additional Actions - Old Scrap Manager

In the old pre-Carbon Scrap Manager, an application which used a private scrap had to take the following additional actions whenever it received suspend and resume events:

  • Suspend Event. On receipt of a suspend event, the application had to copy data from the private scrap to the scrap.

  • Resume Event. On receipt of a resume event, the application had to first examine the convertClipboardFlag bit in the message field of the resume event structure to determine if the data in the scrap had changed since the previous suspend event. If the data in the scrap had changed, the application had to copy the data from the scrap to its private scrap. The application's menu adjustment function enabled the Paste item if the data copied to the private scrap was of the preferred, or other acceptable, type.

The process is illustrated at Fig 2.

Additional Actions - Carbon Scrap Manager

In the preemptively scheduled Mac OS X, this rather straightforward approach is no longer feasible. Consider the following scenario on Mac OS X:

  • Application B, which has a private scrap, is the frontmost application. The user clicks in a window belonging to application A to make application A the frontmost application. Application B receives a suspend event and begins to convert its private scrap.

  • While application B is still converting its private scrap, application A has become the frontmost application, and the user clicks in its menu bar. Application A, needing to decide whether to enable the Paste item in its Edit menu, looks at the scrap to determine what flavours it contains. Because application B has not finished converting its private scrap, and thus has not put anything onto the scrap, application A finds nothing it wants on the scrap and, accordingly, disables the Paste item.

The situation in which application A finds itself with regard to the Paste item is not acceptable in terms of human interface. The user cannot be expected to know that application B is still converting its scrap and that application As Paste item will be enabled in due course.

Making Promises

The Carbon Scrap Manager eliminates this problem using the concept of promised flavours. If, in the above example, application B calls PutScrapFlavor with NULL passed in the flavorData parameter whenever the user chooses Cut or Copy, a promise is made that data of the flavour specified in the flavorType parameter will later be placed on the scrap. On checking the scrap, application A will see the promise and can thus enable its Paste item in the expectation that the actual data will eventually appear in the scrap. The actual data can then be provided by application B through a subsequent call to PutScrapFlavor during the execution of a scrap promise keeper (callback) function. (Scrap promise keeper callback functions are called by the Carbon Scrap Manager as required to keep an earlier promise of a particular scrap flavour.)

In the first (promise-making) call to PutScrapFlavor, passing a non-zero size in the flavorSize parameter is optional; however, providing the size is advisable because callers of GetScrapFlavorSize will then be able to avoid blocking. If the size is provided, the subsequent call to PutScrapFlavor must provide the same amount of data as was promised. If the size is unknown at the time of the promise, your application should pass kScrapFlavorSizeUnknown in the flavorSize parameter.

Note that the promise-making PutScrapFlavor call cannot be made when your application receives a suspend event. This is because of the fundamental difference between the receipt of suspend events in Carbon applications as compared with Classic applications (see Chapter 2). Making the promise each time the user chooses Cut or Copy involves very little overhead, since only the promise, not the data, is being placed on the scrap.

Calling In Promises

In applications that use the Classic event model, your application should invariably call CallInScrapPromises on exit to cater for the possibility that it may have made promises that, after it quits, it cannot possibly honour. CallInScrapPromises forces all promises to be kept. On Mac OS X, this action is necessary even if your application has itself made no promises, the reason being that it is possible that, unbeknown to the application, promises could have been made on its behalf. For example, when you copy TEXT data (which has ASCII 13 for line endings) onto the scrap, the Carbon Scrap Manager promises other flavours which have different line endings and/or text encodings so that Cocoa applications can paste.

Calling CallInScrapPromises is not necessary in applications which use the Carbon event model model because the call will be made automatically in that case.

TextEdit, Dialogs, and Scrap

TextEdit and Scrap

TextEdit is a collection of functions and data structures which you can use to provide your application with basic text editing capabilities.

If your application uses TextEdit in its windows, be aware that TextEdit maintains its own private scrap. Accordingly:

  • PutScrap is not used and the special TextEdit functions TECut, TECopy, and TEToScrap are used in the processes of cutting text from the document and copying text to the TextEdit private scrap and to the desk scrap.

  • GetScrap is not used and the special TextEdit functions TEPaste, TEStylePaste, and TEFromScrap are used in the processes of pasting text from the TextEdit private scrap and copying text from the desk scrap to the TextEdit private scrap.

Chapter 21 describes TextEdit, including the TextEdit private scrap and the TextEdit scrap-related functions.

Dialogs and Scrap

Dialogs may contain edit text items, and the Dialog Manager uses TextEdit to perform the editing operations within those items.

You can use the Dialog Manager to handle most editing operations within dialogs. The Dialog Manager functions DialogCut, DialogCopy, and DialogPaste may be used to implement Cut, Copy and Paste commands within edit text items in dialogs. (See the demonstration program at Chapter 8.)

TextEdit's private scrap facilitates the copying and pasting of data between dialogs. However, your application itself must ensure that the user can copy and paste data between your application's dialogs and its document windows. If your application uses TextEdit for all editing operations within its document windows, this is easily achieved because TextEdit's TECut, TECopy, TEPaste, and TEStylePaste functions and the Dialog Manager's DialogCut, DialogCopy, and DialogPaste functions all use TextEdit's private scrap.

Main Carbon Scrap Manager Data Types and Functions

Constants

Scrap Flavour Types

kScrapFlavorTypePicture    = FOUR_CHAR_CODE('PICT')  // Picture
kScrapFlavorTypeText       = FOUR_CHAR_CODE('TEXT')  // Text
kScrapFlavorTypeTextStyle  = FOUR_CHAR_CODE('styl')  // Text style
kScrapFlavorTypeMovie      = FOUR_CHAR_CODE('moov')  // Movie
kScrapFlavorTypeSound      = FOUR_CHAR_CODE('snd ')  // Sound

Scrap Flavour Flags

kScrapFlavorMaskNone       = 0x00000000
kScrapFlavorMaskSenderOnly = 0x00000001
kScrapFlavorMaskTranslated = 0x00000002

Promising Flavours

kScrapFlavorSizeUnknown    = -1

Result Codes

internalScrapErr            = -4988
duplicateScrapFlavorErr     = -4989
badScrapRefErr              = -4990
processStateIncorrectErr    = -4991
scrapPromiseNotKeptErr      = -4992
noScrapPromiseKeeperErr     = -4993
nilScrapFlavorDataErr       = -4994
scrapFlavorFlagsMismatchErr = -4995
scrapFlavorSizeMismatchErr  = -4996
illegalScrapFlavorFlagsErr  = -4997
illegalScrapFlavorTypeErr   = -4998
illegalScrapFlavorSizeErr   = -4999
scrapFlavorNotFoundErr      = -102
needClearScrapErr           = -100

Data Types

typedef struct OpaqueScrapRef *ScrapRef;
typedef FourCharCode               ScrapFlavorType;
typedef UInt32                     ScrapFlavorFlags;

ScrapFlavorInfo

struct ScrapFlavorInfo 
{
 ScrapFlavorType  flavorType;
 ScrapFlavorFlags flavorFlags;
};
typedef struct ScrapFlavorInfo ScrapFlavorInfo;

Functions

Obtaining a Reference to the Current Scrap

OSStatus  GetCurrentScrap(ScrapRef *scrap);

Obtaining Information About a Specific Scrap Flavour

OSStatus  GetScrapFlavorFlags(ScrapRef scrap,ScrapFlavorType flavorType,
          ScrapFlavorFlags *flavorFlags);

Obtaining the Size of Data of a Specified Scrap Flavour

OSStatus  GetScrapFlavorSize(ScrapRef scrap,ScrapFlavorType flavorType,
          Size *byteCount);

Obtaining the Data of a Specified Scrap Flavour

OSStatus  GetScrapFlavorData(ScrapRef scrap,ScrapFlavorType flavorType,
          Size *byteCount,void *destination);

Writing Data to the Scrap and Clearing the Scrap

OSStatus  PutScrapFlavor(ScrapRef scrap,ScrapFlavorType flavorType,
          ScrapFlavorFlags  flavorFlags,Size flavorSize,const void *flavorData);
OSStatus  ClearCurrentScrap(void);

Scrap Promise Keeping

ScrapPromiseKeeperUPP  NewScrapPromiseKeeperUPP(ScrapPromiseKeeperProcPtr userRoutine);
void      DisposeScrapPromiseKeeperUPP(ScrapPromiseKeeperUPP userUPP);
OSStatus  SetScrapPromiseKeeper(ScrapRef scrap,ScrapPromiseKeeperUPP upp,
          const void *userData);
OSStatus  CallInScrapPromises(void);

Application-Defined (Callback) Function

OSStatus myScrapPromiseKeeperFunction(ScrapRef scrap,ScrapFlavorType flavorType,
         void *userData);

Transferring the Scrap Between Memory and Disk (Mac OS 8/9)

SInt32 UnloadScrap(void); // Does nothing when called on Mac OS X
SInt32 LoadScrap(void);   // Does nothing when called on Mac OS X

 
AAPL
$108.00
Apple Inc.
+1.02
MSFT
$46.95
Microsoft Corpora
+0.90
GOOG
$559.08
Google Inc.
+8.77

MacTech Search:
Community Search:

Software Updates via MacUpdate

Vitamin-R 2.20b1 - Personal productivity...
Vitamin-R creates the optimal conditions for your brain to work at its best by structuring your work into short bursts of distraction-free, highly focused activity alternating with opportunities for... Read more
Dropbox 2.10.44 - Cloud synchronization...
Dropbox is an application that creates a special Finder folder that automatically syncs online and between your computers. It allows you to both backup files and keep them up-to-date between systems... Read more
Sandvox 2.9.2 - Easily build eye-catchin...
Sandvox is for Mac users who want to create a professional looking website quickly and easily. With Sandvox, you don't need to be a Web genius to build a stylish, feature-rich, standards-compliant... Read more
Cocktail 8.0.1 - General maintenance and...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
LibreOffice 4.3.3.2 - Free Open Source o...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
VMware Fusion 7.0.1 - Run Windows apps a...
VMware Fusion allows you to create a Virtual Machine on your Mac and run Windows (including Windows 8.1) and Windows software on your Mac. Run your favorite Windows applications alongside Mac... Read more
OneNote 15.3.2 - Free digital notebook f...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more
Audio Hijack Pro 2.11.4 - Record and enh...
Audio Hijack Pro drastically changes the way you use audio on your computer, giving you the freedom to listen to audio when you want and how you want. Record and enhance any audio with Audio Hijack... Read more
Iridient Developer 3.0.0 beta 3 - Powerf...
Iridient Developer (was RAW Developer) is a powerful image conversion application designed specifically for OS X. Iridient Developer gives advanced photographers total control over every aspect of... Read more
TextWrangler 4.5.11 - Free general purpo...
TextWrangler is the powerful general purpose text editor, and Unix and server administrator's tool. Oh, and also, like the best things in life, it's free. TextWrangler is the "little brother" to... Read more

Latest Forum Discussions

See All

Monster Flash Review
Monster Flash Review By Jordan Minor on October 31st, 2014 Our Rating: :: ALONE IN THE DARKUniversal App - Designed for iPhone and iPad Solid shooting and a surprising amount of spooky tension make Monster Flash a great portable... | Read more »
Retry Review
Retry Review By Rob Thomas on October 31st, 2014 Our Rating: :: SOARING HIGHUniversal App - Designed for iPhone and iPad Flappy who? Let Retry wash all those bad bird-related memories away on a cool retro-flavored flight… right... | Read more »
Dementia: Book of the Dead Review
Dementia: Book of the Dead Review By Lee Hamlet on October 31st, 2014 Our Rating: :: A TOUGH READUniversal App - Designed for iPhone and iPad A witch hunter is sent after a demonic book in the spooky but short-lived Dementia: Book... | Read more »
Card Dungeon, the Semi-Board Game Roguel...
Card Dungeon, the Semi-Board Game Roguelike, Has Been Renovated Posted by Jessica Fisher on October 31st, 2014 [ permalink ] | Read more »
Logitech Protection + Power iPhone5/5S C...
Made by: Logitech Price: $99.99 Hardware/iOS Integration Rating: 3 out of 5 stars Usability Rating: 0.5 out of 5 stars Reuse Value Rating: 0.75 out of 5 stars Build Quality Rating: 0.75 out of 5 stars Overall Rating: 1.25 out of 5 stars | Read more »
This Is Not a Test Goes Free, Permanentl...
This Is Not a Test Goes Free, Permanently Posted by Jessica Fisher on October 31st, 2014 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Swap Heroes Review
Swap Heroes Review By Campbell Bird on October 31st, 2014 Our Rating: :: STRATEGIC SWAPPINGUniversal App - Designed for iPhone and iPad Rotate a cast of heroes to fend of waves of monsters in this difficult, puzzle rpg.   | Read more »
Night Sky Pro™ (Reference)
Night Sky Pro™ 3.0.1 Device: iOS Universal Category: Reference Price: $2.99, Version: 3.0.1 (iTunes) Description: Night Sky Pro™Wonder No More™ Night Sky Pro™ is the ultimate stargazing experience. From the creators of the original... | Read more »
Audio Defence : Zombie Arena (Games)
Audio Defence : Zombie Arena 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: A zombie shooter audio game. Made from gut-wrenching 3D binaural sound, for a new kind of weird immersion. You... | Read more »
RPG Asdivine Hearts (Games)
RPG Asdivine Hearts 1.1.0 Device: iOS Universal Category: Games Price: $3.99, Version: 1.1.0 (iTunes) Description: SPECIAL PRICE50% OFF (USD 7.99 -> USD 3.99)!!! Travel alongside four companions and a cat in the adventure of a... | Read more »

Price Scanner via MacPrices.net

Tablets Ascendent Again; Global Tablet Market...
The worldwide tablet grew 11.5% year over year in the third quarter of 2014 (3Q14) with shipments reaching 53.8 million units according to preliminary data from the International Data Corporation (... Read more
Apple now offering refurbished 2014 13-inch R...
The Apple Store is now offering Apple Certified Refurbished 2014 13″ Retina MacBook Pros for up to $270 off the cost of new models. An Apple one-year warranty is included with each model, and... Read more
Apple Regains Momentum As Windows Stutters An...
The latest smartphone sales data from Kantar Worldpanel ComTech, for the three months to March 2014, shows Apple performing strongly in the first quarter of the year, with sales bouncing back in... Read more
Worldwide Smartphone Shipments Increase 25.2%...
New smartphone releases and an increased emphasis on emerging markets drove global smartphone shipments above 300 million units for the second consecutive quarter, according to preliminary data from... Read more
Apple now offering refurbished 2014 15-inch M...
The Apple Store is now offering 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... Read more
Apple drops prices on refurbished 2013 Retina...
The Apple Store has dropped prices on 2013 Apple Certified Refurbished 13″ and 15″ Retina MacBook Pros, with Retina models now available starting at $999. Apple’s one-year warranty is standard, and... Read more
New 2.8GHz Mac mini on sale for $949, save $5...
Abt Electronics has the new 2.8GHz Mac mini in stock and on sale for $949.05 including free shipping. Their price is $50 off MSRP, and it’s the lowest price available for this model from any reseller... Read more
Sale! 3.7GHz Quad Core Mac Pro available for...
 B&H Photo has the 3.7GHz Quad Core Mac Pro on sale for $2649 including free shipping plus NY sales tax only. Their price is $350 off MSRP, and it’s the lowest price for this model from any... Read more
Mujjo Steps Up The Game With Refined Touchscr...
Netherlands based Mujjo have just launched their Refined Touchscreen Gloves, stepping up their game. The gloves feature a updated elegant design that takes these knitted gloves to the next level. A... Read more
Sale! Preorder the new 27-inch 5K iMac for $2...
 Abt Electronics has the new 27″ 3.5GHz 5K iMac on sale and available for preorder for $2374.05 including free shipping. Their price is $125 off MSRP, and it’s the lowest price available for this... Read more

Jobs Board

Position Opening at *Apple* - Apple (United...
…Summary** As a Specialist, you help create the energy and excitement around Apple products, providing the right solutions and getting products into customers' hands. You Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** Being a Business Manager at an Apple Store means you're the catalyst for businesses to discover and leverage the power, ease, and flexibility of Apple Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** As more and more people discover Apple , they visit our stores seeking ways to incorporate our products into their lives. It's your job, as a Store Read more
Position Opening at *Apple* - Apple (United...
**Job Summary** At the Apple Store, you connect business professionals and entrepreneurs with the tools they need in order to put Apple solutions to work in their Read more
Solutions Specialist with *Apple* Knowledge...
Company Description: We are an Apple Authorized Sales and Service Provider. We have been selling and servicing Apple computers in the Fairfield County area for over Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.