Back to index

scribus-ng  1.3.4.dfsg+svn20071115
scribuscore.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /***************************************************************************
00008                           pageitem.h  -  description
00009                              -------------------
00010     copyright            : Scribus Team
00011  ***************************************************************************/
00012 
00013 /***************************************************************************
00014  *                                                                         *
00015  *   This program is free software; you can redistribute it and/or modify  *
00016  *   it under the terms of the GNU General Public License as published by  *
00017  *   the Free Software Foundation; either version 2 of the License, or     *
00018  *   (at your option) any later version.                                   *
00019  *                                                                         *
00020  ***************************************************************************/
00021  
00022 #include <cassert>
00023 #include <iostream>
00024 #include <qglobal.h>
00025 
00026 #include "scribuscore.h"
00027 #include "scribuscore.moc"
00028 
00029 #include "util.h"
00030 #include "commonstrings.h"
00031 #include "filewatcher.h"
00032 #include "gsutil.h"
00033 #include "pluginmanager.h"
00034 #include "prefsmanager.h"
00035 #include "scpaths.h"
00036 #include "splash.h"
00037 #include "scribusapp.h"
00038 #include "undomanager.h"
00039 
00040 extern ScribusQApp* ScQApp;
00041 
00042 #include "cmserrorhandling.h"
00043 
00044 ScribusCore::ScribusCore() : QObject()
00045 {
00046        m_ScribusInitialized=false;
00047        m_SplashScreen=0;
00048        m_UseGUI=false;
00049        m_HaveCMS=false;
00050        m_PaletteParent=0;
00051        m_currScMW=0;
00052 }
00053 
00054 
00055 
00056 ScribusCore::~ScribusCore()
00057 {
00058        delete m_PaletteParent;
00059 }
00060 
00061 #ifndef NDEBUG
00062 static void abort_on_error(QtMsgType t, const char * m)
00063 {
00064        std::cerr << m << "\n";
00065        if(t==QtFatalMsg) assert(false);
00066 //     if(t!=QtDebugMsg) assert(false);
00067 }
00068 #endif
00069 
00070 
00071 int ScribusCore::init(bool useGUI, bool swapDialogButtonOrder, const QString fileToUse)
00072 {
00073        m_UseGUI=useGUI;
00074        m_File=fileToUse;
00075        m_SwapDialogButtonOrder=swapDialogButtonOrder;
00076 #ifndef NDEBUG
00077        qInstallMsgHandler( & abort_on_error );
00078 #endif
00079 
00080        return 0;
00081 }
00082 
00083 int ScribusCore::startGUI(bool showSplash, bool showFontInfo, bool showProfileInfo, const QString newGuiLanguage, const QString prefsUserFile)
00084 {
00085        m_PaletteParent=new QWidget(0);
00086        Q_CHECK_PTR(m_PaletteParent);
00087        ScribusMainWindow* scribus = new ScribusMainWindow();
00088        Q_CHECK_PTR(scribus);
00089        if (!scribus)
00090               return(EXIT_FAILURE);
00091        ScMWList.append(scribus);
00092        m_currScMW=0;
00093 //     ScMW=scribus;
00094        int retVal=initScribusCore(showSplash, showFontInfo, showProfileInfo,newGuiLanguage, prefsUserFile);
00095        if (retVal == 1)
00096               return(EXIT_FAILURE);
00097        retVal = scribus->initScMW(true);
00098        if (retVal == 1)
00099               return(EXIT_FAILURE);
00100        closeSplash();
00101        m_ScribusInitialized=true;
00102        ScQApp->setMainWidget(scribus);
00103        connect(ScQApp, SIGNAL(lastWindowClosed()), ScQApp, SLOT(quit()));
00104 
00105        scribus->show();
00106        scribus->ShowSubs();
00107 
00108        if (!m_File.isEmpty())
00109               scribus->loadDoc(m_File);
00110        else
00111        {
00112               if (PrefsManager::instance()->appPrefs.showStartupDialog)
00113                      scribus->startUpDialog();
00114               else
00115                      scribus->setFocus();
00116        }
00117 
00118        // A hook for plug-ins and scripts to trigger on. Some plugins and scripts
00119        // require the app to be fully set up (in particular, the main window to be
00120        // built and shown) before running their setup.
00121        emit appStarted();
00122        return EXIT_SUCCESS;
00123 }
00124 
00125 int ScribusCore::initScribusCore(bool showSplash, bool showFontInfo, bool showProfileInfo, 
00126                                                          const QString newGuiLanguage, const QString prefsUserFile)
00127 {
00128        CommonStrings::languageChange();
00129        int retVal=0;
00130 //FIXME       ExternalApp = 0;
00131        m_GuiLanguage = newGuiLanguage;
00132        initSplash(showSplash);
00133        prefsManager = PrefsManager::instance();
00134        prefsManager->setup();
00135        //CB #4428 Get fonts before prefs are set to default
00136        bool haveFonts=false;
00137 #ifdef QT_MAC
00138        haveFonts=ScCore->initFonts(true);
00139 #else
00140        haveFonts=ScCore->initFonts(showFontInfo);
00141 #endif
00142        if (!haveFonts)
00143               return 1;
00144        prefsManager->initDefaults();
00145        prefsManager->initDefaultGUIFont(qApp->font());
00146        prefsManager->initArrowStyles();
00147        undoManager = UndoManager::instance();
00148        fileWatcher = new FileWatcher(this);
00149        pluginManager = new PluginManager();
00150        setSplashStatus( tr("Initializing Plugins") );
00151        pluginManager->initPlugs();
00152 /* #4428, remove block later if ok
00153        bool haveFonts=false;
00154 #ifdef QT_MAC
00155        haveFonts=ScCore->initFonts(true);
00156 #else
00157        haveFonts=ScCore->initFonts(showFontInfo);
00158 #endif
00159        if (!haveFonts)
00160               return 1;
00161 */
00162        setSplashStatus( tr("Initializing Keyboard Shortcuts") );
00163        prefsManager->initDefaultActionKeys();
00164        setSplashStatus( tr("Reading Preferences") );
00165        if (prefsUserFile.isNull())
00166               prefsManager->ReadPrefs();
00167        else
00168               prefsManager->ReadPrefs(prefsUserFile);
00169 
00170        m_HaveGS = testGSAvailability();
00171        m_HavePngAlpha = testGSDeviceAvailability("pngalpha");
00172        m_HaveTiffSep = testGSDeviceAvailability("tiffsep");
00173        
00174        ScCore->setSplashStatus( tr("Reading ICC Profiles") );
00175        m_HaveCMS = false;
00176        getCMSProfiles(showProfileInfo);
00177        initCMS();
00178        /*
00179 
00180               buildFontMenu();
00181 
00182 
00183               initPalettes();
00184 
00185 
00186               setSplashStatus( tr("Initializing Hyphenator") );
00187               QString preLang = prefsManager->appPrefs.Language;
00188               initHyphenator();
00189               if (Sprachen.contains(preLang))
00190                      prefsManager->appPrefs.Language = preLang;
00191               setSplashStatus( tr("Reading Scrapbook") );
00192               initScrapbook();
00193               setSplashStatus( tr("Setting up Shortcuts") );
00194               SetShortCut();
00195               scrActions["helpTooltips"]->setOn(prefsManager->appPrefs.showToolTips);
00196               ToggleTips();
00197 
00198               connect(fileWatcher, SIGNAL(fileDeleted(QString )), this, SLOT(removeRecent(QString)));
00199               connect(this, SIGNAL(TextIFont(QString)), this, SLOT(AdjustFontMenu(QString)));
00200               connect(this, SIGNAL(TextIFont(QString)), propertiesPalette, SLOT(setFontFace(QString)));
00201               connect(this, SIGNAL(TextISize(int)), this, SLOT(setFSizeMenu(int)));
00202               connect(this, SIGNAL(TextISize(int)), propertiesPalette, SLOT(setSize(int)));
00203               connect(this, SIGNAL(TextUSval(int)), propertiesPalette, SLOT(setExtra(int)));
00204               connect(this, SIGNAL(TextStil(int)), propertiesPalette, SLOT(setStil(int)));
00205               connect(this, SIGNAL(TextScale(int)), propertiesPalette, SLOT(setTScale(int)));
00206               connect(this, SIGNAL(TextScaleV(int)), propertiesPalette, SLOT(setTScaleV(int)));
00207               connect(this, SIGNAL(TextBase(int)), propertiesPalette, SLOT(setTBase(int)));
00208               connect(this, SIGNAL(TextShadow(int, int )), propertiesPalette, SLOT(setShadowOffs(int, int )));
00209               connect(this, SIGNAL(TextOutline(int)), propertiesPalette, SLOT(setOutlineW(int)));
00210               connect(this, SIGNAL(TextUnderline(int, int)), propertiesPalette, SLOT(setUnderline(int, int)));
00211               connect(this, SIGNAL(TextStrike(int, int)), propertiesPalette, SLOT(setStrike(int, int)));
00212               connect(this, SIGNAL(TextFarben(QString, QString, int, int)), propertiesPalette, SLOT(setActFarben(QString, QString, int, int)));
00213        }*/
00214 
00215        return retVal;
00216 }
00217 
00218 
00219 void ScribusCore::initSplash(bool showSplash)
00220 {
00221        if (showSplash)
00222        {
00223               m_SplashScreen = new SplashScreen();
00224               if (m_SplashScreen != NULL && m_SplashScreen->isShown())
00225                      setSplashStatus(QObject::tr("Initializing..."));
00226        }
00227        else
00228               m_SplashScreen = NULL;
00229 }
00230 
00231 void ScribusCore::setSplashStatus(const QString& newText)
00232 {
00233        if (m_SplashScreen != NULL)
00234        {
00235               m_SplashScreen->setStatus( newText );
00236               qApp->processEvents();
00237        }
00238 }
00239 
00240 void ScribusCore::showSplash(bool shown)
00241 {
00242        if (m_SplashScreen!=NULL && shown!=m_SplashScreen->isShown())
00243               m_SplashScreen->setShown(shown);
00244 }
00245 
00246 bool ScribusCore::splashShowing() const
00247 {
00248        if (m_SplashScreen != NULL)
00249               return m_SplashScreen->isShown();
00250        return false;
00251 }
00252 
00253 void ScribusCore::closeSplash()
00254 {
00255        if (m_SplashScreen!=NULL)
00256        {
00257               m_SplashScreen->close();
00258               delete m_SplashScreen;
00259               m_SplashScreen = NULL;
00260        }
00261 }
00262 
00263 bool ScribusCore::usingGUI() const
00264 {
00265        return m_UseGUI;
00266 }
00267 
00268 bool ScribusCore::isMacGUI() const
00269 {
00270        // Do it statically for now
00271 #if defined(Q_WS_MAC)
00272        return true;
00273 #else
00274        return false;
00275 #endif
00276 }
00277 
00278 bool ScribusCore::isWinGUI() const
00279 {
00280        // Do it statically for now
00281 #if defined(_WIN32)
00282        return true;
00283 #else
00284        return false;
00285 #endif
00286 }
00287 
00288 bool ScribusCore::reverseDialogButtons() const
00289 {
00290        if (m_SwapDialogButtonOrder)
00291               return true;
00292        //Win32 - dont switch
00293        #if defined(_WIN32)
00294               return false;
00295        //Mac Aqua - switch
00296        #elif defined(Q_WS_MAC)
00297               return true;
00298        #else
00299        //Gnome - switch
00300        QString gnomesession= ::getenv("GNOME_DESKTOP_SESSION_ID");
00301        if (!gnomesession.isEmpty())
00302               return true;
00303 
00304        //KDE/KDE Aqua - dont switch
00305        //Best guess for now if we are running under KDE
00306        QString kdesession= ::getenv("KDE_FULL_SESSION");
00307        if (!kdesession.isEmpty())
00308               return false;
00309        #endif
00310        return false;
00311 }
00312 
00313 //Returns false when there are no fonts
00314 bool ScribusCore::initFonts(bool showFontInfo)
00315 {
00316        setSplashStatus( tr("Searching for Fonts") );
00317        bool haveFonts=prefsManager->GetAllFonts(showFontInfo);
00318        if (!haveFonts)
00319        {
00320               closeSplash();
00321               QString mess = tr("There are no fonts found on your system.");
00322               mess += "\n" + tr("Exiting now.");
00323               QMessageBox::critical(0, tr("Fatal Error"), mess, 1, 0, 0);
00324        }
00325        else
00326               setSplashStatus( tr("Font System Initialized") );
00327        return haveFonts;
00328 }
00329 
00330 
00331 void ScribusCore::getCMSProfiles(bool showInfo)
00332 {
00333        QString profDir;
00334        QStringList profDirs;
00335        MonitorProfiles.clear();
00336        PrinterProfiles.clear();
00337        InputProfiles.clear();
00338        InputProfilesCMYK.clear();
00339        QString pfad = ScPaths::instance().libDir();
00340        pfad += "profiles/";
00341        profDirs = ScPaths::getSystemProfilesDirs();
00342        profDirs.prepend( prefsManager->appPrefs.ProfileDir );
00343        profDirs.prepend( pfad );
00344        for(unsigned int i = 0; i < profDirs.count(); i++)
00345        {
00346               profDir = profDirs[i];
00347               if(!profDir.isEmpty())
00348               {
00349                      if(profDir.right(1) != "/")
00350                             profDir += "/";
00351                      getCMSProfilesDir(profDir, showInfo, true);
00352               }
00353        }
00354        if ((!PrinterProfiles.isEmpty()) && (!InputProfiles.isEmpty()) && (!MonitorProfiles.isEmpty()))
00355               m_HaveCMS = true;
00356        else
00357               m_HaveCMS = false;
00358 }
00359 
00360 void ScribusCore::getCMSProfilesDir(QString pfad, bool showInfo, bool recursive)
00361 {
00362        QDir d(pfad, "*", QDir::Name, QDir::Files | QDir::Readable | QDir::Dirs | QDir::NoSymLinks);
00363        if ((d.exists()) && (d.count() != 0))
00364        {
00365               QString nam = "";
00366               const char *Descriptor;
00367               cmsHPROFILE hIn = NULL;
00368 
00369               for (uint dc = 0; dc < d.count(); ++dc)
00370               {
00371                      QFileInfo fi(pfad + "/" + d[dc]);
00372                      if (fi.isDir() && !recursive)
00373                             continue;
00374                      else if (fi.isDir() && d[dc][0] != '.')
00375                      {
00376                             getCMSProfilesDir(fi.filePath()+"/", showInfo, true);
00377                             continue;
00378                      }
00379 
00380 #ifndef QT_MAC
00381                      QString ext = fi.extension(false).lower();
00382                      if ((ext != "icm") && (ext != "icc"))
00383                             continue;
00384 #endif
00385 
00386                      QFile f(fi.filePath());
00387                      QByteArray bb(40);
00388                      if (!f.open(IO_ReadOnly)) {
00389                             sDebug(QString("couldn't open %1 as ICC").arg(fi.filePath()));
00390                             continue;
00391                      }
00392                      int len = f.readBlock(bb.data(), 40);
00393                      f.close();
00394                      if (len == 40 && bb[36] == 'a' && bb[37] == 'c' && bb[38] == 's' && bb[39] == 'p')
00395                      {
00396                             const QCString profilePath( QString(pfad + d[dc]).local8Bit() );
00397                             if (setjmp(cmsJumpBuffer))
00398                             {
00399                                    // Profile is broken, show info if necessary
00400                                    if (showInfo)
00401                                           sDebug(QString("ICC profile %s is broken").arg(fi.filePath()));
00402                                    // Reset to the default handler otherwise may enter a loop
00403                                    // if an error occur in cmsCloseProfile()
00404                                    cmsSetErrorHandler(NULL);
00405                                    if (hIn)
00406                                    {
00407                                           cmsCloseProfile(hIn);
00408                                           hIn = NULL;
00409                                    }
00410                                    continue;
00411                             }
00412                             cmsSetErrorHandler(&cmsErrorHandler);
00413                             hIn = cmsOpenProfileFromFile(profilePath.data(), "r");
00414                             if (hIn == NULL)
00415                                    continue;
00416                             Descriptor = cmsTakeProductDesc(hIn);
00417                             nam = QString(Descriptor);
00418                             switch (static_cast<int>(cmsGetDeviceClass(hIn)))
00419                             {
00420                             case icSigInputClass:
00421                                    if (static_cast<int>(cmsGetColorSpace(hIn)) == icSigRgbData)
00422                                           InputProfiles.insert(nam, pfad + d[dc], false);
00423                                    break;
00424                             case icSigColorSpaceClass:
00425                                    if (static_cast<int>(cmsGetColorSpace(hIn)) == icSigRgbData)
00426                                           InputProfiles.insert(nam, pfad + d[dc], false);
00427                                    if (static_cast<int>(cmsGetColorSpace(hIn)) == icSigCmykData)
00428                                           InputProfilesCMYK.insert(nam, pfad + d[dc], false);
00429                                    break;
00430                             case icSigDisplayClass:
00431                                    if (static_cast<int>(cmsGetColorSpace(hIn)) == icSigRgbData)
00432                                    {
00433                                           MonitorProfiles.insert(nam, pfad + d[dc], false);
00434                                           InputProfiles.insert(nam, pfad + d[dc], false);
00435                                    }
00436                                    if (static_cast<int>(cmsGetColorSpace(hIn)) == icSigCmykData)
00437                                           InputProfilesCMYK.insert(nam, pfad + d[dc], false);
00438                                    break;
00439                             case icSigOutputClass:
00440                                    // Disable rgb printer profile detection until effective support
00441                                    // PrinterProfiles.insert(nam, pfad + d[dc], false);
00442                                    if (static_cast<int>(cmsGetColorSpace(hIn)) == icSigCmykData)
00443                                    {
00444                                           PDFXProfiles.insert(nam, pfad + d[dc], false);
00445                                           InputProfilesCMYK.insert(nam, pfad + d[dc], false);
00446                                           PrinterProfiles.insert(nam, pfad + d[dc], false);
00447                                    }
00448                                    break;
00449                             }
00450                             cmsCloseProfile(hIn);
00451                             hIn = NULL;
00452                             if (showInfo)
00453                                    sDebug( QString("ICC profile %1 loaded from %2").arg(nam).arg(pfad + d[dc]) );
00454                      }
00455               }
00456               cmsSetErrorHandler(NULL);
00457        }
00458 }
00459 
00460 void ScribusCore::initCMS()
00461 {
00462        if (m_HaveCMS)
00463        {
00464               ProfilesL::Iterator ip;
00465               if ((prefsManager->appPrefs.DCMSset.DefaultImageRGBProfile.isEmpty()) || (!InputProfiles.contains(prefsManager->appPrefs.DCMSset.DefaultImageRGBProfile)))
00466               {
00467                      ip = InputProfiles.begin();
00468                      prefsManager->appPrefs.DCMSset.DefaultImageRGBProfile = ip.key();
00469               }
00470               if ((prefsManager->appPrefs.DCMSset.DefaultImageCMYKProfile.isEmpty()) || (!InputProfilesCMYK.contains(prefsManager->appPrefs.DCMSset.DefaultImageCMYKProfile)))
00471               {
00472                      ip = InputProfilesCMYK.begin();
00473                      prefsManager->appPrefs.DCMSset.DefaultImageCMYKProfile = ip.key();
00474               }
00475               if ((prefsManager->appPrefs.DCMSset.DefaultSolidColorRGBProfile.isEmpty()) || (!InputProfiles.contains(prefsManager->appPrefs.DCMSset.DefaultSolidColorRGBProfile)))
00476               {
00477                      ip = InputProfiles.begin();
00478                      prefsManager->appPrefs.DCMSset.DefaultSolidColorRGBProfile = ip.key();
00479               }
00480               if ((prefsManager->appPrefs.DCMSset.DefaultSolidColorCMYKProfile.isEmpty()) || (!InputProfilesCMYK.contains(prefsManager->appPrefs.DCMSset.DefaultSolidColorCMYKProfile)))
00481               {
00482                      ip = InputProfilesCMYK.begin();
00483                      prefsManager->appPrefs.DCMSset.DefaultSolidColorCMYKProfile = ip.key();
00484               }
00485               if ((prefsManager->appPrefs.DCMSset.DefaultMonitorProfile.isEmpty()) || (!MonitorProfiles.contains(prefsManager->appPrefs.DCMSset.DefaultMonitorProfile)))
00486               {
00487                      ip = MonitorProfiles.begin();
00488                      prefsManager->appPrefs.DCMSset.DefaultMonitorProfile = ip.key();
00489               }
00490               if ((prefsManager->appPrefs.DCMSset.DefaultPrinterProfile.isEmpty()) || (!PrinterProfiles.contains(prefsManager->appPrefs.DCMSset.DefaultPrinterProfile)))
00491               {
00492                      ip = PrinterProfiles.begin();
00493                      prefsManager->appPrefs.DCMSset.DefaultPrinterProfile = ip.key();
00494               }
00495        }
00496 }
00497 
00498 ScribusMainWindow * ScribusCore::primaryMainWindow( )
00499 {
00500        if (ScMWList.count()==0 || m_currScMW>ScMWList.count())
00501               return 0;
00502        ScribusMainWindow* mw=ScMWList.at(m_currScMW);
00503        if (!mw)
00504               return 0;
00505        return mw;
00506 }
00507 
00508 void ScribusCore::recheckGS()
00509 {
00510        m_HaveGS = testGSAvailability();
00511        m_HavePngAlpha = testGSDeviceAvailability("pngalpha");
00512        m_HaveTiffSep = testGSDeviceAvailability("tiffsep");
00513 }
00514 
00515 bool ScribusCore::fileWatcherActive() const
00516 {
00517        if (fileWatcher!=NULL)
00518               return fileWatcher->isActive();
00519        return false;
00520 }