Subversion Repositories Scribus

Rev

Rev 21942 | Rev 22518 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
364 Franz 7
/***************************************************************************
8
 *   Copyright (C) 2004 by Riku Leino                                      *
1184 tsoots 9
 *   tsoots@gmail.com                                                      *
364 Franz 10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 *   This program is distributed in the hope that it will be useful,       *
17
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19
 *   GNU General Public License for more details.                          *
20
 *                                                                         *
21
 *   You should have received a copy of the GNU General Public License     *
22
 *   along with this program; if not, write to the                         *
23
 *   Free Software Foundation, Inc.,                                       *
18122 mrdocs 24
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
364 Franz 25
 ***************************************************************************/
26
 
27
#include "gtgettext.h"
1665 craig 28
#include "pluginmanager.h"
1693 craig 29
#include "scpaths.h"
6132 cbradney 30
#include "pageitem.h"
5781 cbradney 31
#include "scribusdoc.h"
32
#include "selection.h"
13554 pierre 33
#include "ui/gtdialogs.h"
10601 mrdocs 34
#include "gtwriter.h"
8501 cbradney 35
#include <QPixmap>
364 Franz 36
 
11933 mrdocs 37
// Constructor
5781 cbradney 38
gtGetText::gtGetText(ScribusDoc* doc)
364 Franz 39
{
20913 jghali 40
        m_dias = NULL;
11933 mrdocs 41
        // Attach to the active document
20913 jghali 42
        m_Doc = doc;
11933 mrdocs 43
        // Load the plugins array.
364 Franz 44
        loadImporterPlugins();
11933 mrdocs 45
} // gtGetText::gtGetText(ScribusDoc* doc)
364 Franz 46
 
11933 mrdocs 47
// Look at the results of the file selection dialog and figure out if you need to use an importer.
48
// Prompt the user if the importer to use isn't obvious.
6132 cbradney 49
void gtGetText::launchImporter(int importer, const QString& filename, bool textOnly,
20671 fschmid 50
                                                                const QString& encoding, bool append, bool prefix, PageItem* target)
364 Franz 51
{
11933 mrdocs 52
        // Struct for the plugin info, we'll load this up from the array.
364 Franz 53
        struct ImporterData ida;
11933 mrdocs 54
        // Do we need to call an importer? Unsure what happens if this ever becomes false.
364 Franz 55
        bool callImporter = true;
11933 mrdocs 56
        // Check and see if the file selection dialog returned the index position of the 
57
        // importer to be used. If it isn't, try to figure out what it is. If we can't,
58
        // prompt the user.
364 Franz 59
        if (importer == -1)
60
        {
11933 mrdocs 61
                // Attempt to determine the importer based on the file's extension. 
62
                // Create a Qstring with what could be an extension.
10427 cbradney 63
                QString fend = filename.right(filename.length() - filename.lastIndexOf(".") - 1);
16445 craig 64
                QString fendL(fend.toLower());
65
                // Look for that extension in the importer QMap. 
20606 craig 66
                if (m_importerMap.find(fend) != m_importerMap.end())
11933 mrdocs 67
                        // If the map is found, assign ida to the corresponding struct in the map.
20606 craig 68
                        ida = *m_importerMap[fend];
16445 craig 69
                // Otherwise, test for the lowercase version
22422 jghali 70
                else if (m_importerMap.find(fendL) != m_importerMap.end())
16445 craig 71
                        // If the map is found, assign ida to the corresponding struct in the map.
20606 craig 72
                        ida = *m_importerMap[fendL];
11933 mrdocs 73
                // Otherwise, try and ask the user.
364 Franz 74
                else
75
                {
11933 mrdocs 76
                        // Create a new dialog
20606 craig 77
                        m_dias = new gtDialogs();
11933 mrdocs 78
                        // Pop up the dialog asking the user to select the type from our list (ilist) of 
79
                        // importable file types. If one is not selected, set callImporter to false.
22422 jghali 80
                        callImporter = m_dias->runImporterDialog(filename, m_ilist);
11933 mrdocs 81
                        // If we're gonna call an importer, we need to copy it's struct to ida.
364 Franz 82
                        if (callImporter)
20606 craig 83
                                ida = m_importers[m_dias->getImporter()];
11933 mrdocs 84
                        // Destroy the diag
20606 craig 85
                        delete m_dias;
11933 mrdocs 86
                } // else - if (importerMap.find(fend) != importerMap.end())
364 Franz 87
        }
11933 mrdocs 88
        else // If we know which importer to use
364 Franz 89
        {
11933 mrdocs 90
                // Copy the importer's struct to ida.
20606 craig 91
                ida = m_importers[importer];
11933 mrdocs 92
        }       // else - if (importer == -1)
93
 
94
        // Create a target text frame for the imported text and assign it to the parameter "target"
6132 cbradney 95
        PageItem* targetFrame=target;
11933 mrdocs 96
 
97
        // If the targetframe is 0 ( no frame selected/created? ) then reassign it to the 
98
        // (questionable interpretation here) first frame in the documentation.
6132 cbradney 99
        if (targetFrame==0)
100
                targetFrame=m_Doc->m_Selection->itemAt(0);
364 Franz 101
 
11933 mrdocs 102
        // If the targetframe is not zero, and we do need to call the importer, 
103
        // Run the importer via "CallDLL" and pass it what it needs to know.
6132 cbradney 104
        if (targetFrame!=0 && callImporter)
20671 fschmid 105
                CallDLL(ida, filename, encoding, textOnly, append, prefix, targetFrame);
11933 mrdocs 106
}  //void gtGetText::launchImporter(int importer, const QString& filename, bool textOnly, 
107
   //                                           const QString& encoding, bool append, PageItem* target)
364 Franz 108
 
11933 mrdocs 109
// Find the available plugins based on the environment, validate they load, and 
110
// create quick lookup mappings.
364 Franz 111
void gtGetText::loadImporterPlugins()
112
{
11933 mrdocs 113
        // Get the path to the plugins
1693 craig 114
        QString gtdir = ScPaths::instance().pluginDir();
11933 mrdocs 115
        // Append the gettext path to the plugin
872 cbradney 116
        gtdir += "gettext";
11933 mrdocs 117
        // Set the search parameteer for the platform specific extension for the plugins ( DLL, so, etc. )
1665 craig 118
        QString libPattern = QString("*.%1*").arg(PluginManager::platformDllExtension());
11933 mrdocs 119
        // Search for matches.
10402 jghali 120
        QDir d(gtdir, libPattern, QDir::Name, (QDir::Filter) PluginManager::platformDllSearchFlags());
364 Franz 121
 
11933 mrdocs 122
        // Initialize a structure for the importers found
364 Franz 123
        struct ImporterData ida;
124
        ida.fileFormatName = "";
125
 
11933 mrdocs 126
        // Check and see if the directory existed and if the count of files matching is greater than 0.
364 Franz 127
        if ((d.exists()) && (d.count() != 0))
128
        {
11933 mrdocs 129
                // loop through the entries.
364 Franz 130
                for (uint dc = 0; dc < d.count(); ++dc)
131
                {
11933 mrdocs 132
                        // Verify the Plugin will load. If it does, collect the info on the plugin ( Name, extension, format, etc )
1666 craig 133
                        if (DLLName(d[dc], &ida.fileFormatName, &ida.fileEndings))
364 Franz 134
                        {
6361 subik 135
                                // no plugin's "format name" marks "don't load plug"
8461 cbradney 136
                                if (ida.fileFormatName.isNull())
6361 subik 137
                                        continue;
11933 mrdocs 138
                                // Store the path to the plugin.
364 Franz 139
                                ida.soFilePath = d[dc];
11933 mrdocs 140
                                // If the plugin path does not begin with /, prepend a /.
364 Franz 141
                                if (ida.soFilePath.left(1) != "/")
142
                                        ida.soFilePath = "/" + ida.soFilePath;
11933 mrdocs 143
                                // Add the plugin data to the end of the importer's vector.
20606 craig 144
                                m_importers.push_back(ida);
11933 mrdocs 145
                        }       // if (DLLName(d[dc], &ida.fileFormatName, &ida.fileEndings))
146
                }  // for (uint dc = 0; dc < d.count(); ++dc)
147
        }  // if ((d.exists()) && (d.count() != 0))
148
        // Create the Importer Extension to Plugin data qmap.
364 Franz 149
        createMap();
11933 mrdocs 150
}  // void gtGetText::loadImporterPlugins()
364 Franz 151
 
21314 fschmid 152
 
153
QStringList gtGetText::getSupportedTypes()
154
{
155
        QStringList result;
156
        for (uint i = 0; i < m_importers.size(); ++i)
157
        {
158
                if (m_importers[i].fileEndings.count() != 0)
159
                {
160
                        for (int j = 0; j < m_importers[i].fileEndings.count(); ++j)
161
                        {
162
                                result.append(m_importers[i].fileEndings[j].toLower());
163
                        }
164
                }
165
        }
166
        return result;
167
}
168
 
11933 mrdocs 169
// Creates the dialog for the user to import a file based on the supported file formats.
6132 cbradney 170
ImportSetup gtGetText::run()
364 Franz 171
{
11933 mrdocs 172
        // Initialize a filters list.
364 Franz 173
        QString filters = "";
11933 mrdocs 174
        // Create a string for the "All supported files filter". Start with the label then loop through
175
        // the importers vector and add all of the file extensions supported.
364 Franz 176
        QString allSupported = QObject::tr("All Supported Formats") + " (";
11933 mrdocs 177
        // Loop through the importers vector.
20606 craig 178
        for (uint i = 0; i < m_importers.size(); ++i)
364 Franz 179
        {
11933 mrdocs 180
                // If there are any file extnsions declared by the importer
20606 craig 181
                if (m_importers[i].fileEndings.count() != 0)
364 Franz 182
                {
11933 mrdocs 183
                        // Add the importer name to the filters list
20606 craig 184
                        filters += m_importers[i].fileFormatName + " (";
11933 mrdocs 185
                        // Loop though the extensions supported by the importer
20606 craig 186
                        for (int j = 0; j < m_importers[i].fileEndings.count(); ++j)
375 Franz 187
                        {
11933 mrdocs 188
                                // Add the extension to both the filter and allSupported strings
20606 craig 189
                                filters += "*." + m_importers[i].fileEndings[j] + " ";
190
                                allSupported += "*." + m_importers[i].fileEndings[j] + " ";
11933 mrdocs 191
                        }  // for (int j = 0; j < importers[i].fileEndings.count(); ++j)
192
                        // Trim the Qstring
10394 cbradney 193
                        filters = filters.trimmed();
11933 mrdocs 194
                        // Append "entry of entry" information to the end of the filter.
375 Franz 195
                        filters += ");;";
11933 mrdocs 196
                }  // if (importers[i].fileEndings.count() != 0)
197
        }  // for (uint i = 0; i < importers.size(); ++i)
198
        // Trim the allSupported QString and append "end of entry" data to the end of it.
10394 cbradney 199
        allSupported = allSupported.trimmed();
364 Franz 200
        allSupported += ");;";
11933 mrdocs 201
        // Prepend allSupported to the filters Qstring.
364 Franz 202
        filters = allSupported + filters;
11933 mrdocs 203
        // Add an "all files" entry to the end of the filters QString
364 Franz 204
        filters += QObject::tr("All Files (*)");
11933 mrdocs 205
        // Populate ilist with the file importer names.
20606 craig 206
        for (uint i = 0;  i < m_importers.size(); ++i)
207
                m_ilist.append(m_importers[i].fileFormatName);
11933 mrdocs 208
        // Create a new dialog.
20606 craig 209
        m_dias = new gtDialogs();
11933 mrdocs 210
        // Create a new ImportSetup struct
6132 cbradney 211
        ImportSetup impsetup;
11933 mrdocs 212
        // INitialize runDialog to false
6132 cbradney 213
        impsetup.runDialog=false;
11933 mrdocs 214
        // If we get a true back from the File selection Dialog ( which we send our filters and extensions lists )
20606 craig 215
        if (m_dias->runFileDialog(filters, m_ilist))
364 Franz 216
        {
11933 mrdocs 217
                // Set the runDialog to true
20671 fschmid 218
                impsetup.runDialog = true;
11933 mrdocs 219
                // Copy the other values for the struct from the dialog results
20671 fschmid 220
                impsetup.encoding = m_dias->getEncoding();
221
                impsetup.filename = m_dias->getFileName();
222
                impsetup.importer = m_dias->getImporter();
223
                impsetup.textOnly = m_dias->importTextOnly();
224
                impsetup.prefixNames = m_dias->prefixStyles();
22422 jghali 225
        }
11933 mrdocs 226
        // Destroy the dialog.
20606 craig 227
        delete m_dias;
11933 mrdocs 228
        // Return the ImportSetup struct.
6132 cbradney 229
        return impsetup;
11933 mrdocs 230
}  // ImportSetup gtGetText::run()
364 Franz 231
 
11933 mrdocs 232
// Loads, validates, and executes the Importer code.
375 Franz 233
void gtGetText::CallDLL(const ImporterData& idata, const QString& filePath,
20671 fschmid 234
                                                const QString& encoding, bool textOnly, bool append, bool prefix, PageItem* importItem)
364 Franz 235
{
11933 mrdocs 236
        // Pointer for the loaded plugin.
2831 craig 237
        void* gtplugin;
11933 mrdocs 238
        // Type definition for GetText pointer in the function in question.
21282 fschmid 239
        typedef void (*gt2ptr)(QString filename, QString encoding, bool textOnly, bool prefix, bool append, PageItem *textframe);
16699 jghali 240
        // Type definition for GetText pointer in the function in question.
364 Franz 241
        typedef void (*sdem)(QString filename, QString encoding, bool textOnly, gtWriter *writer);
11933 mrdocs 242
        // The point to the above.
16699 jghali 243
        gt2ptr fp_GetText2;
1666 craig 244
        sdem fp_GetText;
11933 mrdocs 245
        // Initialize Path to the "DLL"
21942 craig 246
        QString pluginFilePath = QString("%1/gettext/%2").arg(ScPaths::instance().pluginDir(), idata.soFilePath);
11933 mrdocs 247
        // Attempt to load the plugin, store the pointer in gtplugin
2841 craig 248
        gtplugin = PluginManager::loadDLL(pluginFilePath);
11933 mrdocs 249
        // If gtplugin is NULL we failed to load the plugin. Report an error to the user and exit the method.
2831 craig 250
        if (!gtplugin)
251
        {
18194 fschmid 252
                qWarning("Failed to load plugin %s", pluginFilePath.toLatin1().constData());
2831 craig 253
                return;
11933 mrdocs 254
        } // if (!gtplugin)
14472 fschmid 255
 
16699 jghali 256
        fp_GetText2 = (gt2ptr) PluginManager::resolveSym(gtplugin,"GetText2");
257
        if (fp_GetText2)
258
        {
259
                if (!append)
260
                        importItem->itemText.clear();
261
                // Execute the importer's "GetText2" method.
21282 fschmid 262
                (*fp_GetText2)(filePath, encoding, textOnly, prefix, append, importItem);
16699 jghali 263
        }  // if (!fp_GetText2)        
264
        else
265
        {
266
                // Attempt to map the old GetText method to to the pointer via the PluginManager. Store the result in fp_GetText.
267
                fp_GetText = (sdem) PluginManager::resolveSym(gtplugin,"GetText");
268
                // If fp_GetText is NULL, we could not find the symbol,report the error, unload the "DLL" and exit the method.
269
                if (fp_GetText)
270
                {
271
                        // Create a new writer object in "append"'s mode (true or false ) attached to the importItem
272
                        gtWriter *w = new gtWriter(append, importItem);
273
                        // Execute the importer's "GetText" method.
274
                        (*fp_GetText)(filePath, encoding, textOnly, w);
275
                        // Destroy the writer
276
                        delete w;
277
                }  // if (!fp_GetText)
278
                else
279
                {
18194 fschmid 280
                        qWarning("Failed to get GetText() from %s",pluginFilePath.toLatin1().constData());
16699 jghali 281
                }
282
        }
283
        // GetText is not quite up to date vs styles, clean char formatting already specified at paragraph level
284
        importItem->itemText.fixLegacyFormatting();
285
        // Unload the plugin.
286
        PluginManager::unloadDLL(gtplugin);
11933 mrdocs 287
}  // void gtGetText::CallDLL(const ImporterData& idata, const QString& filePath,
288
   //                     const QString& encoding, bool textOnly, bool append, PageItem* importItem)
364 Franz 289
 
11933 mrdocs 290
// Loads the "DLL", validates the importer is good, populates the passed parameters with 
291
// the plugin information.
1666 craig 292
bool gtGetText::DLLName(QString name, QString *ffName, QStringList *fEndings)
364 Franz 293
{
11933 mrdocs 294
        // Pointer to the plugin, once loaded
2831 craig 295
        void* gtplugin;
11933 mrdocs 296
        // typedef of Qstring to map the importer name (FileFormatName) method results to.
364 Franz 297
        typedef QString (*sdem0)();
11933 mrdocs 298
        // typedef of QStringList to map the file extensions supported method results to.
364 Franz 299
        typedef QStringList (*sdem1)();
11933 mrdocs 300
        // The actual importer name object
1666 craig 301
        sdem0 fp_FileFormatName;
11933 mrdocs 302
        // The actual extensions supported object
1666 craig 303
        sdem1 fp_FileExtensions;
11933 mrdocs 304
        // Initialise the plugin file path ( with filename )
21942 craig 305
        QString pluginFilePath = QString("%1/gettext/%2").arg(ScPaths::instance().pluginDir(), name);
11933 mrdocs 306
        // Attempt to load the plugin.
2831 craig 307
        gtplugin = PluginManager::loadDLL(pluginFilePath);
11933 mrdocs 308
        // if gtplugin is NULL we were unable to load the plugin. Return an error and exit the method.
2831 craig 309
        if (!gtplugin)
310
        {
18194 fschmid 311
                qWarning("Failed to load plugin %s", pluginFilePath.toLatin1().constData());
2831 craig 312
                return false;
313
        }
11933 mrdocs 314
        // Attempt to resolve the plugin symbol to the importer name (FileFormatName)
2831 craig 315
        fp_FileFormatName = (sdem0) PluginManager::resolveSym( gtplugin, "FileFormatName");
11933 mrdocs 316
        // if fp_FileFormatName is NULL, we could not find the FileFormatName symbol. The plugin is incomplete.
317
        // Report an error, unload the plugin, and exit the method.
1666 craig 318
        if (!fp_FileFormatName)
364 Franz 319
        {
18194 fschmid 320
                qWarning("Failed to get FileFormatName() from %s", pluginFilePath.toLatin1().constData());
2831 craig 321
                PluginManager::unloadDLL(gtplugin);
364 Franz 322
                return false;
323
        }
11933 mrdocs 324
        // Attempt to resolve the plugin symbol to the list of supported file extensions.
2831 craig 325
        fp_FileExtensions = (sdem1) PluginManager::resolveSym( gtplugin, "FileExtensions");
11933 mrdocs 326
        // if fp_FileExtensions is NULL, we could not find the FileExtensions symbol. The plugin is incomplete.
327
        // Report an error, unload the plugin, and exit the method.
1666 craig 328
        if (!fp_FileExtensions)
364 Franz 329
        {
18194 fschmid 330
                qWarning("Failed to get FileExtensions() from %s", pluginFilePath.toLatin1().constData());
2831 craig 331
                PluginManager::unloadDLL(gtplugin);
364 Franz 332
                return false;
333
        }
11933 mrdocs 334
        // Set the format name based on the resolved method.
1666 craig 335
        *ffName = (*fp_FileFormatName)();
11933 mrdocs 336
        // Set the extensions list based on the resolved method.
1666 craig 337
        *fEndings = (*fp_FileExtensions)();
11933 mrdocs 338
        // Unload the plugin
2831 craig 339
        PluginManager::unloadDLL(gtplugin);
11933 mrdocs 340
        // Successfully return!
364 Franz 341
        return true;
11933 mrdocs 342
}  // bool gtGetText::DLLName(QString name, QString *ffName, QStringList *fEndings)
364 Franz 343
 
11933 mrdocs 344
// Create the importer Qmap.
364 Franz 345
void gtGetText::createMap()
346
{
11933 mrdocs 347
        // Loop through the importers Vector
20606 craig 348
        for (uint i = 0; i < m_importers.size(); ++i)
364 Franz 349
        {
11933 mrdocs 350
                // Loop through each file extension the importer uses/importers and create an individual 
351
                // Qmap entry for it.
20606 craig 352
                for (int j = 0; j < m_importers[i].fileEndings.count(); ++j)
353
                                m_importerMap.insert(m_importers[i].fileEndings[j], &m_importers[i]);
11933 mrdocs 354
        }  // for (uint i = 0; i < importers.size(); ++i)
355
}  // void gtGetText::createMap()
364 Franz 356
 
11933 mrdocs 357
// Destructor
364 Franz 358
gtGetText::~gtGetText()
359
{
11933 mrdocs 360
        // Nothing needs to happen here.
364 Franz 361
}