00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "katemwmodonhddialog.h"
00021 #include "katemwmodonhddialog.moc"
00022
00023 #include "katedocmanager.h"
00024
00025 #include <kate/document.h>
00026
00027 #include <kiconloader.h>
00028 #include <klistview.h>
00029 #include <klocale.h>
00030 #include <kmessagebox.h>
00031 #include <kprocio.h>
00032 #include <krun.h>
00033 #include <ktempfile.h>
00034 #include <kpushbutton.h>
00035
00036 #include <qlabel.h>
00037 #include <qlistview.h>
00038 #include <qlayout.h>
00039 #include <qpushbutton.h>
00040 #include <qwhatsthis.h>
00041 #include <qvbox.h>
00042
00043 class KateDocItem : public QCheckListItem
00044 {
00045 public:
00046 KateDocItem( Kate::Document *doc, const QString &status, KListView *lv )
00047 : QCheckListItem( lv, doc->url().prettyURL(), CheckBox ),
00048 document( doc )
00049 {
00050 setText( 1, status );
00051 if ( ! doc->isModified() )
00052 setOn( On );
00053 }
00054 ~KateDocItem() {};
00055
00056 Kate::Document *document;
00057 };
00058
00059
00060 KateMwModOnHdDialog::KateMwModOnHdDialog( DocVector docs, QWidget *parent, const char *name )
00061 : KDialogBase( parent, name, true, i18n("Documents Modified on Disk"),
00062 User1|User2|User3, User3, false,
00063 KGuiItem (i18n("&Ignore"), "fileclose"),
00064 KGuiItem (i18n("&Overwrite"), "filesave"),
00065 KGuiItem (i18n("&Reload"), "reload") )
00066 {
00067 setButtonWhatsThis( User1, i18n(
00068 "Removes the modified flag from the selected documents and closes the "
00069 "dialog if there are no more unhandled documents.") );
00070 setButtonWhatsThis( User2, i18n(
00071 "Overwrite selected documents, discarding the disk changes and closes the "
00072 "dialog if there are no more unhandled documents.") );
00073 setButtonWhatsThis( User3, i18n(
00074 "Reloads the selected documents from disk and closes the dialog if there "
00075 "are no more unhandled documents.") );
00076
00077 QVBox *w = makeVBoxMainWidget();
00078 w->setSpacing( KDialog::spacingHint() );
00079
00080 QHBox *lo1 = new QHBox( w );
00081
00082
00083 QLabel *icon = new QLabel( lo1 );
00084 icon->setPixmap( DesktopIcon("messagebox_warning") );
00085
00086 QLabel *t = new QLabel( i18n(
00087 "<qt>The documents listed below has changed on disk.<p>Select one "
00088 "or more at the time and press an action button until the list is empty.</qt>"), lo1 );
00089 lo1->setStretchFactor( t, 1000 );
00090
00091
00092 lvDocuments = new KListView( w );
00093 lvDocuments->addColumn( i18n("Filename") );
00094 lvDocuments->addColumn( i18n("Status on Disk") );
00095 lvDocuments->setSelectionMode( QListView::Single );
00096
00097 QStringList l;
00098 l << "" << i18n("Modified") << i18n("Created") << i18n("Deleted");
00099 for ( uint i=0; i < docs.size(); i++ )
00100 new KateDocItem( docs[i], l[ (uint)KateDocManager::self()->documentInfo( docs[i] )->modifiedOnDiscReason ], lvDocuments );
00101
00102 connect( lvDocuments, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
00103
00104
00105 QHBox *lo2 = new QHBox ( w );
00106 QWidget *d = new QWidget (lo2);
00107 lo2->setStretchFactor (d, 2);
00108 btnDiff = new KPushButton( KGuiItem (i18n("&View Difference"), "edit"), lo2 );
00109
00110 QWhatsThis::add( btnDiff, i18n(
00111 "Calculates the difference between the the editor contents and the disk "
00112 "file for the selected document, and shows the difference with the "
00113 "default application. Requires diff(1).") );
00114 connect( btnDiff, SIGNAL(clicked()), this, SLOT(slotDiff()) );
00115
00116 slotSelectionChanged();
00117 m_tmpfile = 0;
00118 }
00119
00120 KateMwModOnHdDialog::~KateMwModOnHdDialog()
00121 {
00122 }
00123
00124 void KateMwModOnHdDialog::slotUser1()
00125 {
00126 handleSelected( Ignore );
00127 }
00128
00129 void KateMwModOnHdDialog::slotUser2()
00130 {
00131 handleSelected( Overwrite );
00132 }
00133
00134 void KateMwModOnHdDialog::slotUser3()
00135 {
00136 handleSelected( Reload );
00137 }
00138
00139 void KateMwModOnHdDialog::handleSelected( int action )
00140 {
00141
00142 QValueList<QListViewItem *> itemsToDelete;
00143 for ( QListViewItemIterator it ( lvDocuments ); it.current(); ++it )
00144 {
00145 KateDocItem *item = static_cast<KateDocItem *>(it.current());
00146
00147 if ( item->isOn() )
00148 {
00149 int reason = (int)KateDocManager::self()->documentInfo( item->document )->modifiedOnDiscReason;
00150 bool succes = true;
00151
00152 Kate::DocumentExt *dext = documentExt( item->document );
00153 if ( ! dext ) continue;
00154
00155 dext->setModifiedOnDisk( 0 );
00156 switch ( action )
00157 {
00158 case Overwrite:
00159 succes = item->document->save();
00160 if ( ! succes )
00161 {
00162 KMessageBox::sorry( this,
00163 i18n("Could not save the document \n'%1'").
00164 arg( item->document->url().prettyURL() ) );
00165 }
00166 break;
00167
00168 case Reload:
00169 item->document->reloadFile();
00170 break;
00171
00172 default:
00173 break;
00174 }
00175
00176 if ( succes )
00177 itemsToDelete.append (item);
00178 else
00179 dext->setModifiedOnDisk( reason );
00180 }
00181 }
00182
00183
00184 for (unsigned int i=0; i < itemsToDelete.count(); ++i)
00185 delete itemsToDelete[i];
00186
00187
00188 if ( ! lvDocuments->childCount() )
00189 done( Ok );
00190 }
00191
00192 void KateMwModOnHdDialog::slotSelectionChanged()
00193 {
00194
00195 btnDiff->setEnabled( lvDocuments->currentItem() &&
00196 KateDocManager::self()->documentInfo( ((KateDocItem*)lvDocuments->currentItem())->document )->modifiedOnDiscReason != 3 );
00197 }
00198
00199
00200
00201 void KateMwModOnHdDialog::slotDiff()
00202 {
00203 if ( m_tmpfile )
00204 return;
00205
00206 if ( ! lvDocuments->currentItem() )
00207 return;
00208
00209 Kate::Document *doc = ((KateDocItem*)lvDocuments->currentItem())->document;
00210
00211
00212 if ( KateDocManager::self()->documentInfo( doc )->modifiedOnDiscReason == 3 )
00213 return;
00214
00215
00216 KProcIO *p = new KProcIO();
00217 p->setComm( KProcess::All );
00218 *p << "diff" << "-u" << "-" << doc->url().path();
00219 connect( p, SIGNAL(processExited(KProcess*)), this, SLOT(slotPDone(KProcess*)) );
00220 connect( p, SIGNAL(readReady(KProcIO*)), this, SLOT(slotPRead(KProcIO*)) );
00221
00222 setCursor( WaitCursor );
00223
00224 p->start( KProcess::NotifyOnExit, true );
00225
00226 uint lastln = doc->numLines();
00227 for ( uint l = 0; l < lastln; l++ )
00228 p->writeStdin( doc->textLine( l ), l < lastln );
00229
00230 p->closeWhenDone();
00231 }
00232
00233 void KateMwModOnHdDialog::slotPRead( KProcIO *p)
00234 {
00235
00236 if ( ! m_tmpfile )
00237 m_tmpfile = new KTempFile();
00238
00239 QString stmp;
00240 bool dataRead = false;
00241 while ( p->readln( stmp, false ) > -1 ) {
00242 *m_tmpfile->textStream() << stmp << endl;
00243 dataRead = true;
00244 }
00245
00246 if (dataRead)
00247 p->ackRead();
00248 }
00249
00250 void KateMwModOnHdDialog::slotPDone( KProcess *p )
00251 {
00252 setCursor( ArrowCursor );
00253 if( ! m_tmpfile )
00254 {
00255
00256
00257
00258
00259
00260
00261 m_tmpfile = new KTempFile();
00262 }
00263 m_tmpfile->close();
00264
00265 if ( ! p->normalExit() )
00266 {
00267 KMessageBox::sorry( this,
00268 i18n("The diff command failed. Please make sure that "
00269 "diff(1) is installed and in your PATH."),
00270 i18n("Error Creating Diff") );
00271 delete m_tmpfile;
00272 m_tmpfile = 0;
00273 return;
00274 }
00275
00276 KRun::runURL( m_tmpfile->name(), "text/x-diff", true );
00277 delete m_tmpfile;
00278 m_tmpfile = 0;
00279 }
00280
00281