katemwmodonhddialog.cpp
00001 /* 00002 This library is free software; you can redistribute it and/or 00003 modify it under the terms of the GNU Library General Public 00004 License version 2 as published by the Free Software Foundation. 00005 00006 This library is distributed in the hope that it will be useful, 00007 but WITHOUT ANY WARRANTY; without even the implied warranty of 00008 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00009 Library General Public License for more details. 00010 00011 You should have received a copy of the GNU Library General Public License 00012 along with this library; see the file COPYING.LIB. If not, write to 00013 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00014 Boston, MA 02110-1301, USA. 00015 00016 --- 00017 Copyright (C) 2004, Anders Lund <anders@alweb.dk> 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 <tqlabel.h> 00037 #include <tqlistview.h> 00038 #include <tqlayout.h> 00039 #include <tqpushbutton.h> 00040 #include <tqwhatsthis.h> 00041 #include <tqvbox.h> 00042 00043 class KateDocItem : public TQCheckListItem 00044 { 00045 public: 00046 KateDocItem( Kate::Document *doc, const TQString &status, KListView *lv ) 00047 : TQCheckListItem( 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, TQWidget *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 TQVBox *w = makeVBoxMainWidget(); 00078 w->setSpacing( KDialog::spacingHint() ); 00079 00080 TQHBox *lo1 = new TQHBox( w ); 00081 00082 // dialog text 00083 TQLabel *icon = new TQLabel( lo1 ); 00084 icon->setPixmap( DesktopIcon("messagebox_warning") ); 00085 00086 TQLabel *t = new TQLabel( 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 // document list 00092 lvDocuments = new KListView( w ); 00093 lvDocuments->addColumn( i18n("Filename") ); 00094 lvDocuments->addColumn( i18n("Status on Disk") ); 00095 lvDocuments->setSelectionMode( TQListView::Single ); 00096 00097 TQStringList 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, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotSelectionChanged()) ); 00103 00104 // diff button 00105 TQHBox *lo2 = new TQHBox ( w ); 00106 TQWidget *d = new TQWidget (lo2); 00107 lo2->setStretchFactor (d, 2); 00108 btnDiff = new KPushButton( KGuiItem (i18n("&View Difference"), "edit"), lo2 ); 00109 00110 TQWhatsThis::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, TQT_SIGNAL(clicked()), this, TQT_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 // collect all items we can remove 00142 TQValueList<TQListViewItem *> itemsToDelete; 00143 for ( TQListViewItemIterator 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 // remove the marked items 00184 for (unsigned int i=0; i < itemsToDelete.count(); ++i) 00185 delete itemsToDelete[i]; 00186 00187 // any documents left unhandled? 00188 if ( ! lvDocuments->childCount() ) 00189 done( Ok ); 00190 } 00191 00192 void KateMwModOnHdDialog::slotSelectionChanged() 00193 { 00194 // set the diff button enabled 00195 btnDiff->setEnabled( lvDocuments->currentItem() && 00196 KateDocManager::self()->documentInfo( ((KateDocItem*)lvDocuments->currentItem())->document )->modifiedOnDiscReason != 3 ); 00197 } 00198 00199 // ### the code below is slightly modified from kdelibs/kate/part/katedialogs, 00200 // class KateModOnHdPrompt. 00201 void KateMwModOnHdDialog::slotDiff() 00202 { 00203 if ( m_tmpfile ) // we are allready somewhere in this process. 00204 return; 00205 00206 if ( ! lvDocuments->currentItem() ) 00207 return; 00208 00209 Kate::Document *doc = ((KateDocItem*)lvDocuments->currentItem())->document; 00210 00211 // don't try o diff a deleted file 00212 if ( KateDocManager::self()->documentInfo( doc )->modifiedOnDiscReason == 3 ) 00213 return; 00214 00215 // Start a KProcess that creates a diff 00216 KProcIO *p = new KProcIO(); 00217 p->setComm( KProcess::All ); 00218 *p << "diff" << "-u" << "-" << doc->url().path(); 00219 connect( p, TQT_SIGNAL(processExited(KProcess*)), this, TQT_SLOT(slotPDone(KProcess*)) ); 00220 connect( p, TQT_SIGNAL(readReady(KProcIO*)), this, TQT_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 // create a file for the diff if we haven't one allready 00236 if ( ! m_tmpfile ) 00237 m_tmpfile = new KTempFile(); 00238 // put all the data we have in it 00239 TQString 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 // dominik: there were only whitespace changes, so that the diff returned by 00256 // diff(1) has 0 bytes. So slotPRead() is never called, as there is 00257 // no data, so that m_tmpfile was never created and thus is NULL. 00258 // NOTE: would be nice, if we could produce a fake-diff, so that kompare 00259 // tells us "The files are identical". Right now, we get an ugly 00260 // "Could not parse diff output". 00261 m_tmpfile = new KTempFile(); 00262 } 00263 m_tmpfile->close(); 00264 00265 if ( ! p->normalExit() /*|| p->exitStatus()*/ ) 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 // kate: space-indent on; indent-width 2; replace-tabs on;