lib Library API Documentation

koDocumentChild.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017    Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <kparts/partmanager.h>
00021 
00022 #include <koDocumentChild.h>
00023 #include <koDocument.h>
00024 #include <koQueryTrader.h>
00025 #include <kmimetype.h>
00026 #include <klocale.h>
00027 #include <kmessagebox.h>
00028 
00029 #include <qapplication.h>
00030 
00031 #include <kdebug.h>
00032 #include <assert.h>
00033 
00034 // Define the protocol used here for embedded documents' URL
00035 // This used to "store" but KURL didn't like it,
00036 // so let's simply make it "tar" !
00037 #define STORE_PROTOCOL "tar"
00038 #define INTERNAL_PROTOCOL "intern"
00039 // Warning, keep it sync in koStore.cc and koDocument.cc
00040 
00041 /**********************************************************
00042  *
00043  * KoDocumentChild
00044  *
00045  **********************************************************/
00046 
00047 class KoDocumentChildPrivate
00048 {
00049 public:
00050   KoDocumentChildPrivate()
00051   {
00052   }
00053   ~KoDocumentChildPrivate()
00054   {
00055   }
00056 
00057   KoDocument *m_parent;
00058   KoDocument *m_doc;
00059   bool m_deleted;
00060 };
00061 
00062 KoDocumentChild::KoDocumentChild( KoDocument* parent, KoDocument* doc, const QRect& geometry )
00063     : KoChild( parent )
00064 {
00065   d = new KoDocumentChildPrivate;
00066   d->m_parent = parent;
00067   d->m_doc = doc;
00068   setGeometry( geometry );
00069   d->m_deleted = false;
00070   if ( doc )
00071     doc->setStoreInternal( !doc->hasExternURL() );
00072 }
00073 
00074 KoDocumentChild::KoDocumentChild( KoDocument* parent )
00075     : KoChild( parent )
00076 {
00077   d = new KoDocumentChildPrivate;
00078   d->m_parent = parent;
00079   d->m_doc = 0L;
00080   d->m_deleted = false;
00081 }
00082 
00083 void KoDocumentChild::setDocument( KoDocument *doc, const QRect &geometry )
00084 {
00085   kdDebug()<<k_funcinfo<<"doc: "<<doc->url().url()<<endl;
00086   d->m_doc = doc;
00087   setGeometry( geometry );
00088 
00089   updateMatrix();
00090 }
00091 
00092 KoDocument *KoDocumentChild::document() const
00093 {
00094   return d->m_doc;
00095 }
00096 
00097 KoDocument *KoDocumentChild::parentDocument() const
00098 {
00099   return d->m_parent;
00100 }
00101 
00102 KoDocument *KoDocumentChild::hitTest( const QPoint &p, const QWMatrix &_matrix )
00103 {
00104   if ( !region( _matrix ).contains( p ) || !document() )
00105     return 0L;
00106 
00107   QWMatrix m( _matrix );
00108   m = matrix() * m;
00109   m.scale( xScaling(), yScaling() );
00110 
00111   return document()->hitTest( p, m );
00112 }
00113 
00114 bool KoDocumentChild::load( const QDomElement& element, bool uppercase )
00115 {
00116     if ( element.hasAttribute( "url" ) )
00117         m_tmpURL = element.attribute("url");
00118     if ( element.hasAttribute("mime") )
00119         m_tmpMimeType = element.attribute("mime");
00120 
00121     if ( m_tmpURL.isEmpty() )
00122     {
00123         kdDebug(30003) << "Empty 'url' attribute in OBJECT" << endl;
00124         return false;
00125     }
00126     if ( m_tmpMimeType.isEmpty() )
00127     {
00128         kdDebug(30003) << "Empty 'mime' attribute in OBJECT" << endl;
00129         return false;
00130     }
00131 
00132     bool brect = FALSE;
00133     QDomElement e = element.firstChild().toElement();
00134     for( ; !e.isNull(); e = e.nextSibling().toElement() )
00135     {
00136         if ( e.tagName() == "rect" || ( uppercase && e.tagName() == "RECT" ) )
00137         {
00138             brect = true;
00139             int x, y, w, h;
00140             x=y=w=h=0;
00141             if ( e.hasAttribute( "x" ) )
00142                 x = e.attribute( "x" ).toInt(&brect);
00143             if ( e.hasAttribute( "y" ) )
00144                 y = e.attribute( "y" ).toInt(&brect);
00145             if ( e.hasAttribute( "w" ) )
00146                 w = e.attribute( "w" ).toInt(&brect);
00147             if ( e.hasAttribute( "h" ) )
00148                 h = e.attribute( "h" ).toInt(&brect);
00149             m_tmpGeometry = QRect(x, y, w, h);
00150             setGeometry(m_tmpGeometry);
00151         }
00152     }
00153 
00154     if ( !brect )
00155     {
00156         kdDebug(30003) << "Missing RECT in OBJECT" << endl;
00157         return false;
00158     }
00159 
00160     return true;
00161 }
00162 
00163 bool KoDocumentChild::loadDocument( KoStore* store )
00164 {
00165     assert( !m_tmpURL.isEmpty() );
00166 
00167     kdDebug(30003) << "KoDocumentChild::loadDocument: trying to load " << m_tmpURL << endl;
00168 
00169     // Backwards compatibility
00170     if ( m_tmpMimeType == "application/x-killustrator" )
00171         m_tmpMimeType = "application/x-kontour";
00172 
00173     KoDocumentEntry e = KoDocumentEntry::queryByMimeType( m_tmpMimeType );
00174     if ( e.isEmpty() )
00175     {
00176         kdWarning(30003) << "Could not create child document with type " << m_tmpMimeType << endl;
00177         bool res = createUnavailDocument( store, true );
00178         if ( res )
00179         {
00180             // Try to turn the mimetype name into its comment
00181             QString mimeName = m_tmpMimeType;
00182             KMimeType::Ptr mime = KMimeType::mimeType( m_tmpMimeType );
00183             if ( mime->name() != KMimeType::defaultMimeType() )
00184                 mimeName = mime->comment();
00185             d->m_doc->setProperty( "unavailReason", i18n( "No handler found for %1" ).arg( mimeName ) );
00186         }
00187         return res;
00188     }
00189 
00190     return loadDocumentInternal( store, e );
00191 }
00192 
00193 bool KoDocumentChild::loadDocumentInternal( KoStore* _store, const KoDocumentEntry& e, bool doOpenURL )
00194 {
00195     kdDebug(30003) << "KoDocumentChild::loadDocumentInternal doOpenURL=" << doOpenURL << " m_tmpURL=" << m_tmpURL << endl;
00196     KoDocument * doc = e.createDoc( d->m_parent );
00197     if (!doc) {
00198         kdWarning(30003) << "createDoc failed" << endl;
00199         return false;
00200     }
00201     setDocument( doc, m_tmpGeometry );
00202 
00203     bool res = true;
00204     if ( doOpenURL )
00205     {
00206         bool internalURL = false;
00207         if ( m_tmpURL.startsWith( STORE_PROTOCOL ) || KURL::isRelativeURL( m_tmpURL ) )
00208         {
00209             res = document()->loadFromStore( _store, m_tmpURL );
00210             internalURL = true;
00211             document()->setStoreInternal( true );
00212         }
00213         else
00214         {
00215             // Reference to an external document. Hmmm...
00216             document()->setStoreInternal( false );
00217             KURL url( m_tmpURL );
00218             if ( !url.isLocalFile() )
00219             {
00220                 QApplication::restoreOverrideCursor();
00221                 // For security reasons we need to ask confirmation if the url is remote
00222                 int result = KMessageBox::warningYesNoCancel(
00223                     0, i18n( "This document contains an external link to a remote document\n%1").arg(m_tmpURL),
00224                     i18n( "Confirmation required" ), i18n( "Download" ), i18n( "Skip" ) );
00225 
00226                 if ( result == KMessageBox::Cancel )
00227                 {
00228                     d->m_parent->setErrorMessage("USER_CANCELED");
00229                     return false;
00230                 }
00231                 if ( result == KMessageBox::Yes )
00232                     res = document()->openURL( url );
00233                 // and if == No, res will still be false so we'll use a kounavail below
00234             }
00235             else
00236                 res = document()->openURL( url );
00237         }
00238         if ( !res )
00239         {
00240             delete d->m_doc;
00241             d->m_doc = 0;
00242             QString tmpURL = m_tmpURL; // keep a copy, createUnavailDocument will erase it
00243             // Not found -> use a kounavail instead
00244             res = createUnavailDocument( _store, false /* the URL doesn't exist, don't try to open it */ );
00245             if ( res )
00246             {
00247                 d->m_doc->setProperty( "realURL", tmpURL ); // so that it gets saved correctly
00248                 d->m_doc->setStoreInternal( true );
00249                 if ( internalURL )
00250                     d->m_doc->setProperty( "unavailReason", i18n( "Couldn't load embedded object." ) );
00251                 else
00252                     d->m_doc->setProperty( "unavailReason", i18n( "External document not found:\n%1" ).arg( tmpURL ) );
00253             }
00254             return res;
00255         }
00256         // Still waiting...
00257         QApplication::setOverrideCursor( waitCursor );
00258     }
00259 
00260     m_tmpURL = QString::null;
00261 
00262     // see KoDocument::insertChild for an explanation what's going on
00263     // now :-)
00264     if ( parentDocument() )
00265     {
00266         KoDocument *parent = parentDocument();
00267 
00268         if ( parent->manager() && parent->manager()->parts() )
00269         {
00270             KParts::PartManager *manager = parent->manager();
00271 
00272             if ( !manager->parts()->containsRef( document() ) &&
00273                  !parent->isSingleViewMode() )
00274                 manager->addPart( document(), false );
00275         }
00276     }
00277 
00278     QApplication::restoreOverrideCursor();
00279 
00280     return res;
00281 }
00282 
00283 bool KoDocumentChild::createUnavailDocument( KoStore* store, bool doOpenURL )
00284 {
00285     // We don't need a trader query here. We're looking for a very specific component.
00286     KService::Ptr serv = KService::serviceByDesktopName( "kounavail" );
00287     if ( serv == 0L )
00288     {
00289         kdWarning(30003) << "ERROR: service kounavail not found " << endl;
00290         return false;
00291     }
00292     KoDocumentEntry e( serv );
00293     if ( !loadDocumentInternal( store, e, doOpenURL ) )
00294         return false;
00295     d->m_doc->setProperty( "mimetype", m_tmpMimeType );
00296     return true;
00297 }
00298 
00299 QDomElement KoDocumentChild::save( QDomDocument& doc, bool uppercase )
00300 {
00301     if( document() )
00302     {
00303         QDomElement e = doc.createElement( ( uppercase ? "OBJECT" : "object" ) );
00304         if ( document()->url().protocol() != INTERNAL_PROTOCOL ) {
00305             e.setAttribute( "url", document()->url().url() );
00306             kdDebug() << "KoDocumentChild::save url=" << document()->url().url() << endl;
00307         }
00308         else {
00309             e.setAttribute( "url", document()->url().path().mid( 1 ) );
00310             kdDebug() << "KoDocumentChild::save url=" << document()->url().path().mid( 1 ) << endl;
00311         }
00312         e.setAttribute( "mime", document()->nativeFormatMimeType() );
00313         kdDebug() << "KoDocumentChild::save mime=" << document()->nativeFormatMimeType() << endl;
00314         QDomElement rect = doc.createElement( ( uppercase ? "RECT" : "rect" ) );
00315         rect.setAttribute( "x", geometry().left() );
00316         rect.setAttribute( "y", geometry().top() );
00317         rect.setAttribute( "w", geometry().width() );
00318         rect.setAttribute( "h", geometry().height() );
00319         e.appendChild(rect);
00320         return e;
00321     }
00322     return QDomElement();
00323 }
00324 
00325 bool KoDocumentChild::isStoredExtern()
00326 {
00327     return document()->isStoredExtern();
00328 }
00329 
00330 KURL KoDocumentChild::url()
00331 {
00332     return ( document() ? document()->url() : KURL() );
00333 }
00334 
00335 KoDocumentChild::~KoDocumentChild()
00336 {
00337   if ( d->m_doc ) {
00338     delete d->m_doc;
00339     d->m_doc=0L;
00340   }
00341   delete d;
00342 }
00343 
00344 bool KoDocumentChild::isDeleted() const
00345 {
00346     return d->m_deleted;
00347 }
00348 
00349 void KoDocumentChild::setDeleted( bool on )
00350 {
00351     d->m_deleted = on;
00352 }
00353 
00354 #include <koDocumentChild.moc>
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Mar 11 11:47:41 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003