kdiff3_part.cpp 10 KB
Newer Older
Joachim Eibl's avatar
Joachim Eibl committed
1
/***************************************************************************
Joachim Eibl's avatar
Joachim Eibl committed
2
 * Copyright (C) 2003-2007 Joachim Eibl <joachim.eibl at gmx.de>           *
Joachim Eibl's avatar
Joachim Eibl committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.           *
 ***************************************************************************/
Joachim Eibl's avatar
Joachim Eibl committed
19
20
21

#include "kdiff3_part.h"

Michael Reeves's avatar
Michael Reeves committed
22
#include <KAboutData>
Michael Reeves's avatar
Michael Reeves committed
23
#include <QAction>
Joachim Eibl's avatar
0.9.93    
Joachim Eibl committed
24
#include <kstandardaction.h>
Joachim Eibl's avatar
Joachim Eibl committed
25
26
#include <kfiledialog.h>

Joachim Eibl's avatar
Joachim Eibl committed
27
28
#include <QFile>
#include <QTextStream>
Joachim Eibl's avatar
Joachim Eibl committed
29
30
#include <QProcess>

Joachim Eibl's avatar
Joachim Eibl committed
31
32
33
34
35
#include "kdiff3.h"
#include "fileaccess.h"

#include <kmessagebox.h>
#include <klocale.h>
Joachim Eibl's avatar
0.9.86    
Joachim Eibl committed
36
37
38

#include "version.h"

Michael Reeves's avatar
Michael Reeves committed
39

Michael Reeves's avatar
Michael Reeves committed
40
/*static KAboutData createAboutData()
Michael Reeves's avatar
Michael Reeves committed
41
{
Michael Reeves's avatar
Michael Reeves committed
42
43
44
45
46
47
48
49
50
51
52
    QByteArray appVersion = QByteArray( VERSION );
    if ( sizeof(void*)==8 )
      appVersion += " (64 bit)";
    else if ( sizeof(void*)==4 )
      appVersion += " (32 bit)";
    
    KAboutData aboutData( "kdiff3part", i18n( "KDiff3 Part" ),
                           appVersion, i18n( "A KPart to display SVG images" ),
                           KAboutLicense::GPL_V2,
                           i18n( "Copyright 2007, Aurélien Gâteau <aurelien.gateau@free.fr>" ) );
    aboutData.addAuthor( i18n( "Joachim Eibl" ), QString(), QByteArray( "joachim.eibl at gmx.de" ) );
Michael Reeves's avatar
Michael Reeves committed
53
    return aboutData;
Michael Reeves's avatar
Michael Reeves committed
54
}*/
Michael Reeves's avatar
Michael Reeves committed
55

Michael Reeves's avatar
Michael Reeves committed
56
K_PLUGIN_FACTORY( KDiff3PartFactory, registerPlugin<KDiff3Part>(); )
Michael Reeves's avatar
Michael Reeves committed
57
//K_EXPORT_PLUGIN( KDiff3PartFactory(createAboutData()))
Michael Reeves's avatar
Michael Reeves committed
58

59
KDiff3Part::KDiff3Part( QWidget *parentWidget, QObject *parent, const QVariantList &args)
Michael Reeves's avatar
Michael Reeves committed
60
    : KParts::ReadWritePart( parent )
Joachim Eibl's avatar
Joachim Eibl committed
61
62
{
    // we need an instance
Michael Reeves's avatar
Michael Reeves committed
63
    //setComponentData( KPluginFactory::componentData() );
64
    const char *widgetName = args[0].toString().toUtf8().data();
Joachim Eibl's avatar
Joachim Eibl committed
65
66
67

    // this should be your custom internal widget
    m_widget = new KDiff3App( parentWidget, widgetName, this );
Michael Reeves's avatar
Michael Reeves committed
68

Joachim Eibl's avatar
Joachim Eibl committed
69
    // This hack is necessary to avoid a crash when the program terminates.
Michael Reeves's avatar
Michael Reeves committed
70
    m_bIsShell = qobject_cast<KParts::MainWindow*>( parentWidget ) != 0;
Joachim Eibl's avatar
Joachim Eibl committed
71
72

    // notify the part that this is our internal widget
Michael Reeves's avatar
Michael Reeves committed
73
    setWidget( m_widget );
Joachim Eibl's avatar
Joachim Eibl committed
74
75

    // create our actions
Joachim Eibl's avatar
0.9.93    
Joachim Eibl committed
76
77
78
    //KStandardAction::open(this, SLOT(fileOpen()), actionCollection());
    //KStandardAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
    //KStandardAction::save(this, SLOT(save()), actionCollection());
Joachim Eibl's avatar
Joachim Eibl committed
79

Michael Reeves's avatar
Michael Reeves committed
80
    setXMLFile( "kdiff3_part.rc" );
Joachim Eibl's avatar
Joachim Eibl committed
81
82

    // we are read-write by default
Michael Reeves's avatar
Michael Reeves committed
83
    setReadWrite( true );
Joachim Eibl's avatar
Joachim Eibl committed
84
85

    // we are not modified since we haven't done anything yet
Michael Reeves's avatar
Michael Reeves committed
86
    setModified( false );
Joachim Eibl's avatar
Joachim Eibl committed
87
88
89
90
}

KDiff3Part::~KDiff3Part()
{
Michael Reeves's avatar
Michael Reeves committed
91
    if( m_widget != 0  && ! m_bIsShell ) {
92
        m_widget->saveOptions( KSharedConfig::openConfig() );
Michael Reeves's avatar
Michael Reeves committed
93
    }
Joachim Eibl's avatar
Joachim Eibl committed
94
95
}

Michael Reeves's avatar
Michael Reeves committed
96
void KDiff3Part::setReadWrite( bool /*rw*/ )
Joachim Eibl's avatar
Joachim Eibl committed
97
98
99
100
{
//    ReadWritePart::setReadWrite(rw);
}

Michael Reeves's avatar
Michael Reeves committed
101
void KDiff3Part::setModified( bool /*modified*/ )
Joachim Eibl's avatar
Joachim Eibl committed
102
{
Michael Reeves's avatar
Michael Reeves committed
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    /*
        // get a handle on our Save action and make sure it is valid
        QAction *save = actionCollection()->action(KStandardAction::stdName(KStandardAction::Save));
        if (!save)
            return;

        // if so, we either enable or disable it based on the current
        // state
        if (modified)
            save->setEnabled(true);
        else
            save->setEnabled(false);

        // in any event, we want our parent to do it's thing
        ReadWritePart::setModified(modified);
    */
Joachim Eibl's avatar
Joachim Eibl committed
119
120
}

Joachim Eibl's avatar
Joachim Eibl committed
121
122
static void getNameAndVersion( const QString& str, const QString& lineStart, QString& fileName, QString& version )
{
Michael Reeves's avatar
Michael Reeves committed
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    if( str.left( lineStart.length() ) == lineStart && fileName.isEmpty() ) {
        int pos = lineStart.length();
        while( pos < str.length() && ( str[pos] == ' ' || str[pos] == '\t' ) ) ++pos;
        int pos2 = str.length() - 1;
        while( pos2 > pos ) {
            while( pos2 > pos && str[pos2] != ' ' && str[pos2] != '\t' ) --pos2;
            fileName = str.mid( pos, pos2 - pos );
            fprintf( stderr, "KDiff3: %s\n", fileName.toLatin1().constData() );
            if( FileAccess( fileName ).exists() ) break;
            --pos2;
        }

        int vpos = str.lastIndexOf( "\t", -1 );
        if( vpos > 0 && vpos > ( int )pos2 ) {
            version = str.mid( vpos + 1 );
            while( !version.right( 1 )[0].isLetterOrNumber() )
                version.truncate( version.length() - 1 );
        }
    }
Joachim Eibl's avatar
Joachim Eibl committed
142
143
144
}


Joachim Eibl's avatar
Joachim Eibl committed
145
146
bool KDiff3Part::openFile()
{
Michael Reeves's avatar
Michael Reeves committed
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
    // m_file is always local so we can use QFile on it
    fprintf( stderr, "KDiff3: %s\n", localFilePath().toLatin1().constData() );
    QFile file( localFilePath() );
    if( file.open( QIODevice::ReadOnly ) == false )
        return false;

    // our example widget is text-based, so we use QTextStream instead
    // of a raw QDataStream
    QTextStream stream( &file );
    QString str;
    QString fileName1;
    QString fileName2;
    QString version1;
    QString version2;
    while( !stream.atEnd() && ( fileName1.isEmpty() || fileName2.isEmpty() ) ) {
        str = stream.readLine() + "\n";
        getNameAndVersion( str, "---", fileName1, version1 );
        getNameAndVersion( str, "+++", fileName2, version2 );
    }

    file.close();

    if( fileName1.isEmpty() && fileName2.isEmpty() ) {
        KMessageBox::sorry( m_widget, i18n( "Couldn't find files for comparison." ) );
        return false;
    }

    FileAccess f1( fileName1 );
    FileAccess f2( fileName2 );

    if( f1.exists() && f2.exists() && fileName1 != fileName2 ) {
        m_widget->slotFileOpen2( fileName1, fileName2, "", "", "", "", "", 0 );
        return true;
    }
    else if( version1.isEmpty() && f1.exists() ) {
        // Normal patch
        // patch -f -u --ignore-whitespace -i [inputfile] -o [outfile] [patchfile]
        QString tempFileName = FileAccess::tempFileName();
        QString cmd = "patch -f -u --ignore-whitespace -i \"" + localFilePath() +
                      "\" -o \"" + tempFileName + "\" \"" + fileName1 + "\"";

        QProcess process;
        process.start( cmd );
        process.waitForFinished( -1 );

        m_widget->slotFileOpen2( fileName1, tempFileName, "", "",
                                 "", version2.isEmpty() ? fileName2 : "REV:" + version2 + ":" + fileName2, "", 0 ); // alias names
Joachim Eibl's avatar
0.9.93    
Joachim Eibl committed
194
//    std::cerr << "KDiff3: f1:" << fileName1.toLatin1() <<"<->"<<tempFileName.toLatin1()<< std::endl;
Michael Reeves's avatar
Michael Reeves committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
        FileAccess::removeTempFile( tempFileName );
    }
    else if( version2.isEmpty() && f2.exists() ) {
        // Reverse patch
        // patch -f -u -R --ignore-whitespace -i [inputfile] -o [outfile] [patchfile]
        QString tempFileName = FileAccess::tempFileName();
        QString cmd = "patch -f -u -R --ignore-whitespace -i \"" + localFilePath() +
                      "\" -o \"" + tempFileName + "\" \"" + fileName2 + "\"";

        QProcess process;
        process.start( cmd );
        process.waitForFinished( -1 );

        m_widget->slotFileOpen2( tempFileName, fileName2, "", "",
                                 version1.isEmpty() ? fileName1 : "REV:" + version1 + ":" + fileName1, "", "", 0 ); // alias name
Joachim Eibl's avatar
0.9.93    
Joachim Eibl committed
210
//    std::cerr << "KDiff3: f2:" << fileName2.toLatin1() <<"<->"<<tempFileName.toLatin1()<< std::endl;
Michael Reeves's avatar
Michael Reeves committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
        FileAccess::removeTempFile( tempFileName );
    }
    else if( !version1.isEmpty() && !version2.isEmpty() ) {
        fprintf( stderr, "KDiff3: f1/2:%s<->%s\n", fileName1.toLatin1().constData(), fileName2.toLatin1().constData() );
        // Assuming that files are on CVS: Try to get them
        // cvs update -p -r [REV] [FILE] > [OUTPUTFILE]

        QString tempFileName1 = FileAccess::tempFileName();
        QString cmd1 = "cvs update -p -r " + version1 + " \"" + fileName1 + "\" >\"" + tempFileName1 + "\"";
        QProcess process1;
        process1.start( cmd1 );
        process1.waitForFinished( -1 );

        QString tempFileName2 = FileAccess::tempFileName();
        QString cmd2 = "cvs update -p -r " + version2 + " \"" + fileName2 + "\" >\"" + tempFileName2 + "\"";
        QProcess process2;
        process2.start( cmd2 );
        process2.waitForFinished( -1 );

        m_widget->slotFileOpen2( tempFileName1, tempFileName2, "", "",
                                 "REV:" + version1 + ":" + fileName1,
                                 "REV:" + version2 + ":" + fileName2,
                                 "", 0
                               );
Joachim Eibl's avatar
Joachim Eibl committed
235

Joachim Eibl's avatar
0.9.93    
Joachim Eibl committed
236
//    std::cerr << "KDiff3: f1/2:" << tempFileName1.toLatin1() <<"<->"<<tempFileName2.toLatin1()<< std::endl;
Michael Reeves's avatar
Michael Reeves committed
237
238
239
240
241
242
243
244
245
        FileAccess::removeTempFile( tempFileName1 );
        FileAccess::removeTempFile( tempFileName2 );
        return true;
    }
    else {
        KMessageBox::sorry( m_widget, i18n( "Couldn't find files for comparison." ) );
    }

    return true;
Joachim Eibl's avatar
Joachim Eibl committed
246
247
248
249
}

bool KDiff3Part::saveFile()
{
Michael Reeves's avatar
Michael Reeves committed
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
    /*    // if we aren't read-write, return immediately
        if (isReadWrite() == false)
            return false;

        // localFilePath() is always local, so we use QFile
        QFile file(localFilePath());
        if (file.open(IO_WriteOnly) == false)
            return false;

        // use QTextStream to dump the text to the file
        QTextStream stream(&file);
        //stream << m_widget->text();

        file.close();
        return true;
    */
Joachim Eibl's avatar
Joachim Eibl committed
266
267
    return false;  // Not implemented
}
Joachim Eibl's avatar
0.9.86    
Joachim Eibl committed
268
269
270
// Suppress warning with --enable-final
#undef VERSION

Michael Reeves's avatar
Michael Reeves committed
271
#include "kdiff3_part.moc"