00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "part.h"
00022 #include "event.h"
00023 #include "plugin.h"
00024 #include "mainwindow.h"
00025 #include "partmanager.h"
00026 #include "browserextension.h"
00027
00028 #include <QtGui/QApplication>
00029 #include <QtCore/QFile>
00030 #include <QtCore/QFileInfo>
00031 #include <QtGui/QPainter>
00032 #include <QtCore/QPoint>
00033 #include <QtCore/QTextStream>
00034
00035 #include <kdirnotify.h>
00036 #include <kfiledialog.h>
00037 #include <kcomponentdata.h>
00038 #include <kio/job.h>
00039 #include <kio/jobuidelegate.h>
00040 #include <klocale.h>
00041 #include <kmessagebox.h>
00042 #include <kstandarddirs.h>
00043 #include <ktemporaryfile.h>
00044 #include <kxmlguifactory.h>
00045
00046 #include <stdio.h>
00047 #include <unistd.h>
00048 #include <assert.h>
00049 #include <kdebug.h>
00050 #include <kiconloader.h>
00051
00052 using namespace KParts;
00053
00054 namespace KParts
00055 {
00056
00057 class PartBasePrivate
00058 {
00059 public:
00060 Q_DECLARE_PUBLIC(PartBase)
00061
00062 PartBasePrivate(PartBase *q): q_ptr(q)
00063 {
00064 m_pluginLoadingMode = PartBase::LoadPlugins;
00065 m_pluginInterfaceVersion = 0;
00066 m_obj = 0;
00067 }
00068
00069 virtual ~PartBasePrivate()
00070 {
00071 }
00072
00073 PartBase *q_ptr;
00074 PartBase::PluginLoadingMode m_pluginLoadingMode;
00075 int m_pluginInterfaceVersion;
00076 QObject *m_obj;
00077 };
00078
00079 class PartPrivate: public PartBasePrivate
00080 {
00081 public:
00082 Q_DECLARE_PUBLIC(Part)
00083
00084 PartPrivate(Part *q)
00085 : PartBasePrivate(q),
00086 m_iconLoader(0),
00087 m_bSelectable(true),
00088 m_autoDeleteWidget(true),
00089 m_autoDeletePart(true),
00090 m_manager(0)
00091 {
00092 }
00093
00094 ~PartPrivate()
00095 {
00096 }
00097
00098 KIconLoader* m_iconLoader;
00099 bool m_bSelectable;
00100 bool m_autoDeleteWidget;
00101 bool m_autoDeletePart;
00102 PartManager * m_manager;
00103 QPointer<QWidget> m_widget;
00104 };
00105
00106 }
00107
00108 PartBase::PartBase()
00109 : d_ptr(new PartBasePrivate(this))
00110 {
00111 }
00112
00113 PartBase::PartBase(PartBasePrivate &dd)
00114 : d_ptr(&dd)
00115 {
00116 }
00117
00118 PartBase::~PartBase()
00119 {
00120 delete d_ptr;
00121 }
00122
00123 void PartBase::setPartObject( QObject *obj )
00124 {
00125 Q_D(PartBase);
00126
00127 d->m_obj = obj;
00128 }
00129
00130 QObject *PartBase::partObject() const
00131 {
00132 Q_D(const PartBase);
00133
00134 return d->m_obj;
00135 }
00136
00137 void PartBase::setComponentData(const KComponentData &componentData)
00138 {
00139 setComponentData(componentData, true);
00140 }
00141
00142 void PartBase::setComponentData(const KComponentData &componentData, bool bLoadPlugins)
00143 {
00144 Q_D(PartBase);
00145
00146 KXMLGUIClient::setComponentData(componentData);
00147 KGlobal::locale()->insertCatalog(componentData.catalogName());
00148
00149 KGlobal::dirs()->addResourceType((componentData.componentName() + "data").toUtf8(),
00150 "data", componentData.componentName());
00151 if (bLoadPlugins) {
00152 loadPlugins(d->m_obj, this, componentData);
00153 }
00154 }
00155
00156 void PartBase::loadPlugins(QObject *parent, KXMLGUIClient *parentGUIClient, const KComponentData &instance)
00157 {
00158 Q_D(PartBase);
00159
00160 if( d->m_pluginLoadingMode != DoNotLoadPlugins )
00161 Plugin::loadPlugins( parent, parentGUIClient, instance, d->m_pluginLoadingMode == LoadPlugins, d->m_pluginInterfaceVersion );
00162 }
00163
00164 void PartBase::setPluginLoadingMode( PluginLoadingMode loadingMode )
00165 {
00166 Q_D(PartBase);
00167
00168 d->m_pluginLoadingMode = loadingMode;
00169 }
00170
00171 void KParts::PartBase::setPluginInterfaceVersion( int version )
00172 {
00173 Q_D(PartBase);
00174
00175 d->m_pluginInterfaceVersion = version;
00176 }
00177
00178 Part::Part( QObject *parent )
00179 : QObject( parent ), PartBase( *new PartPrivate(this) )
00180 {
00181 PartBase::setPartObject( this );
00182 }
00183
00184 Part::Part(PartPrivate &dd, QObject *parent)
00185 : QObject( parent ), PartBase( dd )
00186 {
00187 PartBase::setPartObject( this );
00188 }
00189
00190 Part::~Part()
00191 {
00192 Q_D(Part);
00193
00194
00195
00196 if ( d->m_widget )
00197 {
00198
00199 disconnect( d->m_widget, SIGNAL( destroyed() ),
00200 this, SLOT( slotWidgetDestroyed() ) );
00201 }
00202
00203 if ( d->m_manager )
00204 d->m_manager->removePart(this);
00205
00206 if ( d->m_widget && d->m_autoDeleteWidget )
00207 {
00208 kDebug(1000) << "deleting widget " << d->m_widget << " " << d->m_widget->objectName();
00209 delete static_cast<QWidget*>(d->m_widget);
00210 }
00211
00212 delete d->m_iconLoader;
00213 }
00214
00215 void Part::embed( QWidget * parentWidget )
00216 {
00217 if ( widget() )
00218 {
00219 widget()->setParent( parentWidget, 0 );
00220 widget()->setGeometry( 0, 0, widget()->width(), widget()->height() );
00221 widget()->show();
00222 }
00223 }
00224
00225 QWidget *Part::widget()
00226 {
00227 Q_D(Part);
00228
00229 return d->m_widget;
00230 }
00231
00232 void Part::setAutoDeleteWidget(bool autoDeleteWidget)
00233 {
00234 Q_D(Part);
00235 d->m_autoDeleteWidget = autoDeleteWidget;
00236 }
00237
00238 void Part::setAutoDeletePart(bool autoDeletePart)
00239 {
00240 Q_D(Part);
00241 d->m_autoDeletePart = autoDeletePart;
00242 }
00243
00244
00245
00246 KIconLoader* Part::iconLoader()
00247 {
00248 Q_D(Part);
00249
00250 if (!d->m_iconLoader) {
00251 Q_ASSERT(componentData().isValid());
00252 d->m_iconLoader = new KIconLoader( componentData() );
00253 }
00254 return d->m_iconLoader;
00255 }
00256
00257 void Part::setManager( PartManager *manager )
00258 {
00259 Q_D(Part);
00260
00261 d->m_manager = manager;
00262 }
00263
00264 PartManager *Part::manager() const
00265 {
00266 Q_D(const Part);
00267
00268 return d->m_manager;
00269 }
00270
00271 Part *Part::hitTest( QWidget *widget, const QPoint & )
00272 {
00273 Q_D(Part);
00274
00275 if ( (QWidget *)d->m_widget != widget )
00276 return 0;
00277
00278 return this;
00279 }
00280
00281 void Part::setWidget( QWidget *widget )
00282 {
00283 Q_D(Part);
00284
00285 assert ( !d->m_widget );
00286 d->m_widget = widget;
00287 connect( d->m_widget, SIGNAL( destroyed() ),
00288 this, SLOT( slotWidgetDestroyed() ) );
00289 }
00290
00291 void Part::setSelectable( bool selectable )
00292 {
00293 Q_D(Part);
00294
00295 d->m_bSelectable = selectable;
00296 }
00297
00298 bool Part::isSelectable() const
00299 {
00300 Q_D(const Part);
00301
00302 return d->m_bSelectable;
00303 }
00304
00305 void Part::customEvent( QEvent *ev )
00306 {
00307 if ( PartActivateEvent::test( ev ) )
00308 {
00309 partActivateEvent( static_cast<PartActivateEvent *>(ev) );
00310 return;
00311 }
00312
00313 if ( PartSelectEvent::test( ev ) )
00314 {
00315 partSelectEvent( static_cast<PartSelectEvent *>(ev) );
00316 return;
00317 }
00318
00319 if ( GUIActivateEvent::test( ev ) )
00320 {
00321 guiActivateEvent( static_cast<GUIActivateEvent *>(ev) );
00322 return;
00323 }
00324
00325 QObject::customEvent( ev );
00326 }
00327
00328 void Part::partActivateEvent( PartActivateEvent * )
00329 {
00330 }
00331
00332 void Part::partSelectEvent( PartSelectEvent * )
00333 {
00334 }
00335
00336 void Part::guiActivateEvent( GUIActivateEvent * )
00337 {
00338 }
00339
00340 QWidget *Part::hostContainer( const QString &containerName )
00341 {
00342 if ( !factory() )
00343 return 0;
00344
00345 return factory()->container( containerName, this );
00346 }
00347
00348 void Part::slotWidgetDestroyed()
00349 {
00350 Q_D(Part);
00351
00352 d->m_widget = 0;
00353 if (d->m_autoDeletePart) {
00354 kDebug(1000) << "KPart::slotWidgetDestroyed(), deleting part " << objectName();
00355 delete this;
00356 }
00357 }
00358
00359 void Part::loadPlugins()
00360 {
00361 PartBase::loadPlugins(this, this, componentData());
00362 }
00363
00365
00366 namespace KParts
00367 {
00368
00369 class ReadOnlyPartPrivate: public PartPrivate
00370 {
00371 public:
00372 Q_DECLARE_PUBLIC(ReadOnlyPart)
00373
00374 ReadOnlyPartPrivate(ReadOnlyPart *q): PartPrivate(q)
00375 {
00376 m_job = 0;
00377 m_uploadJob = 0;
00378 m_showProgressInfo = true;
00379 m_saveOk = false;
00380 m_waitForSave = false;
00381 m_duringSaveAs = false;
00382 m_bTemp = false;
00383 m_bAutoDetectedMime = false;
00384 }
00385
00386 ~ReadOnlyPartPrivate()
00387 {
00388 }
00389
00390 void _k_slotJobFinished( KJob * job );
00391 void _k_slotGotMimeType(KIO::Job *job, const QString &mime);
00392
00393 KIO::FileCopyJob * m_job;
00394 KIO::FileCopyJob * m_uploadJob;
00395 KUrl m_originalURL;
00396 QString m_originalFilePath;
00397 bool m_showProgressInfo : 1;
00398 bool m_saveOk : 1;
00399 bool m_waitForSave : 1;
00400 bool m_duringSaveAs : 1;
00401
00405 bool m_bTemp: 1;
00406
00407
00408 bool m_bAutoDetectedMime : 1;
00409
00413 KUrl m_url;
00414
00418 QString m_file;
00419
00420 OpenUrlArguments m_arguments;
00421 };
00422
00423 class ReadWritePartPrivate: public ReadOnlyPartPrivate
00424 {
00425 public:
00426 Q_DECLARE_PUBLIC(ReadWritePart)
00427
00428 ReadWritePartPrivate(ReadWritePart *q): ReadOnlyPartPrivate(q)
00429 {
00430 m_bModified = false;
00431 m_bReadWrite = true;
00432 m_bClosing = false;
00433 }
00434
00435 void _k_slotUploadFinished( KJob * job );
00436
00437 void prepareSaving();
00438
00439 bool m_bModified;
00440 bool m_bReadWrite;
00441 bool m_bClosing;
00442 QEventLoop m_eventLoop;
00443 };
00444
00445 }
00446
00447 ReadOnlyPart::ReadOnlyPart( QObject *parent )
00448 : Part( *new ReadOnlyPartPrivate(this), parent )
00449 {
00450 }
00451
00452 ReadOnlyPart::ReadOnlyPart( ReadOnlyPartPrivate &dd, QObject *parent )
00453 : Part( dd, parent )
00454 {
00455 }
00456
00457 ReadOnlyPart::~ReadOnlyPart()
00458 {
00459 ReadOnlyPart::closeUrl();
00460 }
00461
00462 KUrl ReadOnlyPart::url() const
00463 {
00464 Q_D(const ReadOnlyPart);
00465
00466 return d->m_url;
00467 }
00468
00469 void ReadOnlyPart::setUrl(const KUrl &url)
00470 {
00471 Q_D(ReadOnlyPart);
00472
00473 d->m_url = url;
00474 }
00475
00476 QString ReadOnlyPart::localFilePath() const
00477 {
00478 Q_D(const ReadOnlyPart);
00479
00480 return d->m_file;
00481 }
00482
00483 void ReadOnlyPart::setLocalFilePath( const QString &localFilePath )
00484 {
00485 Q_D(ReadOnlyPart);
00486
00487 d->m_file = localFilePath;
00488 }
00489
00490 bool ReadOnlyPart::isLocalFileTemporary() const
00491 {
00492 Q_D(const ReadOnlyPart);
00493
00494 return d->m_bTemp;
00495 }
00496
00497 void ReadOnlyPart::setLocalFileTemporary( bool temp )
00498 {
00499 Q_D(ReadOnlyPart);
00500
00501 d->m_bTemp = temp;
00502 }
00503
00504 void ReadOnlyPart::setProgressInfoEnabled( bool show )
00505 {
00506 Q_D(ReadOnlyPart);
00507
00508 d->m_showProgressInfo = show;
00509 }
00510
00511 bool ReadOnlyPart::isProgressInfoEnabled() const
00512 {
00513 Q_D(const ReadOnlyPart);
00514
00515 return d->m_showProgressInfo;
00516 }
00517
00518 #ifndef KDE_NO_COMPAT
00519 void ReadOnlyPart::showProgressInfo( bool show )
00520 {
00521 Q_D(ReadOnlyPart);
00522
00523 d->m_showProgressInfo = show;
00524 }
00525 #endif
00526
00527 bool ReadOnlyPart::openUrl( const KUrl &url )
00528 {
00529 Q_D(ReadOnlyPart);
00530
00531 if ( !url.isValid() )
00532 return false;
00533 if (d->m_bAutoDetectedMime) {
00534 d->m_arguments.setMimeType(QString());
00535 d->m_bAutoDetectedMime = false;
00536 }
00537 OpenUrlArguments args = d->m_arguments;
00538 if ( !closeUrl() )
00539 return false;
00540 d->m_arguments = args;
00541 d->m_url = url;
00542 if ( d->m_url.isLocalFile() )
00543 {
00544 emit started( 0 );
00545 d->m_file = d->m_url.toLocalFile();
00546
00547 if (d->m_arguments.mimeType().isEmpty())
00548 {
00549
00550
00551 KMimeType::Ptr mime = KMimeType::findByUrl(d->m_url, 0, true );
00552 if (mime) {
00553 d->m_arguments.setMimeType(mime->name());
00554 d->m_bAutoDetectedMime = true;
00555 }
00556 }
00557 bool ret = openFile();
00558 if (ret) {
00559 emit setWindowCaption( d->m_url.prettyUrl() );
00560 emit completed();
00561 } else emit canceled(QString());
00562 return ret;
00563 }
00564 else
00565 {
00566 d->m_bTemp = true;
00567
00568 QString fileName = url.fileName();
00569 QFileInfo fileInfo(fileName);
00570 QString ext = fileInfo.completeSuffix();
00571 QString extension;
00572 if ( !ext.isEmpty() && url.query().isNull() )
00573 extension = '.'+ext;
00574 KTemporaryFile tempFile;
00575 tempFile.setSuffix(extension);
00576 tempFile.setAutoRemove(false);
00577 tempFile.open();
00578 d->m_file = tempFile.fileName();
00579
00580 KUrl destURL;
00581 destURL.setPath( d->m_file );
00582 KIO::JobFlags flags = d->m_showProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo;
00583 flags |= KIO::Overwrite;
00584 d->m_job = KIO::file_copy( d->m_url, destURL, 0600, flags );
00585 d->m_job->ui()->setWindow( widget() ? widget()->topLevelWidget() : 0 );
00586 emit started( d->m_job );
00587 connect( d->m_job, SIGNAL( result( KJob * ) ), this, SLOT( _k_slotJobFinished ( KJob * ) ) );
00588 connect(d->m_job, SIGNAL(mimetype(KIO::Job *, const QString &)),
00589 this, SLOT(_k_slotGotMimeType(KIO::Job *, const QString&)));
00590 return true;
00591 }
00592 }
00593
00594 void ReadOnlyPart::abortLoad()
00595 {
00596 Q_D(ReadOnlyPart);
00597
00598 if ( d->m_job )
00599 {
00600
00601 d->m_job->kill();
00602 d->m_job = 0;
00603 }
00604 }
00605
00606 bool ReadOnlyPart::closeUrl()
00607 {
00608 Q_D(ReadOnlyPart);
00609
00610 abortLoad();
00611
00612 d->m_arguments = KParts::OpenUrlArguments();
00613
00614 if ( d->m_bTemp )
00615 {
00616 unlink( QFile::encodeName(d->m_file) );
00617 d->m_bTemp = false;
00618 }
00619
00620
00621
00622 return true;
00623 }
00624
00625 void ReadOnlyPartPrivate::_k_slotJobFinished( KJob * job )
00626 {
00627 Q_Q(ReadOnlyPart);
00628
00629 kDebug(1000) << "ReadOnlyPart::slotJobFinished";
00630 assert( job == m_job );
00631 m_job = 0;
00632 if (job->error())
00633 emit q->canceled( job->errorString() );
00634 else
00635 {
00636 if ( q->openFile() ) {
00637 emit q->setWindowCaption( m_url.prettyUrl() );
00638 emit q->completed();
00639 } else emit q->canceled(QString());
00640 }
00641 }
00642
00643 void ReadOnlyPartPrivate::_k_slotGotMimeType(KIO::Job *job, const QString &mime)
00644 {
00645 kDebug(1000) << "ReadOnlyPart::slotJobFinished:" << mime;
00646 Q_ASSERT(job == m_job);
00647
00648 if (m_arguments.mimeType().isEmpty()) {
00649 m_arguments.setMimeType(mime);
00650 m_bAutoDetectedMime = true;
00651 }
00652 }
00653
00654 void ReadOnlyPart::guiActivateEvent( GUIActivateEvent * event )
00655 {
00656 Q_D(ReadOnlyPart);
00657
00658 if (event->activated())
00659 {
00660 if (!d->m_url.isEmpty())
00661 {
00662 kDebug(1000) << "ReadOnlyPart::guiActivateEvent -> " << d->m_url.prettyUrl();
00663 emit setWindowCaption( d->m_url.prettyUrl() );
00664 } else emit setWindowCaption( "" );
00665 }
00666 }
00667
00668 bool ReadOnlyPart::openStream( const QString& mimeType, const KUrl& url )
00669 {
00670 Q_D(ReadOnlyPart);
00671
00672 OpenUrlArguments args = d->m_arguments;
00673 if ( !closeUrl() )
00674 return false;
00675 d->m_arguments = args;
00676 d->m_url = url;
00677 return doOpenStream( mimeType );
00678 }
00679
00680 bool ReadOnlyPart::writeStream( const QByteArray& data )
00681 {
00682 return doWriteStream( data );
00683 }
00684
00685 bool ReadOnlyPart::closeStream()
00686 {
00687 return doCloseStream();
00688 }
00689
00690 BrowserExtension* ReadOnlyPart::browserExtension() const
00691 {
00692 return findChild<KParts::BrowserExtension *>();
00693 }
00694
00695 void KParts::ReadOnlyPart::setArguments(const OpenUrlArguments& arguments)
00696 {
00697 Q_D(ReadOnlyPart);
00698 d->m_arguments = arguments;
00699 d->m_bAutoDetectedMime = arguments.mimeType().isEmpty();
00700 }
00701
00702 OpenUrlArguments KParts::ReadOnlyPart::arguments() const
00703 {
00704 Q_D(const ReadOnlyPart);
00705 return d->m_arguments;
00706 }
00707
00709
00710
00711 ReadWritePart::ReadWritePart( QObject *parent )
00712 : ReadOnlyPart( *new ReadWritePartPrivate(this), parent )
00713 {
00714 }
00715
00716 ReadWritePart::~ReadWritePart()
00717 {
00718
00719
00720
00721
00722 }
00723
00724 void ReadWritePart::setReadWrite( bool readwrite )
00725 {
00726 Q_D(ReadWritePart);
00727
00728
00729 d->m_bReadWrite = readwrite;
00730 }
00731
00732 void ReadWritePart::setModified( bool modified )
00733 {
00734 Q_D(ReadWritePart);
00735
00736 kDebug(1000) << "ReadWritePart::setModified( " << (modified ? "true" : "false") << ")";
00737 if ( !d->m_bReadWrite && modified )
00738 {
00739 kError(1000) << "Can't set a read-only document to 'modified' !" << endl;
00740 return;
00741 }
00742 d->m_bModified = modified;
00743 }
00744
00745 void ReadWritePart::setModified()
00746 {
00747 setModified( true );
00748 }
00749
00750 bool ReadWritePart::queryClose()
00751 {
00752 Q_D(ReadWritePart);
00753
00754 if ( !isReadWrite() || !isModified() )
00755 return true;
00756
00757 QString docName = url().fileName();
00758 if (docName.isEmpty()) docName = i18n( "Untitled" );
00759
00760 QWidget *parentWidget=widget();
00761 if(!parentWidget) parentWidget=QApplication::activeWindow();
00762
00763 int res = KMessageBox::warningYesNoCancel( parentWidget,
00764 i18n( "The document \"%1\" has been modified.\n"
00765 "Do you want to save your changes or discard them?" , docName ),
00766 i18n( "Close Document" ), KStandardGuiItem::save(), KStandardGuiItem::discard() );
00767
00768 bool abortClose=false;
00769 bool handled=false;
00770
00771 switch(res) {
00772 case KMessageBox::Yes :
00773 sigQueryClose(&handled,&abortClose);
00774 if (!handled)
00775 {
00776 if (d->m_url.isEmpty())
00777 {
00778 KUrl url = KFileDialog::getSaveUrl(KUrl(), QString(), parentWidget);
00779 if (url.isEmpty())
00780 return false;
00781
00782 saveAs( url );
00783 }
00784 else
00785 {
00786 save();
00787 }
00788 } else if (abortClose) return false;
00789 return waitSaveComplete();
00790 case KMessageBox::No :
00791 return true;
00792 default :
00793 return false;
00794 }
00795 }
00796
00797 bool ReadWritePart::closeUrl()
00798 {
00799 abortLoad();
00800 if ( isReadWrite() && isModified() )
00801 {
00802 if (!queryClose())
00803 return false;
00804 }
00805
00806 return ReadOnlyPart::closeUrl();
00807 }
00808
00809 bool ReadWritePart::closeUrl( bool promptToSave )
00810 {
00811 return promptToSave ? closeUrl() : ReadOnlyPart::closeUrl();
00812 }
00813
00814 bool ReadWritePart::save()
00815 {
00816 Q_D(ReadWritePart);
00817
00818 d->m_saveOk = false;
00819 if ( d->m_file.isEmpty() )
00820 d->prepareSaving();
00821 if( saveFile() )
00822 return saveToUrl();
00823 else
00824 emit canceled(QString());
00825 return false;
00826 }
00827
00828 bool ReadWritePart::saveAs( const KUrl & kurl )
00829 {
00830 Q_D(ReadWritePart);
00831
00832 if (!kurl.isValid())
00833 {
00834 kError(1000) << "saveAs: Malformed URL " << kurl.url() << endl;
00835 return false;
00836 }
00837 d->m_duringSaveAs = true;
00838 d->m_originalURL = d->m_url;
00839 d->m_originalFilePath = d->m_file;
00840 d->m_url = kurl;
00841 d->prepareSaving();
00842 bool result = save();
00843 if (result) {
00844 emit setWindowCaption( d->m_url.prettyUrl() );
00845 } else {
00846 d->m_url = d->m_originalURL;
00847 d->m_file = d->m_originalFilePath;
00848 d->m_duringSaveAs = false;
00849 d->m_originalURL = KUrl();
00850 d->m_originalFilePath.clear();
00851 }
00852
00853 return result;
00854 }
00855
00856
00857 void ReadWritePartPrivate::prepareSaving()
00858 {
00859
00860 if ( m_url.isLocalFile() )
00861 {
00862 if ( m_bTemp )
00863 {
00864 unlink( QFile::encodeName(m_file) );
00865 m_bTemp = false;
00866 }
00867 m_file = m_url.path();
00868 }
00869 else
00870 {
00871
00872 if ( m_file.isEmpty() || !m_bTemp )
00873 {
00874 KTemporaryFile tempFile;
00875 tempFile.setAutoRemove(false);
00876 tempFile.open();
00877 m_file = tempFile.fileName();
00878 m_bTemp = true;
00879 }
00880
00881 }
00882 }
00883
00884 bool ReadWritePart::saveToUrl()
00885 {
00886 Q_D(ReadWritePart);
00887
00888 if ( d->m_url.isLocalFile() )
00889 {
00890 setModified( false );
00891 emit completed();
00892
00893 assert( !d->m_bTemp );
00894 d->m_saveOk = true;
00895 d->m_duringSaveAs = false;
00896 d->m_originalURL = KUrl();
00897 d->m_originalFilePath.clear();
00898 return true;
00899 }
00900 else
00901 {
00902 if (d->m_uploadJob)
00903 {
00904 unlink(QFile::encodeName(d->m_uploadJob->srcUrl().path()));
00905 d->m_uploadJob->kill();
00906 d->m_uploadJob = 0;
00907 }
00908 KTemporaryFile *tempFile = new KTemporaryFile();
00909 tempFile->open();
00910 QString uploadFile = tempFile->fileName();
00911 delete tempFile;
00912 KUrl uploadUrl;
00913 uploadUrl.setPath( uploadFile );
00914
00915 if (::link(QFile::encodeName(d->m_file), QFile::encodeName(uploadFile)) != 0)
00916 {
00917
00918 return false;
00919 }
00920 d->m_uploadJob = KIO::file_move( uploadUrl, d->m_url, -1, KIO::Overwrite );
00921 d->m_uploadJob->ui()->setWindow( widget() ? widget()->topLevelWidget() : 0 );
00922 connect( d->m_uploadJob, SIGNAL( result( KJob * ) ), this, SLOT( _k_slotUploadFinished (KJob *) ) );
00923 return true;
00924 }
00925 }
00926
00927 void ReadWritePartPrivate::_k_slotUploadFinished( KJob * )
00928 {
00929 Q_Q(ReadWritePart);
00930
00931 if (m_uploadJob->error())
00932 {
00933 unlink(QFile::encodeName(m_uploadJob->srcUrl().path()));
00934 QString error = m_uploadJob->errorString();
00935 m_uploadJob = 0;
00936 if (m_duringSaveAs) {
00937 m_url = m_originalURL;
00938 m_file = m_originalFilePath;
00939 }
00940 emit q->canceled( error );
00941 }
00942 else
00943 {
00944 KUrl dirUrl( m_url );
00945 dirUrl.setPath( dirUrl.directory() );
00946 ::org::kde::KDirNotify::emitFilesAdded( dirUrl.url() );
00947
00948 m_uploadJob = 0;
00949 q->setModified( false );
00950 emit q->completed();
00951 m_saveOk = true;
00952 }
00953 m_duringSaveAs = false;
00954 m_originalURL = KUrl();
00955 m_originalFilePath.clear();
00956 if (m_waitForSave) {
00957 m_eventLoop.quit();
00958 }
00959 }
00960
00961 bool ReadWritePart::isReadWrite() const
00962 {
00963 Q_D(const ReadWritePart);
00964
00965 return d->m_bReadWrite;
00966 }
00967
00968 bool ReadWritePart::isModified() const
00969 {
00970 Q_D(const ReadWritePart);
00971
00972 return d->m_bModified;
00973 }
00974
00975 bool ReadWritePart::waitSaveComplete()
00976 {
00977 Q_D(ReadWritePart);
00978
00979 if (!d->m_uploadJob)
00980 return d->m_saveOk;
00981
00982 d->m_waitForSave = true;
00983
00984 d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
00985
00986 d->m_waitForSave = false;
00987
00988 return d->m_saveOk;
00989 }
00990
00992
00993 class KParts::OpenUrlArgumentsPrivate : public QSharedData
00994 {
00995 public:
00996 OpenUrlArgumentsPrivate()
00997 : reload(false),
00998 actionRequestedByUser(true),
00999 xOffset(0),
01000 yOffset(0),
01001 mimeType(),
01002 metaData()
01003 {}
01004 bool reload;
01005 bool actionRequestedByUser;
01006 int xOffset;
01007 int yOffset;
01008 QString mimeType;
01009 QMap<QString, QString> metaData;
01010 };
01011
01012 KParts::OpenUrlArguments::OpenUrlArguments()
01013 : d(new OpenUrlArgumentsPrivate)
01014 {
01015 }
01016
01017 KParts::OpenUrlArguments::OpenUrlArguments(const OpenUrlArguments &other)
01018 : d(other.d)
01019 {
01020 }
01021
01022 KParts::OpenUrlArguments & KParts::OpenUrlArguments::operator=( const OpenUrlArguments &other)
01023 {
01024 d = other.d;
01025 return *this;
01026 }
01027
01028 KParts::OpenUrlArguments::~OpenUrlArguments()
01029 {
01030 }
01031
01032 bool KParts::OpenUrlArguments::reload() const
01033 {
01034 return d->reload;
01035 }
01036
01037 void KParts::OpenUrlArguments::setReload(bool b)
01038 {
01039 d->reload = b;
01040 }
01041
01042 int KParts::OpenUrlArguments::xOffset() const
01043 {
01044 return d->xOffset;
01045 }
01046
01047 void KParts::OpenUrlArguments::setXOffset(int x)
01048 {
01049 d->xOffset = x;
01050 }
01051
01052 int KParts::OpenUrlArguments::yOffset() const
01053 {
01054 return d->yOffset;
01055 }
01056
01057 void KParts::OpenUrlArguments::setYOffset(int y)
01058 {
01059 d->yOffset = y;
01060 }
01061
01062 QString KParts::OpenUrlArguments::mimeType() const
01063 {
01064 return d->mimeType;
01065 }
01066
01067 void KParts::OpenUrlArguments::setMimeType(const QString& mime)
01068 {
01069 d->mimeType = mime;
01070 }
01071
01072 QMap<QString, QString> & KParts::OpenUrlArguments::metaData()
01073 {
01074 return d->metaData;
01075 }
01076
01077 const QMap<QString, QString> & KParts::OpenUrlArguments::metaData() const
01078 {
01079 return d->metaData;
01080 }
01081
01082 bool KParts::OpenUrlArguments::actionRequestedByUser() const
01083 {
01084 return d->actionRequestedByUser;
01085 }
01086
01087 void KParts::OpenUrlArguments::setActionRequestedByUser(bool userRequested)
01088 {
01089 d->actionRequestedByUser = userRequested;
01090 }
01091
01092 #include "part.moc"