joachim99@69
|
1 /***************************************************************************
|
joachim99@77
|
2 * Copyright (C) 2003-2007 Joachim Eibl <joachim.eibl at gmx.de> *
|
joachim99@69
|
3 * *
|
joachim99@69
|
4 * This program is free software; you can redistribute it and/or modify *
|
joachim99@69
|
5 * it under the terms of the GNU General Public License as published by *
|
joachim99@69
|
6 * the Free Software Foundation; either version 2 of the License, or *
|
joachim99@69
|
7 * (at your option) any later version. *
|
joachim99@69
|
8 * *
|
joachim99@69
|
9 * This program is distributed in the hope that it will be useful, *
|
joachim99@69
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
joachim99@69
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
joachim99@69
|
12 * GNU General Public License for more details. *
|
joachim99@69
|
13 * *
|
joachim99@69
|
14 * You should have received a copy of the GNU General Public License *
|
joachim99@69
|
15 * along with this program; if not, write to the *
|
joachim99@69
|
16 * Free Software Foundation, Inc., *
|
joachim99@69
|
17 * 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. *
|
joachim99@69
|
18 ***************************************************************************/
|
joachim99@8
|
19
|
joachim99@8
|
20 #include "kdiff3_part.h"
|
joachim99@8
|
21
|
joachim99@80
|
22 #include <kcomponentdata.h>
|
joachim99@8
|
23 #include <kaction.h>
|
joachim99@80
|
24 #include <kstandardaction.h>
|
joachim99@8
|
25 #include <kfiledialog.h>
|
joachim99@8
|
26
|
joachim99@8
|
27 #include <qfile.h>
|
joachim99@8
|
28 #include <qtextstream.h>
|
joachim99@75
|
29 #include <QProcess>
|
joachim99@75
|
30
|
joachim99@8
|
31 #include "kdiff3.h"
|
joachim99@8
|
32 #include "fileaccess.h"
|
joachim99@8
|
33
|
joachim99@8
|
34 #include <kmessagebox.h>
|
joachim99@8
|
35 #include <klocale.h>
|
joachim99@8
|
36 #include <iostream>
|
joachim99@66
|
37
|
joachim99@66
|
38 #include "version.h"
|
joachim99@66
|
39
|
joachim99@8
|
40 KDiff3Part::KDiff3Part( QWidget *parentWidget, const char *widgetName,
|
joachim99@80
|
41 QObject *parent )
|
joachim99@80
|
42 : KParts::ReadWritePart(parent)
|
joachim99@8
|
43 {
|
joachim99@8
|
44 // we need an instance
|
joachim99@80
|
45 setComponentData( *KDiff3PartFactory::instance() );
|
joachim99@8
|
46
|
joachim99@8
|
47 // this should be your custom internal widget
|
joachim99@8
|
48 m_widget = new KDiff3App( parentWidget, widgetName, this );
|
joachim99@8
|
49
|
joachim99@8
|
50 // This hack is necessary to avoid a crash when the program terminates.
|
joachim99@8
|
51 m_bIsShell = dynamic_cast<KParts::MainWindow*>(parentWidget)!=0;
|
joachim99@8
|
52
|
joachim99@8
|
53 // notify the part that this is our internal widget
|
joachim99@8
|
54 setWidget(m_widget);
|
joachim99@8
|
55
|
joachim99@8
|
56 // create our actions
|
joachim99@80
|
57 //KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
|
joachim99@80
|
58 //KStandardAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
|
joachim99@80
|
59 //KStandardAction::save(this, SLOT(save()), actionCollection());
|
joachim99@8
|
60
|
joachim99@8
|
61 setXMLFile("kdiff3_part.rc");
|
joachim99@8
|
62
|
joachim99@8
|
63 // we are read-write by default
|
joachim99@8
|
64 setReadWrite(true);
|
joachim99@8
|
65
|
joachim99@8
|
66 // we are not modified since we haven't done anything yet
|
joachim99@8
|
67 setModified(false);
|
joachim99@8
|
68 }
|
joachim99@8
|
69
|
joachim99@8
|
70 KDiff3Part::~KDiff3Part()
|
joachim99@8
|
71 {
|
joachim99@8
|
72 if ( m_widget!=0 && ! m_bIsShell )
|
joachim99@8
|
73 {
|
joachim99@80
|
74 m_widget->saveOptions( m_widget->isPart() ? componentData().config() : KGlobal::config() );
|
joachim99@8
|
75 }
|
joachim99@8
|
76 }
|
joachim99@8
|
77
|
joachim99@8
|
78 void KDiff3Part::setReadWrite(bool /*rw*/)
|
joachim99@8
|
79 {
|
joachim99@8
|
80 // ReadWritePart::setReadWrite(rw);
|
joachim99@8
|
81 }
|
joachim99@8
|
82
|
joachim99@8
|
83 void KDiff3Part::setModified(bool /*modified*/)
|
joachim99@8
|
84 {
|
joachim99@8
|
85 /*
|
joachim99@8
|
86 // get a handle on our Save action and make sure it is valid
|
joachim99@80
|
87 KAction *save = actionCollection()->action(KStandardAction::stdName(KStandardAction::Save));
|
joachim99@8
|
88 if (!save)
|
joachim99@8
|
89 return;
|
joachim99@8
|
90
|
joachim99@8
|
91 // if so, we either enable or disable it based on the current
|
joachim99@8
|
92 // state
|
joachim99@8
|
93 if (modified)
|
joachim99@8
|
94 save->setEnabled(true);
|
joachim99@8
|
95 else
|
joachim99@8
|
96 save->setEnabled(false);
|
joachim99@8
|
97
|
joachim99@8
|
98 // in any event, we want our parent to do it's thing
|
joachim99@8
|
99 ReadWritePart::setModified(modified);
|
joachim99@8
|
100 */
|
joachim99@8
|
101 }
|
joachim99@8
|
102
|
joachim99@68
|
103 static void getNameAndVersion( const QString& str, const QString& lineStart, QString& fileName, QString& version )
|
joachim99@68
|
104 {
|
joachim99@68
|
105 if ( str.left( lineStart.length() )==lineStart && fileName.isEmpty() )
|
joachim99@68
|
106 {
|
joachim99@70
|
107 int pos = lineStart.length();
|
joachim99@68
|
108 while ( pos<str.length() && (str[pos]==' ' || str[pos]=='\t') ) ++pos;
|
joachim99@70
|
109 int pos2 = str.length()-1;
|
joachim99@68
|
110 while ( pos2>pos )
|
joachim99@68
|
111 {
|
joachim99@68
|
112 while (pos2>pos && str[pos2]!=' ' && str[pos2]!='\t') --pos2;
|
joachim99@68
|
113 fileName = str.mid( pos, pos2-pos );
|
joachim99@75
|
114 std::cerr << "KDiff3: " << fileName.toLatin1().constData() << std::endl;
|
joachim99@68
|
115 if ( FileAccess(fileName).exists() ) break;
|
joachim99@68
|
116 --pos2;
|
joachim99@68
|
117 }
|
joachim99@68
|
118
|
joachim99@75
|
119 int vpos = str.lastIndexOf("\t", -1);
|
joachim99@68
|
120 if ( vpos>0 && vpos>(int)pos2 )
|
joachim99@68
|
121 {
|
joachim99@68
|
122 version = str.mid( vpos+1 );
|
joachim99@68
|
123 while( !version.right(1)[0].isLetterOrNumber() )
|
joachim99@68
|
124 version.truncate( version.length()-1 );
|
joachim99@68
|
125 }
|
joachim99@68
|
126 }
|
joachim99@68
|
127 }
|
joachim99@68
|
128
|
joachim99@68
|
129
|
joachim99@8
|
130 bool KDiff3Part::openFile()
|
joachim99@8
|
131 {
|
joachim99@8
|
132 // m_file is always local so we can use QFile on it
|
joachim99@80
|
133 std::cerr << "KDiff3: " << localFilePath().toLatin1().constData() << std::endl;
|
joachim99@80
|
134 QFile file(localFilePath());
|
joachim99@70
|
135 if (file.open(QIODevice::ReadOnly) == false)
|
joachim99@8
|
136 return false;
|
joachim99@8
|
137
|
joachim99@8
|
138 // our example widget is text-based, so we use QTextStream instead
|
joachim99@8
|
139 // of a raw QDataStream
|
joachim99@8
|
140 QTextStream stream(&file);
|
joachim99@8
|
141 QString str;
|
joachim99@8
|
142 QString fileName1;
|
joachim99@8
|
143 QString fileName2;
|
joachim99@8
|
144 QString version1;
|
joachim99@8
|
145 QString version2;
|
joachim99@70
|
146 while (!stream.atEnd() && (fileName1.isEmpty() || fileName2.isEmpty()) )
|
joachim99@8
|
147 {
|
joachim99@8
|
148 str = stream.readLine() + "\n";
|
joachim99@68
|
149 getNameAndVersion( str, "---", fileName1, version1 );
|
joachim99@68
|
150 getNameAndVersion( str, "+++", fileName2, version2 );
|
joachim99@8
|
151 }
|
joachim99@8
|
152
|
joachim99@8
|
153 file.close();
|
joachim99@8
|
154
|
joachim99@8
|
155 if ( fileName1.isEmpty() && fileName2.isEmpty() )
|
joachim99@8
|
156 {
|
joachim99@8
|
157 KMessageBox::sorry(m_widget, i18n("Couldn't find files for comparison."));
|
joachim99@8
|
158 return false;
|
joachim99@8
|
159 }
|
joachim99@8
|
160
|
joachim99@8
|
161 FileAccess f1(fileName1);
|
joachim99@8
|
162 FileAccess f2(fileName2);
|
joachim99@8
|
163
|
joachim99@8
|
164 if ( f1.exists() && f2.exists() && fileName1!=fileName2 )
|
joachim99@8
|
165 {
|
joachim99@66
|
166 m_widget->slotFileOpen2( fileName1, fileName2, "", "", "", "", "", 0 );
|
joachim99@8
|
167 return true;
|
joachim99@8
|
168 }
|
joachim99@8
|
169 else if ( version1.isEmpty() && f1.exists() )
|
joachim99@8
|
170 {
|
joachim99@8
|
171 // Normal patch
|
joachim99@8
|
172 // patch -f -u --ignore-whitespace -i [inputfile] -o [outfile] [patchfile]
|
joachim99@8
|
173 QString tempFileName = FileAccess::tempFileName();
|
joachim99@80
|
174 QString cmd = "patch -f -u --ignore-whitespace -i \"" + localFilePath() +
|
joachim99@68
|
175 "\" -o \""+tempFileName + "\" \"" + fileName1+ "\"";
|
joachim99@8
|
176
|
joachim99@75
|
177 QProcess process;
|
joachim99@75
|
178 process.start( cmd );
|
joachim99@75
|
179 process.waitForFinished(-1);
|
joachim99@8
|
180
|
joachim99@8
|
181 m_widget->slotFileOpen2( fileName1, tempFileName, "", "",
|
joachim99@66
|
182 "", version2.isEmpty() ? fileName2 : "REV:"+version2+":"+fileName2, "", 0 ); // alias names
|
joachim99@80
|
183 // std::cerr << "KDiff3: f1:" << fileName1.toLatin1() <<"<->"<<tempFileName.toLatin1()<< std::endl;
|
joachim99@73
|
184 FileAccess::removeTempFile( tempFileName );
|
joachim99@8
|
185 }
|
joachim99@8
|
186 else if ( version2.isEmpty() && f2.exists() )
|
joachim99@8
|
187 {
|
joachim99@8
|
188 // Reverse patch
|
joachim99@8
|
189 // patch -f -u -R --ignore-whitespace -i [inputfile] -o [outfile] [patchfile]
|
joachim99@8
|
190 QString tempFileName = FileAccess::tempFileName();
|
joachim99@80
|
191 QString cmd = "patch -f -u -R --ignore-whitespace -i \"" + localFilePath() +
|
joachim99@68
|
192 "\" -o \""+tempFileName + "\" \"" + fileName2+"\"";
|
joachim99@8
|
193
|
joachim99@75
|
194 QProcess process;
|
joachim99@75
|
195 process.start( cmd );
|
joachim99@75
|
196 process.waitForFinished(-1);
|
joachim99@8
|
197
|
joachim99@8
|
198 m_widget->slotFileOpen2( tempFileName, fileName2, "", "",
|
joachim99@66
|
199 version1.isEmpty() ? fileName1 : "REV:"+version1+":"+fileName1, "", "", 0 ); // alias name
|
joachim99@80
|
200 // std::cerr << "KDiff3: f2:" << fileName2.toLatin1() <<"<->"<<tempFileName.toLatin1()<< std::endl;
|
joachim99@73
|
201 FileAccess::removeTempFile( tempFileName );
|
joachim99@8
|
202 }
|
joachim99@8
|
203 else if ( !version1.isEmpty() && !version2.isEmpty() )
|
joachim99@8
|
204 {
|
joachim99@75
|
205 std::cerr << "KDiff3: f1/2:" << fileName1.toLatin1().constData() <<"<->"<<fileName2.toLatin1().constData()<< std::endl;
|
joachim99@8
|
206 // Assuming that files are on CVS: Try to get them
|
joachim99@8
|
207 // cvs update -p -r [REV] [FILE] > [OUTPUTFILE]
|
joachim99@8
|
208
|
joachim99@8
|
209 QString tempFileName1 = FileAccess::tempFileName();
|
joachim99@68
|
210 QString cmd1 = "cvs update -p -r " + version1 + " \"" + fileName1 + "\" >\""+tempFileName1+"\"";
|
joachim99@75
|
211 QProcess process1;
|
joachim99@75
|
212 process1.start( cmd1 );
|
joachim99@75
|
213 process1.waitForFinished(-1);
|
joachim99@8
|
214
|
joachim99@8
|
215 QString tempFileName2 = FileAccess::tempFileName();
|
joachim99@68
|
216 QString cmd2 = "cvs update -p -r " + version2 + " \"" + fileName2 + "\" >\""+tempFileName2+"\"";
|
joachim99@75
|
217 QProcess process2;
|
joachim99@75
|
218 process2.start( cmd2 );
|
joachim99@75
|
219 process2.waitForFinished(-1);
|
joachim99@8
|
220
|
joachim99@8
|
221 m_widget->slotFileOpen2( tempFileName1, tempFileName2, "", "",
|
joachim99@8
|
222 "REV:"+version1+":"+fileName1,
|
joachim99@8
|
223 "REV:"+version2+":"+fileName2,
|
joachim99@66
|
224 "", 0
|
joachim99@8
|
225 );
|
joachim99@8
|
226
|
joachim99@80
|
227 // std::cerr << "KDiff3: f1/2:" << tempFileName1.toLatin1() <<"<->"<<tempFileName2.toLatin1()<< std::endl;
|
joachim99@73
|
228 FileAccess::removeTempFile( tempFileName1 );
|
joachim99@73
|
229 FileAccess::removeTempFile( tempFileName2 );
|
joachim99@8
|
230 return true;
|
joachim99@8
|
231 }
|
joachim99@8
|
232 else
|
joachim99@8
|
233 {
|
joachim99@8
|
234 KMessageBox::sorry(m_widget, i18n("Couldn't find files for comparison."));
|
joachim99@8
|
235 }
|
joachim99@8
|
236
|
joachim99@8
|
237 return true;
|
joachim99@8
|
238 }
|
joachim99@8
|
239
|
joachim99@8
|
240 bool KDiff3Part::saveFile()
|
joachim99@8
|
241 {
|
joachim99@8
|
242 /* // if we aren't read-write, return immediately
|
joachim99@8
|
243 if (isReadWrite() == false)
|
joachim99@8
|
244 return false;
|
joachim99@8
|
245
|
joachim99@80
|
246 // localFilePath() is always local, so we use QFile
|
joachim99@80
|
247 QFile file(localFilePath());
|
joachim99@8
|
248 if (file.open(IO_WriteOnly) == false)
|
joachim99@8
|
249 return false;
|
joachim99@8
|
250
|
joachim99@8
|
251 // use QTextStream to dump the text to the file
|
joachim99@8
|
252 QTextStream stream(&file);
|
joachim99@8
|
253 //stream << m_widget->text();
|
joachim99@8
|
254
|
joachim99@8
|
255 file.close();
|
joachim99@8
|
256 return true;
|
joachim99@8
|
257 */
|
joachim99@8
|
258 return false; // Not implemented
|
joachim99@8
|
259 }
|
joachim99@8
|
260
|
joachim99@8
|
261
|
joachim99@8
|
262 // It's usually safe to leave the factory code alone.. with the
|
joachim99@8
|
263 // notable exception of the KAboutData data
|
joachim99@8
|
264 #include <kaboutdata.h>
|
joachim99@8
|
265 #include <klocale.h>
|
joachim99@80
|
266 #include <kglobal.h>
|
joachim99@8
|
267
|
joachim99@80
|
268 KComponentData* KDiff3PartFactory::s_instance = 0L;
|
joachim99@8
|
269 KAboutData* KDiff3PartFactory::s_about = 0L;
|
joachim99@8
|
270
|
joachim99@8
|
271 KDiff3PartFactory::KDiff3PartFactory()
|
joachim99@8
|
272 : KParts::Factory()
|
joachim99@8
|
273 {
|
joachim99@8
|
274 }
|
joachim99@8
|
275
|
joachim99@8
|
276 KDiff3PartFactory::~KDiff3PartFactory()
|
joachim99@8
|
277 {
|
joachim99@8
|
278 delete s_instance;
|
joachim99@8
|
279 delete s_about;
|
joachim99@8
|
280
|
joachim99@8
|
281 s_instance = 0L;
|
joachim99@8
|
282 }
|
joachim99@8
|
283
|
joachim99@80
|
284 KParts::Part* KDiff3PartFactory::createPartObject( QWidget *parentWidget,
|
joachim99@80
|
285 QObject *parent,
|
joachim99@8
|
286 const char *classname, const QStringList&/*args*/ )
|
joachim99@8
|
287 {
|
joachim99@8
|
288 // Create an instance of our Part
|
joachim99@80
|
289 KDiff3Part* obj = new KDiff3Part( parentWidget, 0, parent );
|
joachim99@8
|
290
|
joachim99@8
|
291 // See if we are to be read-write or not
|
joachim99@75
|
292 if (QString(classname) == "KParts::ReadOnlyPart")
|
joachim99@8
|
293 obj->setReadWrite(false);
|
joachim99@8
|
294
|
joachim99@8
|
295 return obj;
|
joachim99@8
|
296 }
|
joachim99@8
|
297
|
joachim99@80
|
298 KComponentData* KDiff3PartFactory::instance()
|
joachim99@8
|
299 {
|
joachim99@8
|
300 if( !s_instance )
|
joachim99@8
|
301 {
|
joachim99@80
|
302 s_about = new KAboutData(QByteArray("kdiff3part"), QByteArray("kdiff3part"), ki18n("KDiff3Part"), QByteArray(VERSION));
|
joachim99@80
|
303 s_about->addAuthor(ki18n("Joachim Eibl"), KLocalizedString(), QByteArray("joachim.eibl at gmx.de"));
|
joachim99@80
|
304 s_instance = new KComponentData(s_about);
|
joachim99@8
|
305 }
|
joachim99@8
|
306 return s_instance;
|
joachim99@8
|
307 }
|
joachim99@8
|
308
|
joachim99@8
|
309 extern "C"
|
joachim99@8
|
310 {
|
joachim99@8
|
311 void* init_libkdiff3part()
|
joachim99@8
|
312 {
|
joachim99@8
|
313 return new KDiff3PartFactory;
|
joachim99@8
|
314 }
|
joachim99@53
|
315 }
|
joachim99@8
|
316
|
joachim99@66
|
317 // Suppress warning with --enable-final
|
joachim99@66
|
318 #undef VERSION
|
joachim99@66
|
319
|
joachim99@70
|
320 //#include "kdiff3_part.moc"
|