//--------------------------------------------------------------------- // Ipe preference settings //--------------------------------------------------------------------- /* This file is part of the extensible drawing editor Ipe. Copyright (C) 1993-2004 Otfried Cheong Ipe 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. As a special exception, you have permission to link Ipe with the CGAL library and distribute executables, as long as you follow the requirements of the Gnu General Public License in regard to all of the software in the executable aside from CGAL. Ipe 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 Ipe; if not, you can find it at "http://www.gnu.org/copyleft/gpl.html", or write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ipexml.h" #include "ipeq.h" #include "ipeprefs.h" #if defined(WIN32) #include #endif #include #include #include // -------------------------------------------------------------------- /*! \class IpePreferences \brief The configurable settings of the Ipe program. There are compile-time defaults, which can be overridden by environment variables. The compression levels are saved to $HOME/.iperc (on Unix) or $HOME/_ipecfg (on Windows). The interesting data members are all public. */ #ifdef WIN32 #define SEP ';' #else #define SEP ':' #endif const char * const stdFontMap[] = { "Times-Roman", "Times-Italic", "Times-Bold", "Times-BoldItalic", "Helvetica", "Helvetica-Oblique", "Helvetica-Bold", "Helvetica-BoldOblique", "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique", "Symbol", "ZapfDingbats", }; const int ConfigFileRevisionLevel = 18; IpePreferences *IpePreferences::This = 0; //! Return a pointer to the unique IpePreferences instance. IpePreferences *IpePreferences::Static() { if (!This) { This = new IpePreferences; } return This; } //! Constructor sets up preferences. /*! Preferences are read from the preferences file ($HOME/.iperc on Unix, $HOME/_ipecfg on Windows). If the file doesn't exist or is not readable, built-in defaults are used. The directory settings are computed from the location of the executable on Windows, and taken from compile-time settings on Unix. In both cases, environment variables override these settings. */ IpePreferences::IpePreferences() { // First set compile-time defaults iCompressLevel = 9; iSelectDistance = 36; iSnapDistance = 16; iRightMouseSelects = true; iWhitePaper = false; iBigToolButtons = false; iTransformable = true; iAntiAlias = true; iGridVisible = true; iMaximize = false; iMedia = IpeVector(595, 842); // A4 iGridSize = 16; iStyleSheet = QString::null; iStyleSheet2 = QString::null; iLanguage = QString::null; iMikTeX = false; QDir home = QDir::home(); #ifdef WIN32 char exename[OFS_MAXPATHNAME]; GetModuleFileNameA(0, exename, OFS_MAXPATHNAME); QFileInfo finfo = QFileInfo(QString(exename)); QDir ipedir = finfo.dir(true); iBinDir = ipedir.path(); ipedir.cdUp(); iDocDir = ipedir.filePath("doc"); iFontmap = ipedir.filePath("data/fontmap.xml"); iLangDir = ipedir.filePath("languages"); iIpeletPath = ipedir.filePath("ipelets"); iLatexDir = ipedir.filePath("latexrun"); #else iBinDir = IPEBINDIR; QDir ipedir = home.filePath(".ipe"); if (!ipedir.exists()) home.mkdir(".ipe"); iLatexDir = ipedir.filePath("latexrun"); iDocDir = IPEDOCDIR; iFontmap = IPEFONTMAP; iBrowser = IPEBROWSER; iIpeletPath.append(IPELETPATH); iLangDir = IPELANGDIR; #endif iPdfLatex = "pdflatex"; const char *p; p = getenv("IPELATEXDIR"); if (p) iLatexDir = p; p = getenv("IPEPDFLATEX"); if (p) iPdfLatex = p; p = getenv("IPEBINDIR"); if (p) iBinDir = p; p = getenv("IPEDOCDIR"); if (p) iDocDir = p; p = getenv("IPELANGDIR"); if (p) iLangDir = p; p = getenv("IPEFONTMAP"); if (p) iFontmap = p; p = getenv("IPEBROWSER"); if (p) iBrowser = p; p = getenv("IPELETPATH"); if (p) iIpeletPath = QStringList::split(QChar(SEP), p); p = getenv("TEXINPUTS"); if (p) iTexInputs = p; #ifdef WIN32 iPrefsFileName = home.filePath("_ipecfg"); iKeysFileName = home.filePath("_ipekeys.qm"); #else iPrefsFileName = ipedir.filePath("iperc"); iKeysFileName = ipedir.filePath("ipekeys.qm"); #endif iDialogDir = QDir::current().path(); QFile file(iPrefsFileName); if (!file.open(IO_ReadOnly)) return; QDataStream ds(&file); int revLevel; ds >> revLevel; if (revLevel != ConfigFileRevisionLevel) return; Q_INT8 flag; ds >> iCompressLevel; ds >> iSelectDistance; ds >> iSnapDistance; ds >> flag; iWhitePaper = !!flag; ds >> flag; iBigToolButtons = !!flag; ds >> flag; iTransformable = !!flag; ds >> flag; iAntiAlias = !!flag; ds >> flag; iGridVisible = !!flag; ds >> flag; iMaximize = !!flag; ds >> iMedia.iX >> iMedia.iY; ds >> iGridSize; ds >> iStyleSheet; ds >> iFont; ds >> iTextFont; ds >> iLanguage; ds >> flag; iMikTeX = !!flag; FindStandardFonts(); } //! Save preferences to preferences file. bool IpePreferences::Save() { QFile file(iPrefsFileName); if (!file.open(IO_WriteOnly)) return false; QDataStream ds(&file); ds << ConfigFileRevisionLevel << iCompressLevel << iSelectDistance << iSnapDistance << Q_INT8(iWhitePaper) << Q_INT8(iBigToolButtons) << Q_INT8(iTransformable) << Q_INT8(iAntiAlias) << Q_INT8(iGridVisible) << Q_INT8(iMaximize) << iMedia.iX << iMedia.iY << iGridSize << iStyleSheet << iFont << iTextFont << iLanguage << Q_INT8(iMikTeX); file.close(); emit Changed(); return true; } // -------------------------------------------------------------------- class FontmapParser : public IpeXmlParser { public: explicit FontmapParser(IpeDataSource &source) : IpeXmlParser(source) { /* nothing */ } bool ParseFontmap(); QString iGlyphs[14]; }; // Parse a fontmap. bool FontmapParser::ParseFontmap() { IpeXmlAttributes att; IpeString tag = ParseToTag(); if (tag == "?xml") { if (!ParseAttributes(att, true)) return false; tag = ParseToTag(); } if (tag != "fontmap") return false; if (!ParseAttributes(att)) return false; tag = ParseToTag(); while (tag == "font") { if (!ParseAttributes(att)) return false; if (att["format"] == "type1") { IpeString name = att["name"]; IpeString glyphs = att["glyphs"]; int i = 0; while (i < 14 && name != IpeString(stdFontMap[i])) ++i; if (i < 14) iGlyphs[i] = QIpe(glyphs); } tag = ParseToTag(); } if (tag != "/fontmap") return false; return true; } // -------------------------------------------------------------------- //! Parse the fontmap and store absolute paths for standard fonts. void IpePreferences::FindStandardFonts() { QFile file(iFontmap); QDir dir = QFileInfo(file).dir(); if (!file.open(IO_ReadOnly)) { qDebug("Could not open fontmap '%s'", iFontmap.latin1()); return; } XmlQSource source(&file); FontmapParser parser(source); if (parser.ParseFontmap()) { for (int i = 0; i < 14; ++i) { if (parser.iGlyphs[i] != QString::null) { QString fname = dir.absFilePath(parser.iGlyphs[i]); if (QFile::exists(fname)) iStandardFont[i] = fname; } } } file.close(); for (int i = 0; i < 14; ++i) { if (iStandardFont[i] == QString::null) { qDebug("No font file found for '%s'", stdFontMap[i]); } else { ipeDebug("Standard font '%s' uses font file '%s", stdFontMap[i], iStandardFont[i].latin1()); } } } //! Return contents of font file for standard font \a name. IpeBuffer IpePreferences::StandardFont(IpeString name) { for (int i = 0; i < 14; ++i) { if (name == stdFontMap[i]) { // if it's known and not yet loaded, load it if (iStandardFont[i] != QString::null && iStandardFontBuffer[i].size() == 0) { QFile file(iStandardFont[i]); if (file.open(IO_ReadOnly)) { QByteArray a = file.readAll(); file.close(); iStandardFontBuffer[i] = IpeBuffer(a.data(), a.size()); } } return iStandardFontBuffer[i]; } } return IpeBuffer(); } // --------------------------------------------------------------------