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