joachim99@69: /*************************************************************************** joachim99@77: * Copyright (C) 2003-2007 Joachim Eibl * joachim99@69: * * joachim99@69: * This program is free software; you can redistribute it and/or modify * joachim99@69: * it under the terms of the GNU General Public License as published by * joachim99@69: * the Free Software Foundation; either version 2 of the License, or * joachim99@69: * (at your option) any later version. * joachim99@69: * * joachim99@69: * This program is distributed in the hope that it will be useful, * joachim99@69: * but WITHOUT ANY WARRANTY; without even the implied warranty of * joachim99@69: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * joachim99@69: * GNU General Public License for more details. * joachim99@69: * * joachim99@69: * You should have received a copy of the GNU General Public License * joachim99@69: * along with this program; if not, write to the * joachim99@69: * Free Software Foundation, Inc., * joachim99@69: * 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. * joachim99@69: ***************************************************************************/ joachim99@8: joachim99@8: #include "kdiff3_part.h" joachim99@8: joachim99@80: #include joachim99@8: #include joachim99@80: #include joachim99@8: #include joachim99@8: joachim99@8: #include joachim99@8: #include joachim99@75: #include joachim99@75: joachim99@8: #include "kdiff3.h" joachim99@8: #include "fileaccess.h" joachim99@8: joachim99@8: #include joachim99@8: #include joachim99@8: #include joachim99@66: joachim99@66: #include "version.h" joachim99@66: joachim99@8: KDiff3Part::KDiff3Part( QWidget *parentWidget, const char *widgetName, joachim99@80: QObject *parent ) joachim99@80: : KParts::ReadWritePart(parent) joachim99@8: { joachim99@8: // we need an instance joachim99@80: setComponentData( *KDiff3PartFactory::instance() ); joachim99@8: joachim99@8: // this should be your custom internal widget joachim99@8: m_widget = new KDiff3App( parentWidget, widgetName, this ); joachim99@8: joachim99@8: // This hack is necessary to avoid a crash when the program terminates. joachim99@8: m_bIsShell = dynamic_cast(parentWidget)!=0; joachim99@8: joachim99@8: // notify the part that this is our internal widget joachim99@8: setWidget(m_widget); joachim99@8: joachim99@8: // create our actions joachim99@80: //KStandardAction::open(this, SLOT(fileOpen()), actionCollection()); joachim99@80: //KStandardAction::saveAs(this, SLOT(fileSaveAs()), actionCollection()); joachim99@80: //KStandardAction::save(this, SLOT(save()), actionCollection()); joachim99@8: joachim99@8: setXMLFile("kdiff3_part.rc"); joachim99@8: joachim99@8: // we are read-write by default joachim99@8: setReadWrite(true); joachim99@8: joachim99@8: // we are not modified since we haven't done anything yet joachim99@8: setModified(false); joachim99@8: } joachim99@8: joachim99@8: KDiff3Part::~KDiff3Part() joachim99@8: { joachim99@8: if ( m_widget!=0 && ! m_bIsShell ) joachim99@8: { joachim99@80: m_widget->saveOptions( m_widget->isPart() ? componentData().config() : KGlobal::config() ); joachim99@8: } joachim99@8: } joachim99@8: joachim99@8: void KDiff3Part::setReadWrite(bool /*rw*/) joachim99@8: { joachim99@8: // ReadWritePart::setReadWrite(rw); joachim99@8: } joachim99@8: joachim99@8: void KDiff3Part::setModified(bool /*modified*/) joachim99@8: { joachim99@8: /* joachim99@8: // get a handle on our Save action and make sure it is valid joachim99@80: KAction *save = actionCollection()->action(KStandardAction::stdName(KStandardAction::Save)); joachim99@8: if (!save) joachim99@8: return; joachim99@8: joachim99@8: // if so, we either enable or disable it based on the current joachim99@8: // state joachim99@8: if (modified) joachim99@8: save->setEnabled(true); joachim99@8: else joachim99@8: save->setEnabled(false); joachim99@8: joachim99@8: // in any event, we want our parent to do it's thing joachim99@8: ReadWritePart::setModified(modified); joachim99@8: */ joachim99@8: } joachim99@8: joachim99@68: static void getNameAndVersion( const QString& str, const QString& lineStart, QString& fileName, QString& version ) joachim99@68: { joachim99@68: if ( str.left( lineStart.length() )==lineStart && fileName.isEmpty() ) joachim99@68: { joachim99@70: int pos = lineStart.length(); joachim99@68: while ( pospos ) joachim99@68: { joachim99@68: while (pos2>pos && str[pos2]!=' ' && str[pos2]!='\t') --pos2; joachim99@68: fileName = str.mid( pos, pos2-pos ); joachim99@75: std::cerr << "KDiff3: " << fileName.toLatin1().constData() << std::endl; joachim99@68: if ( FileAccess(fileName).exists() ) break; joachim99@68: --pos2; joachim99@68: } joachim99@68: joachim99@75: int vpos = str.lastIndexOf("\t", -1); joachim99@68: if ( vpos>0 && vpos>(int)pos2 ) joachim99@68: { joachim99@68: version = str.mid( vpos+1 ); joachim99@68: while( !version.right(1)[0].isLetterOrNumber() ) joachim99@68: version.truncate( version.length()-1 ); joachim99@68: } joachim99@68: } joachim99@68: } joachim99@68: joachim99@68: joachim99@8: bool KDiff3Part::openFile() joachim99@8: { joachim99@8: // m_file is always local so we can use QFile on it joachim99@80: std::cerr << "KDiff3: " << localFilePath().toLatin1().constData() << std::endl; joachim99@80: QFile file(localFilePath()); joachim99@70: if (file.open(QIODevice::ReadOnly) == false) joachim99@8: return false; joachim99@8: joachim99@8: // our example widget is text-based, so we use QTextStream instead joachim99@8: // of a raw QDataStream joachim99@8: QTextStream stream(&file); joachim99@8: QString str; joachim99@8: QString fileName1; joachim99@8: QString fileName2; joachim99@8: QString version1; joachim99@8: QString version2; joachim99@70: while (!stream.atEnd() && (fileName1.isEmpty() || fileName2.isEmpty()) ) joachim99@8: { joachim99@8: str = stream.readLine() + "\n"; joachim99@68: getNameAndVersion( str, "---", fileName1, version1 ); joachim99@68: getNameAndVersion( str, "+++", fileName2, version2 ); joachim99@8: } joachim99@8: joachim99@8: file.close(); joachim99@8: joachim99@8: if ( fileName1.isEmpty() && fileName2.isEmpty() ) joachim99@8: { joachim99@8: KMessageBox::sorry(m_widget, i18n("Couldn't find files for comparison.")); joachim99@8: return false; joachim99@8: } joachim99@8: joachim99@8: FileAccess f1(fileName1); joachim99@8: FileAccess f2(fileName2); joachim99@8: joachim99@8: if ( f1.exists() && f2.exists() && fileName1!=fileName2 ) joachim99@8: { joachim99@66: m_widget->slotFileOpen2( fileName1, fileName2, "", "", "", "", "", 0 ); joachim99@8: return true; joachim99@8: } joachim99@8: else if ( version1.isEmpty() && f1.exists() ) joachim99@8: { joachim99@8: // Normal patch joachim99@8: // patch -f -u --ignore-whitespace -i [inputfile] -o [outfile] [patchfile] joachim99@8: QString tempFileName = FileAccess::tempFileName(); joachim99@80: QString cmd = "patch -f -u --ignore-whitespace -i \"" + localFilePath() + joachim99@68: "\" -o \""+tempFileName + "\" \"" + fileName1+ "\""; joachim99@8: joachim99@75: QProcess process; joachim99@75: process.start( cmd ); joachim99@75: process.waitForFinished(-1); joachim99@8: joachim99@8: m_widget->slotFileOpen2( fileName1, tempFileName, "", "", joachim99@66: "", version2.isEmpty() ? fileName2 : "REV:"+version2+":"+fileName2, "", 0 ); // alias names joachim99@80: // std::cerr << "KDiff3: f1:" << fileName1.toLatin1() <<"<->"<slotFileOpen2( tempFileName, fileName2, "", "", joachim99@66: version1.isEmpty() ? fileName1 : "REV:"+version1+":"+fileName1, "", "", 0 ); // alias name joachim99@80: // std::cerr << "KDiff3: f2:" << fileName2.toLatin1() <<"<->"<"< [OUTPUTFILE] joachim99@8: joachim99@8: QString tempFileName1 = FileAccess::tempFileName(); joachim99@68: QString cmd1 = "cvs update -p -r " + version1 + " \"" + fileName1 + "\" >\""+tempFileName1+"\""; joachim99@75: QProcess process1; joachim99@75: process1.start( cmd1 ); joachim99@75: process1.waitForFinished(-1); joachim99@8: joachim99@8: QString tempFileName2 = FileAccess::tempFileName(); joachim99@68: QString cmd2 = "cvs update -p -r " + version2 + " \"" + fileName2 + "\" >\""+tempFileName2+"\""; joachim99@75: QProcess process2; joachim99@75: process2.start( cmd2 ); joachim99@75: process2.waitForFinished(-1); joachim99@8: joachim99@8: m_widget->slotFileOpen2( tempFileName1, tempFileName2, "", "", joachim99@8: "REV:"+version1+":"+fileName1, joachim99@8: "REV:"+version2+":"+fileName2, joachim99@66: "", 0 joachim99@8: ); joachim99@8: joachim99@80: // std::cerr << "KDiff3: f1/2:" << tempFileName1.toLatin1() <<"<->"<text(); joachim99@8: joachim99@8: file.close(); joachim99@8: return true; joachim99@8: */ joachim99@8: return false; // Not implemented joachim99@8: } joachim99@8: joachim99@8: joachim99@8: // It's usually safe to leave the factory code alone.. with the joachim99@8: // notable exception of the KAboutData data joachim99@8: #include joachim99@8: #include joachim99@80: #include joachim99@8: joachim99@80: KComponentData* KDiff3PartFactory::s_instance = 0L; joachim99@8: KAboutData* KDiff3PartFactory::s_about = 0L; joachim99@8: joachim99@8: KDiff3PartFactory::KDiff3PartFactory() joachim99@8: : KParts::Factory() joachim99@8: { joachim99@8: } joachim99@8: joachim99@8: KDiff3PartFactory::~KDiff3PartFactory() joachim99@8: { joachim99@8: delete s_instance; joachim99@8: delete s_about; joachim99@8: joachim99@8: s_instance = 0L; joachim99@8: } joachim99@8: joachim99@80: KParts::Part* KDiff3PartFactory::createPartObject( QWidget *parentWidget, joachim99@80: QObject *parent, joachim99@8: const char *classname, const QStringList&/*args*/ ) joachim99@8: { joachim99@8: // Create an instance of our Part joachim99@80: KDiff3Part* obj = new KDiff3Part( parentWidget, 0, parent ); joachim99@8: joachim99@8: // See if we are to be read-write or not joachim99@75: if (QString(classname) == "KParts::ReadOnlyPart") joachim99@8: obj->setReadWrite(false); joachim99@8: joachim99@8: return obj; joachim99@8: } joachim99@8: joachim99@80: KComponentData* KDiff3PartFactory::instance() joachim99@8: { joachim99@8: if( !s_instance ) joachim99@8: { joachim99@80: s_about = new KAboutData(QByteArray("kdiff3part"), QByteArray("kdiff3part"), ki18n("KDiff3Part"), QByteArray(VERSION)); joachim99@80: s_about->addAuthor(ki18n("Joachim Eibl"), KLocalizedString(), QByteArray("joachim.eibl at gmx.de")); joachim99@80: s_instance = new KComponentData(s_about); joachim99@8: } joachim99@8: return s_instance; joachim99@8: } joachim99@8: joachim99@8: extern "C" joachim99@8: { joachim99@8: void* init_libkdiff3part() joachim99@8: { joachim99@8: return new KDiff3PartFactory; joachim99@8: } joachim99@53: } joachim99@8: joachim99@66: // Suppress warning with --enable-final joachim99@66: #undef VERSION joachim99@66: joachim99@70: //#include "kdiff3_part.moc"