Back to index

scribus-ng  1.3.4.dfsg+svn20071115
fontprefs.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 #include "fontprefs.h"
00008 #include "fontprefs.moc"
00009 #include <qhbox.h>
00010 #include <qfile.h>
00011 #include <qfileinfo.h>
00012 #include <qfiledialog.h>
00013 #include <qlabel.h>
00014 #include <qcursor.h>
00015 
00016 #include "prefscontext.h"
00017 #include "prefsfile.h"
00018 #include "sccombobox.h"
00019 #include "scribuscore.h"
00020 #include "scribusdoc.h"
00021 #include "prefsmanager.h"
00022 #include "scconfig.h"
00023 #include "colorutil.h"
00024 #include "util.h"
00025 #include "scpaths.h"
00026 
00027 extern QPixmap loadIcon(QString nam);
00028 
00029 
00030 FontPrefs::FontPrefs( QWidget* parent, bool Hdoc, QString PPath, ScribusDoc* doc ) : QTabWidget( parent, "fpre" )
00031 {
00032        RList = PrefsManager::instance()->appPrefs.GFontSub;
00033        HomeP = PPath;
00034        DocAvail = Hdoc;
00035        UsedFonts.clear();
00036        CurrentPath = "";
00037        docc = doc;
00038        setMinimumSize(fontMetrics().width( tr( "Available Fonts" )+ tr( "Font Substitutions" )+ tr( "Additional Paths" ))+180, 200);
00039        tab1 = new QWidget( this, "tab1" );
00040        tab1Layout = new QVBoxLayout( tab1, 0, 5, "tab1Layout");
00041        fontList = new QListView(tab1, "fontList" );
00042        fontList->setAllColumnsShowFocus(true);
00043        fontList->setShowSortIndicator(true);
00044        fontList->addColumn( tr("Font Name", "font preview"));
00045        fontList->addColumn( tr("Use Font", "font preview"));
00046        fontList->setColumnAlignment(1, Qt::AlignCenter);
00047        fontList->addColumn( tr("Embed in PostScript", "font preview"));
00048        fontList->setColumnAlignment(2, Qt::AlignCenter);
00049        fontList->addColumn( tr("Subset", "font preview"));
00050        fontList->setColumnAlignment(3, Qt::AlignCenter);
00051        fontList->addColumn( tr("Path to Font File", "font preview"));
00052        ttfFont = loadIcon("font_truetype16.png");
00053        otfFont = loadIcon("font_otf16.png");
00054        psFont = loadIcon("font_type1_16.png");
00055        substFont = loadIcon("font_subst16.png");
00056 
00057        checkOn = getQCheckBoxPixmap(true, fontList->paletteBackgroundColor());
00058        checkOff = getQCheckBoxPixmap(false, fontList->paletteBackgroundColor());
00059 
00060        tab1Layout->addWidget( fontList );
00061        insertTab( tab1, tr( "&Available Fonts" ) );
00062 
00063        tab = new QWidget( this, "tab" );
00064        tabLayout = new QVBoxLayout( tab, 10, 5, "tabLayout");
00065        Table3 = new QTable( tab, "Repl" );
00066        Table3->setSorting(false);
00067        Table3->setSelectionMode(QTable::SingleRow);
00068        Table3->setLeftMargin(0);
00069        Table3->verticalHeader()->hide();
00070        Table3->setNumCols( 2 );
00071        Table3->setNumRows(PrefsManager::instance()->appPrefs.GFontSub.count());
00072        Header2 = Table3->horizontalHeader();
00073        Header2->setLabel(0, tr("Font Name"));
00074        Header2->setLabel(1, tr("Replacement"));
00075 //     int a = 0;
00076 //     QMap<QString,QString>::Iterator itfsu;
00077 //     for (itfsu = RList.begin(); itfsu != RList.end(); ++itfsu)
00078 //     {
00079 //            Table3->setText(a, 0, itfsu.key());
00080 //            ScComboBox *item = new ScComboBox( true, this, "Replace" );
00081 //            item->setEditable(false);
00082 //            item->insertStringList(UsedFonts);
00083 //            item->setCurrentText(itfsu.data());
00084 //            Table3->setCellWidget(a, 1, item);
00085 //            FlagsRepl.append(item);
00086 //            a++;
00087 //     }
00088        Table3->setColumnStretchable(0, true);
00089        Table3->setColumnStretchable(1, true);
00090        Table3->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
00091        tabLayout->addWidget( Table3 );
00092        Layout2a = new QHBoxLayout( 0, 0, 5, "Layout2");
00093        QSpacerItem* spacer1 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
00094        Layout2a->addItem( spacer1 );
00095        DelB = new QPushButton( tr( "&Delete" ), tab, "DelB" );
00096        DelB->setEnabled(false);
00097        Layout2a->addWidget( DelB );
00098        QSpacerItem* spacer2 = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
00099        Layout2a->addItem( spacer2 );
00100        tabLayout->addLayout( Layout2a );
00101        insertTab( tab, tr( "Font &Substitutions" ) );
00102 
00103        tab3 = new QWidget( this, "tab3" );
00104        tab3Layout = new QHBoxLayout( tab3, 10, 5, "tab3Layout");
00105        // If we're being called for global application preferences, not document
00106        // preferences, we let the user customize font search paths. Because things
00107        // go rather badly if paths are changed/removed while a doc is open, the
00108        // control is also not displayed if there is a document open.
00109        if (!DocAvail && !ScCore->primaryMainWindow()->HaveDoc)
00110        {
00111               PathList = new QListBox( tab3, "PathList" );
00112               readPaths();
00113               PathList->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
00114               tab3Layout->addWidget( PathList );
00115               LayoutR = new QVBoxLayout( 0, 0, 5, "LayoutR");
00116               ChangeB = new QPushButton( tr( "C&hange..." ), tab3, "ChangeB" );
00117               LayoutR->addWidget( ChangeB );
00118               AddB = new QPushButton( tr( "A&dd..." ), tab3, "AddB" );
00119               LayoutR->addWidget( AddB );
00120               RemoveB = new QPushButton( tr( "&Remove" ), tab3, "RemoveB" );
00121               LayoutR->addWidget( RemoveB );
00122               QSpacerItem* spacer_2 = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
00123               LayoutR->addItem( spacer_2 );
00124               tab3Layout->addLayout( LayoutR );
00125               ChangeB->setEnabled(false);
00126               RemoveB->setEnabled(false);
00127               connect(PathList, SIGNAL(highlighted(QListBoxItem*)), this, SLOT(SelectPath(QListBoxItem*)));
00128               connect(AddB, SIGNAL(clicked()), this, SLOT(AddPath()));
00129               connect(ChangeB, SIGNAL(clicked()), this, SLOT(ChangePath()));
00130               connect(RemoveB, SIGNAL(clicked()), this, SLOT(DelPath()));
00131        }
00132        else
00133        {
00134               // Rather than just making the tab vanish when editing doc-specific settings
00135               // (we don't support per-doc font paths), show a useful explanation.
00136               QLabel *whyBlankLabel = new QLabel("<qt>" +
00137                             tr("Font search paths can only be set in File > Preferences, and only when "
00138                                "there is no document currently open. Close any open documents, then "
00139                                "use File > Preferences > Fonts to change the font search path.") + "</qt>",
00140                             tab3, "whyBlankLabel");
00141               tab3Layout->addWidget( whyBlankLabel );
00142        }
00143        insertTab( tab3, tr( "Additional &Paths" ) );
00144 
00145        // signals and slots connections
00146        connect(Table3, SIGNAL(currentChanged(int, int)), this, SLOT(ReplaceSel(int, int)));
00147        connect(DelB, SIGNAL(clicked()), this, SLOT(DelEntry()));
00148        connect(fontList, SIGNAL(clicked(QListViewItem *, const QPoint &, int)),
00149                      this, SLOT(slotClick(QListViewItem*, const QPoint &, int)));
00150 }
00151 
00152 void FontPrefs::restoreDefaults()
00153 {
00154        rebuildDialog();
00155 }
00156 
00157 void FontPrefs::slotClick(QListViewItem* ite, const QPoint &, int col)
00158 {
00159        if (ite == NULL || ite == 0)
00160               return;
00161        QString tmp = ite->text(0);
00162        if ((col == 1) && (!DocAvail))
00163        {
00164               fontFlags[tmp].FlagUse = !fontFlags[tmp].FlagUse;
00165               if (fontFlags[tmp].FlagUse)
00166                      ite->setPixmap(1, checkOn);
00167               else
00168                      ite->setPixmap(1, checkOff);
00169        }
00170        if (col == 2)
00171        {
00172               fontFlags[tmp].FlagPS = !fontFlags[tmp].FlagPS;
00173               if (fontFlags[tmp].FlagPS)
00174                      ite->setPixmap(2, checkOn);
00175               else
00176                      ite->setPixmap(2, checkOff);
00177        }
00178        if ((col == 3) && (!fontFlags[tmp].FlagOTF) && (fontFlags[tmp].FlagNames))
00179        {
00180               fontFlags[tmp].FlagSub = !fontFlags[tmp].FlagSub;
00181               if (fontFlags[tmp].FlagSub)
00182                      ite->setPixmap(3, checkOn);
00183               else
00184                      ite->setPixmap(3, checkOff);
00185        }
00186        UpdateFliste();
00187 }
00188 
00189 void FontPrefs::ReplaceSel(int, int)
00190 {
00191        DelB->setEnabled(true);
00192 }
00193 
00194 void FontPrefs::UpdateFliste()
00195 {
00196        QString tmp;
00197        UsedFonts.clear();
00198        SCFontsIterator it(PrefsManager::instance()->appPrefs.AvailFonts);
00199        for ( ; it.hasNext() ; it.next())
00200        {
00201               if (fontFlags[it.currentKey()].FlagUse)
00202                      UsedFonts.append(it.currentKey());
00203        }
00204        UsedFonts.sort();
00205        for (uint b = 0; b < FlagsRepl.count(); ++b)
00206        {
00207               tmp = FlagsRepl.at(b)->currentText();
00208               FlagsRepl.at(b)->clear();
00209               FlagsRepl.at(b)->insertStringList(UsedFonts);
00210               if (UsedFonts.contains(tmp) != 0)
00211                      FlagsRepl.at(b)->setCurrentText(tmp);
00212               else
00213                      FlagsRepl.at(b)->setCurrentItem(0);
00214        }
00215 }
00216 
00217 void FontPrefs::DelEntry()
00218 {
00219        int r = Table3->currentRow();
00220        QString tmp = Table3->text(r, 0);
00221        Table3->removeRow(r);
00222        FlagsRepl.remove(r);
00223        RList.remove(tmp);
00224 }
00225 
00226 void FontPrefs::readPaths()
00227 {
00228        Q_ASSERT(!DocAvail); // should never be called in doc-specific prefs
00229        PrefsContext *fontPrefsContext = PrefsManager::instance()->prefsFile->getContext("Fonts");
00230        PrefsTable *fontPathTable = fontPrefsContext->getTable("ExtraFontDirs");
00231        PathList->clear();
00232        for (int i = 0; i < fontPathTable->getRowCount(); ++i)
00233               PathList->insertItem( QDir::convertSeparators(fontPathTable->get(i,0)) );
00234 }
00235 
00236 void FontPrefs::writePaths()
00237 {
00238        Q_ASSERT(!DocAvail); // should never be called in doc-specific prefs
00239        PrefsContext *fontPrefsContext = PrefsManager::instance()->prefsFile->getContext("Fonts");
00240        PrefsTable *fontPathTable = fontPrefsContext->getTable("ExtraFontDirs");
00241        fontPathTable->clear();
00242        for (uint i = 0; i < PathList->count(); ++i)
00243               fontPathTable->set(i, 0, ScPaths::separatorsToSlashes(PathList->text(i)) );
00244 }
00245 
00246 void FontPrefs::SelectPath(QListBoxItem *c)
00247 {
00248        if (!DocAvail)
00249        {
00250               ChangeB->setEnabled(true);
00251               RemoveB->setEnabled(true);
00252        }
00253        CurrentPath = c->text();
00254 }
00255 
00256 void FontPrefs::AddPath()
00257 {
00258        Q_ASSERT(!DocAvail); // should never be called in doc-specific prefs
00259        PrefsContext* dirs = PrefsManager::instance()->prefsFile->getContext("dirs");
00260        CurrentPath = dirs->get("fontprefs", ".");
00261        QString s = QFileDialog::getExistingDirectory(CurrentPath, this, "d", tr("Choose a Directory"), true);
00262        if (!s.isEmpty())
00263        {
00264               dirs->set("fontprefs", s.left(s.findRev("/", -2)));
00265               if( s.endsWith("/") )
00266                      s = s.left(s.length()-1);
00267               QString s2 = QDir::convertSeparators(s);
00268               if (PathList->findItem(s2))
00269                      return;
00270               PathList->insertItem(s2);
00271               writePaths();
00272               ChangeB->setEnabled(true);
00273               RemoveB->setEnabled(true);
00274               CurrentPath = s;
00275               rebuildDialog();
00276        }
00277 }
00278 
00279 void FontPrefs::ChangePath()
00280 {
00281        Q_ASSERT(!DocAvail); // should never be called in doc-specific prefs
00282        QString s = QFileDialog::getExistingDirectory(CurrentPath, this, "d", tr("Choose a Directory"), true);
00283        if (!s.isEmpty())
00284        {
00285               if( s.endsWith("/") )
00286                      s = s.left(s.length()-1);
00287               QString s2 = QDir::convertSeparators(s);
00288               if (PathList->findItem(s2))
00289                      return;
00290               PathList->changeItem(s2, PathList->currentItem());
00291               writePaths();
00292               CurrentPath = s;
00293               rebuildDialog();
00294               ChangeB->setEnabled(true);
00295               RemoveB->setEnabled(true);
00296        }
00297 }
00298 
00299 void FontPrefs::DelPath()
00300 {
00301        Q_ASSERT(!DocAvail); // should never be called in doc-specific prefs
00302        QFile fx(HomeP+"/scribusfont13.rc");
00303        if (fx.open(IO_WriteOnly))
00304        {
00305               if (PathList->count() == 1)
00306                      PathList->clear();
00307               else
00308                      PathList->removeItem(PathList->currentItem());
00309               writePaths();
00310        }
00311        else
00312               return;
00313        CurrentPath = "";
00314        rebuildDialog();
00315        bool setter = PathList->count() > 0 ? true : false;
00316        ChangeB->setEnabled(setter);
00317        RemoveB->setEnabled(setter);
00318 }
00319 
00320 void FontPrefs::rebuildDialog()
00321 {
00322        SCFonts* availFonts=&(PrefsManager::instance()->appPrefs.AvailFonts);
00323 
00324        /*
00325        DON'T REMOVE THIS COMMENTS, PLEASE! (Petr)
00326        It's just a performance vs. functionality test.
00327        availFonts->clear();
00328        // FIXME: This is main preformance issue. It's about 90% of all preference reads! - PV
00329        availFonts->GetFonts(HomeP); */
00330        /* Are you wondering why this condition? See the comment at
00331        line #102 (or somewhere near) as reference. Hint: PathList
00332        is not initialized for example... - PV */
00333        if (!DocAvail && !ScCore->primaryMainWindow()->HaveDoc)
00334        {
00335               for (uint a = 0; a < PathList->count(); ++a)
00336               {
00337                      QString dir = ScPaths::separatorsToSlashes(PathList->text(a));
00338                      availFonts->AddScalableFonts(dir +"/"); //, docc->DocName);
00339                      availFonts->updateFontMap();
00340               }
00341        }
00342        UsedFonts.clear();
00343        fontFlags.clear();
00344        fontList->clear();
00345        SCFontsIterator it(*availFonts);
00346        for ( ; it.hasNext(); it.next())
00347        {
00348               if (it.current().isNone())
00349                      continue;
00350               fontSet foS;
00351               QListViewItem *row = new QListViewItem(fontList);
00352               row->setText(0, it.currentKey());
00353 
00354               foS.FlagUse = it.current().usable();
00355               row->setPixmap(1, foS.FlagUse ? checkOn : checkOff);
00356               if (foS.FlagUse)
00357                      UsedFonts.append(it.currentKey());
00358 
00359               foS.FlagPS = it.current().embedPs();
00360               row->setPixmap(2, foS.FlagPS ? checkOn : checkOff);
00361 
00362               foS.FlagSub = it.current().subset();
00363               row->setPixmap(3, foS.FlagSub ? checkOn : checkOff);
00364 
00365               ScFace::FontType type = it.current().type();
00366               foS.FlagOTF = (type == ScFace::OTF) ? true : false;
00367               if (it.current().isReplacement())
00368                      row->setPixmap(0, substFont);
00369               else if (type == ScFace::TYPE1)
00370                      row->setPixmap(0, psFont);
00371               else if (type == ScFace::TTF)
00372                      row->setPixmap(0, ttfFont);
00373               else if (type == ScFace::OTF)
00374                      row->setPixmap(0, otfFont);
00375 
00376               foS.FlagNames = it.current().hasNames();
00377               row->setText(4, it.current().fontPath());
00378               fontFlags.insert(it.currentKey(), foS);
00379        }
00380        fontList->sort();
00381        UsedFonts.sort();
00382        FlagsRepl.clear();
00383        int a = 0;
00384        QMap<QString,QString>::Iterator itfsu;
00385        for (itfsu = RList.begin(); itfsu != RList.end(); ++itfsu)
00386        {
00387               Table3->setText(a, 0, itfsu.key());
00388               ScComboBox *item = new ScComboBox( true, this, "Replace" );
00389               item->setEditable(false);
00390               item->insertStringList(UsedFonts);
00391               item->setCurrentText(itfsu.data());
00392               Table3->setCellWidget(a, 1, item);
00393               FlagsRepl.append(item);
00394               a++;
00395        }
00396        UpdateFliste();
00397 }