// $Revision: 1.6 $ // Copyright (C)1995 Taligent,Inc. All rights reserved. #ifndef Taligent_GUICOMPOUNDDOCUMENT #include #endif #ifndef Taligent_MODELSCRAPITEM #include #endif #ifndef TaligentSamples_WEBMODEL #include "WebModel.h" #endif #ifndef TaligentSamples_WEBPRESENTERSTATE #include "WebPresenterState.h" #endif #ifndef TaligentSamples_WEBLINK #include "WebLink.h" #endif #ifndef Taligent_TEXTGRAPHIC #include #endif #ifndef TaligentSamples_GRAPHICDOCUMENTVIEW #include #endif #ifndef Taligent_RANDOMNUMBER #include #endif #ifndef Taligent_LOCALIZATION #include #endif #ifndef Taligent_NUMBERFORMAT #include #endif #ifndef Taligent_MULTIPLEROOTLOCATOR #include #endif #ifndef Taligent_SCRAPITEMON #include #endif #ifndef TaligentSamples_HYPERTEXTSCRAPITEM #include "HypertextScrapItem.h" #endif typedef TGUIComponentStationeryFor TWebStationery; TDocumentReference TWebModel::OpenWebDocument(const TURL& URL) { static TUniformRandomInteger randomNumbers; long randomNumber = randomNumbers.Next(); char randomString[100]; TLocale currentLocale; TLocale::GetCurrentLocale(currentLocale); TLocaleItem item; TDeleterFor numberFormatter = item.CopyItem(TLocale::kNumberFormatID, currentLocale); TStandardText numText; TNumberFormatResult result; numberFormatter->Format(TFormatableNumber(randomNumber), numText, result); TStandardText documentName = "WebDocument."; documentName += numText; TMultipleRootLocator locator(THostSpecificPathName("Places/DefaultUserHomePlace/Temp")); TDirectory directory = locator.GetWritableDirectory(true); TDocumentReference reference; try { TDeleterFor webStationery(new TWebStationery); TDocumentComponent* component = webStationery->CreateComponent( new TWebModel(URL), new TWebPresenterState); TCompoundDocumentStationery documentStationery(webStationery.OrphanObject()); TStandardStorageMechanism store(directory, documentName); reference = documentStationery.CreateDocument(component, store); TDeleterFor environment( TPlaceEnvironment::CopyPlaceEnvironmentFor( TPlaceReference::GetDefaultPlace())); environment->OpenDocument(reference); } catch (const TStandardException& exception) { qprintf("Exception thrown while opening web document\n"); } return reference; } ModelDefinitionsMacroOne(TWebModel, kOriginalVersion, TEmbedderTextModel); TWebModel::TWebModel() : TEmbedderTextModel(), fCurrentURL(), fCurrentTitle() { } TWebModel::TWebModel(const TURL& firstURL) : TEmbedderTextModel(), fCurrentURL(firstURL), fCurrentTitle() { FollowURL(fCurrentURL); } TWebModel::TWebModel(const TWebModel& source) : TEmbedderTextModel(source), fCurrentURL(source.fCurrentURL), fCurrentTitle(source.fCurrentTitle) { FollowURL(fCurrentURL); } TWebModel::~TWebModel() { } TWebModel& TWebModel::operator=(const TWebModel& source) { if (&source != this) { TEmbedderTextModel::operator=(source); fCurrentURL = source.fCurrentURL; fCurrentTitle = source.fCurrentTitle; } return *this; } TStream& TWebModel::operator>>=(TStream& toStream) const { WriteVersion(toStream); TEmbedderTextModel::operator>>=(toStream); fCurrentURL >>= toStream; // There's no need to stream out the title since streaming in is // immediately followed by a call to FollowURL, which recreates the // title. return toStream; } TStream& TWebModel::operator<<=(TStream& fromStream) { TURL url; ::ReadVersion(fromStream, kOriginalVersion, kOriginalVersion); RemoveText(TTextArea::GetMaximumArea()); TEmbedderTextModel::operator<<=(fromStream); url <<= fromStream; FollowURL(url); return fromStream; } TURL TWebModel::FollowURL(const TURL& newURL) { const TURL oldURL = fCurrentURL; // The title of a document defaults to the URL's text representation. fCurrentTitle = newURL.GetURLText(); fCurrentURL = newURL; const TTypeDescription hypertextScrapType(StaticTypeInfo(THypertextScrapItem)); const TTypeDescription graphicScrapType(StaticTypeInfo(TScrapItemOn)); const TTypeDescription componentScrapType = TEmbedderModel::GetTypeDescription(); TDequeOf acceptableTypes( new TOperatorComparator, NIL); acceptableTypes.Add(&hypertextScrapType); acceptableTypes.Add(&graphicScrapType); acceptableTypes.Add(&componentScrapType); TDeleterFor scrapItem = newURL.Follow(acceptableTypes); if (scrapItem != NIL) { THypertextScrapItem* textScrapItem = 0; DynamicCastTo(textScrapItem, scrapItem.GetObject()); if (textScrapItem != 0) { AcceptHypertextScrap(*textScrapItem); } else { TScrapItemOn* graphicScrapItem = 0; DynamicCastTo(graphicScrapItem, scrapItem.GetObject()); if (graphicScrapItem != 0) { // This is a special case to deal with URLs that lead to // graphics. These can be retrieved as components when // CommonPoint supports a layout negotiation interface to // determine the dimensions of a component, but for now, these // are manually handled as graphics to allow the sample to // determine the dimensions of the component. MGraphic* graphic = graphicScrapItem->OrphanObject(); TGRect graphicSize = graphic->GetLooseFitBounds(); TGPoint componentSize(graphicSize.GetWidth(), graphicSize.GetHeight()); TDocumentComponent* component = new TDocumentComponent( new TAtomicModelOn(graphic), new TGUIPresenterStateFor >); AdoptComponentAt(component, componentSize, TTextRange::GetMaximumRange()); } else { TModelScrapItem* modelScrapItem = 0; DynamicCastTo(modelScrapItem, scrapItem.GetObject()); if (modelScrapItem != 0) { AcceptModelScrap(*modelScrapItem); } else { ReplaceText(TStandardText("UNABLE TO RETRIEVE URL"), TTextRange::GetMaximumRange()); } } } } else { TStandardText failMessage("No translator available to display URL "); failMessage += newURL.GetURLText(); ReplaceText(failMessage, TTextRange::GetMaximumRange()); } NotifyOfChange(TNotification(GetAllChangesInterest())); return oldURL; } TStandardText TWebModel::GetPageTitle() const { return fCurrentTitle; } void TWebModel::AcceptModelScrap(const TModelScrapItem& modelScrapItem) { TDeleterFor model = modelScrapItem.CopyModel(TType(StaticTypeInfo(TModel))); TEmbedderModel* containerModel = 0; DynamicCastTo(containerModel, model.GetObject()); if (containerModel != NIL) { TDeleterFor > iterator = containerModel->CreateComponentIterator(); TDocumentComponent* component = iterator->First(); if (component != NIL) { AdoptComponentAt(containerModel->OrphanAndUnembed(*component), TGPoint(200,200), TTextRange::GetMaximumRange()); } } } void TWebModel::AcceptHypertextScrap(const THypertextScrapItem& hypertextScrap) { const TText* hypertext = hypertextScrap.GetText(); if (hypertext != 0) { ReplaceText(*hypertext, TTextRange::GetMaximumRange()); } const TText* title = hypertextScrap.GetTitle(); if (title != 0) { fCurrentTitle = *title; } // Links are kept as a list of URLs and then converted into components // when they are actually embedded into the text. TDeleterFor > > iterator = hypertextScrap.CreateLinkIterator(); for (TKeyValuePair* linkPair = iterator->First(); linkPair != 0; linkPair = iterator->Next()) { TTextRange* linkRange = linkPair->GetKey(); TURL* linkURL = linkPair->GetValue(); const TText* currentText = GetText(); TStandardText textToDisplay; currentText->Extract(*linkRange, textToDisplay); TTextLabel displayTextLabel(textToDisplay); TGPoint linkSize(displayTextLabel.GetBounds().GetWidth() + 16, displayTextLabel.GetBounds().GetHeight() + 5); TDocumentComponent* linkComponent = TWebLink::CreateWebLinkComponent(*linkURL, textToDisplay, TModelReference(*this)); try { AdoptComponentAt(linkComponent, linkSize, *linkRange); } catch(const TStandardException& exception) { // This currently throws an exception, but seems to work fine // if caught. } } }