1 /***************************************************************************
2  *   Copyright (C) 2007 by Pierre Marchand   *
3  *   pierre@oep-h.com   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 
21 
22 
23 #include "aboutwidget.h"
24 #include "browserwidget.h"
25 #include "dataexport.h"
26 #include "dataloader.h"
27 #include "dumpdialog.h"
28 #include "floatingwidget.h"
29 #include "floatingwidgetsregister.h"
30 #include "fmactivate.h"
31 #include "fmfontdb.h"
32 #include "fmfontextract.h"
33 #include "fmmatchraster.h"
34 #include "fmlayout.h"
35 #include "fmpaths.h"
36 #include "fmrepair.h"
37 #include "fontbook.h"
38 #include "fontcomparewidget.h"
39 #include "fontitem.h"
40 // #include "helpwidget.h"
41 #include "helpbrowser.h"
42 #include "hyphenate/fmhyphenator.h"
43 #include "importedfontsdialog.h"
44 #include "importtags.h"
45 //#include "listdockwidget.h"
46 #include "mainviewwidget.h"
47 #include "panosedialog.h"
48 #include "panosewidget.h"
49 #include "playwidget.h"
50 #include "prefspaneldialog.h"
51 #include "remotedir.h"
52 //#include "savedata.h"
53 #include "shortcuts.h"
54 #include "systray.h"
55 #include "tagswidget.h"
56 #include "tttableview.h"
57 #include "typotek.h"
58 #include "winutils.h"
59 
60 #include <QDesktopWidget>
61 #include <QtGui>
62 #include <QTextEdit>
63 #include <QTextStream>
64 #include <QCloseEvent>
65 #include <QFileDialog>
66 #include <QDir>
67 #include <QProgressDialog>
68 #include <QProgressBar>
69 #include <QDomDocument>
70 #include <QProcess>
71 #include <QDockWidget>
72 #include <QStackedWidget>
73 #include <QMessageBox>
74 
75 #ifdef HAVE_FONTCONFIG
76 #include <fontconfig/fontconfig.h>
77 #endif
78 
79 
80 #ifdef HAVE_PYTHONQT
81 #include "fmpython_w.h"
82 #include "fmscriptconsole.h"
83 #define MAX_RECENT_PYSCRIPTS 10
84 #endif // HAVE_PYTHONQT
85 
86 #ifdef Q_WS_MAC
87 #include <ApplicationServices/ApplicationServices.h>
88 #endif
89 
90 typotek* typotek::instance = 0;
91 bool typotek::matrix = false;
92 QString typotek::fonteditorPath = "/usr/bin/fontforge";
93 extern bool __FM_SHOW_FONTLOADED;
94 extern int fm_num_face_opened;
95 
96 
97 /// LazyInit *********************************************
run()98 void LazyInit::run()
99 {
100 	/// We keep this for further needs
101 	emit endOfRun();
102 }
103 ///******************************************************
104 
105 /// a bit of globalness *******************************************
106 namespace fontmatrix
107 {
exploreDirs(const QDir & dir,int deep)108 	QStringList exploreDirs ( const QDir &dir, int deep )
109 	{
110 		static QStringList retDirList;
111 		if ( deep > 10 )
112 			return QStringList();
113 		if ( deep == 0 )
114 			retDirList.clear();
115 		retDirList << dir.absolutePath();
116 		QStringList localEntries ( dir.entryList ( QDir::AllDirs | QDir::NoDotAndDotDot ) );
117 		foreach ( QString dirEntry, localEntries )
118 		{
119 // 			qDebug() << "[exploreDirs] - " + dir.absolutePath() + "/" + dirEntry;
120 			QDir d ( dir.absolutePath() + "/" + dirEntry );
121 			exploreDirs ( d, deep + 1 );
122 			if ( !retDirList.contains ( d.absolutePath() ) )
123 				retDirList << d.absolutePath();
124 		}
125 
126 		return retDirList;
127 	}
128 
129 
130 	QMap<QString , Qt::DockWidgetArea> DockPosition;
131 
fillDockPos()132 	void fillDockPos()
133 	{
134 		DockPosition["Float"] = Qt::LeftDockWidgetArea;
135 		DockPosition["Left"] = Qt::LeftDockWidgetArea;
136 		DockPosition["Right"]= Qt::RightDockWidgetArea;
137 		DockPosition["Top"]= Qt::TopDockWidgetArea;
138 		DockPosition["Bottom"]= Qt::BottomDockWidgetArea;
139 	}
140 }
141 
142 /// *****************************************************
143 
getInstance()144 typotek * typotek::getInstance()
145 {
146 	if(!instance)
147 	{
148 		instance = new typotek;
149 		Q_ASSERT(instance);
150 	}
151 	return instance;
152 }
153 
typotek()154 typotek::typotek()
155 {
156 	setWindowTitle ( "Fontmatrix" );
157 	setupDrop();
158 	theMainView = 0;
159 	hyphenator = 0;
160 	theHelp = 0;
161 	dataLoader = 0;
162 	playVisible = false;
163 
164 	m_dpiX = ( double ) QApplication::desktop()->physicalDpiX();
165 	m_dpiY = ( double ) QApplication::desktop()->physicalDpiY();
166 #ifdef Q_WS_MAC
167 	CGDirectDisplayID macDId = CGMainDisplayID();
168 	CGRect macDRect = CGDisplayBounds(macDId);
169 	CGSize macDSize = CGDisplayScreenSize(macDId);
170 
171 	double macDisplayPxWidth(macDRect.size.width);
172 	double macDisplayPxHeight(macDRect.size.height);
173 	double macDisplayPhysicalWidth(double(macDSize.width) / 25.4);
174 	double macDisplayPhysicalHeight(double(macDSize.height) / 25.4);
175 
176 	m_dpiX = macDisplayPxWidth / macDisplayPhysicalWidth;
177 	m_dpiY = macDisplayPxHeight / macDisplayPhysicalHeight;
178 #endif
179 
180 	qDebug()<< m_dpiX << m_dpiY;
181 }
182 
initMatrix()183 void typotek::initMatrix()
184 {
185 	qDebug()<<"Main Thread:"<<thread();
186 	if(matrix)
187 		return;
188 	matrix = true;
189 	fontmatrix::fillDockPos();
190 
191 	checkOwnDir();
192 	readSettings();
193 	initDir();
194 
195 
196 	theMainView = new MainViewWidget ( this );
197 	theBrowser = new BrowserWidget(this);
198 	mainStack = new QStackedWidget(this);
199 
200 	mainStack->addWidget(theMainView);
201 	mainStack->addWidget(theBrowser);
202 	setCentralWidget ( mainStack );
203 
204 	if ( QSystemTrayIcon::isSystemTrayAvailable() )
205 		systray = new Systray();
206 	else
207 		systray = 0;
208 
209 	setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::ForceTabbedDocks);
210 
211 //	installDock("Main", tr ( "Browse Fonts" ), ListDockWidget::getInstance() , tr ( "Show/hide fonts browsing sidebar" ));
212 //	installDock("Tags", tr ( "Tags" ), TagsWidget::getInstance() ,  tr ( "Show/hide tags list sidebar" ) );
213 //	installDock("Panose", tr ( "Panose"), PanoseWidget::getInstance(), tr ( "Browse fonts by means of Panose attributes" ) );
214 
215 	// force tabifyication
216 //	QStringList dl;
217 //	dl << "Tags" << "Panose" << "Main";
218 //	for(int i(1); i < dl.count(); ++i)
219 //	{
220 //		if(dockArea[dl[i]] != "Float")
221 //		{
222 //			for(int j(i-1); j >=0 ; --j)
223 //			{
224 //				if(dockArea[dl[j]] == dockArea[dl[i]])
225 //					tabifyDockWidget(dockWidget[dl[j]], dockWidget[dl[i]]);
226 //			}
227 //		}
228 //	}
229 
230 	createActions();
231 	createMenus();
232 	createStatusBar();
233 	doConnect();
234 
235 	showToltalFilteredFonts();
236 
237 	if(!hyphenator)
238 	{
239 		QSettings st;
240 		QString dP( st.value("Sample/HyphenationDict", "hyph.dic").toString() );
241 		if(QFileInfo(dP).exists())
242 		{
243 			hyphenator = new FMHyphenator();
244 			if (!hyphenator->loadDict(dP, st.value("Sample/HyphLeft", 2).toInt(), st.value("Sample/HyphRight", 3).toInt())) {
245 				st.setValue("Sample/HyphenationDict", "");
246 				st.setValue("Sample/HyphLeft", 2);
247 				st.setValue("Sample/HyphRight", 3);
248 			}
249 		}
250 		else
251 		{
252 			hyphenator = new FMHyphenator(); // init the hyphenator anyway for the prefs
253 			st.setValue("Sample/HyphenationDict", "");
254 			st.setValue("Sample/HyphLeft", 2);
255 			st.setValue("Sample/HyphRight", 3);
256 			qDebug()<<"Err H"<<dP;
257 		}
258 	}
259 }
260 
installDock(const QString & id,const QString & name,QWidget * w,const QString & tip)261 void typotek::installDock(const QString& id, const QString& name, QWidget * w, const QString& tip)
262 {
263 	QDockWidget * dw = new QDockWidget(name);
264 	dw->setObjectName(id);
265 	dockWidget[id] = dw;
266 	dw->setWidget( w );
267 	dw->setStatusTip ( tip );
268 	addDockWidget(fontmatrix::DockPosition[dockArea[id]], dw);
269 	qDebug()<<"I"<<id<<dockArea[id]<<dockVisible[id];
270 	if(dockArea[id] == QString("Float"))
271 		dw->setFloating(true);
272 	if(!dockGeometry[id].isNull())
273 		dw->setGeometry(dockGeometry[id]);
274 
275 	connect(dw , SIGNAL(dockLocationChanged( Qt::DockWidgetArea )),
276 		this, SLOT(slotDockAreaChanged(Qt::DockWidgetArea )));
277 }
278 
postInit()279 void typotek::postInit()
280 {
281 	// TODO restore last filter
282 //	theMainView->slotViewAll();
283 
284 	QSettings st;
285 	QString cname(st.value("CurrentFont", QString()).toString());
286 //	if(!cname.isEmpty())
287 //	{
288 //		if(!ListDockWidget::getInstance()->fontTree->slotSetCurrent(cname))
289 //			theMainView->displayWelcomeMessage();
290 //	}
291 //	else
292 //		theMainView->displayWelcomeMessage();
293 }
294 
doConnect()295 void typotek::doConnect()
296 {
297 	if(getSystray())
298 		connect ( FMActivate::getInstance() ,SIGNAL ( activationEvent ( const QStringList& ) ), getSystray(),SLOT ( updateTagMenu ( const QStringList& ) ) );
299 
300 //	connect(FMLayout::getLayout()->optionDialog,SIGNAL(finished( int )),this,SLOT(slotUpdateLayOptStatus()));
301 #ifdef HAVE_PYTHONQT
302 	connect(FMScriptConsole::getInstance(),SIGNAL(finished()), this, SLOT(slotUpdateScriptConsoleStatus()));
303 #endif
304 	connect(toggleMainViewButton, SIGNAL(toggled(bool)), this, SLOT(toggleMainView(bool)));
305 }
306 
closeEvent(QCloseEvent * event)307 void typotek::closeEvent ( QCloseEvent *event )
308 {
309 	QSettings settings ;
310 	if ( systray )
311 	{
312 		if ( systray->isVisible() && settings.value ( "Systray/CloseToTray", true ).toBool() )
313 		{
314 			if ( !settings.value ( "Systray/CloseNoteShown", false ).toBool() )
315 			{
316 				QMessageBox::information ( this, tr ( "Fontmatrix" ),
317 				                           tr ( "The program will keep running in the "
318 				                                "system tray. To terminate the program, "
319 				                                "choose <b>Exit</b> in the context menu "
320 				                                "of the system tray entry." ) );
321 				settings.setValue ( "Systray/CloseNoteShown", true );
322 			}
323 			hide();
324 			event->ignore();
325 			return;
326 		}
327 	}
328 
329 	foreach(FloatingWidget *f, FloatingWidgetsRegister::AllWidgets())
330 	{
331 		f->close();
332 	}
333 	writeSettings();
334 
335 	delete PlayWidget::getInstance();
336 	delete FontCompareWidget::getInstance();
337 	delete theMainView;
338 
339 	event->accept();
340 
341 }
342 
343 /// IMPORT
344 // if announce == true user will be shown a dialog of imported fonts
345 // if announce == false and collect == true all fonts imported will be
346 // collected and announced next time announce == true
open(QString path,bool recursive,bool announce,bool collect)347 void typotek::open ( QString path, bool recursive, bool announce, bool collect )
348 {
349 	static QStringList nameList;
350 	static QStringList tali; // tali gets reseted when announce = true then the shouldAskTali is also set to true
351 	static bool shouldAskTali = true; // initial tags is only asked once if collect == true
352 	QStringList pathList;
353 
354 	QFileInfo finfo ( path );
355 	if ( finfo.isDir() || path.isEmpty() ) // importing a directory
356 	{
357 		static QSettings settings;
358 		static QString dir = settings.value ( "Places/LastUsedFolder", QDir::homePath() ).toString(); // first time use the home path then remember the last used dir
359 		QDir d ( dir );
360 		if ( !d.exists() )
361 			dir = QDir::homePath();
362 
363 		QString tmpdir;
364 
365 		if ( !path.isEmpty() )
366 			tmpdir = path;
367 		else
368 			tmpdir = QFileDialog::getExistingDirectory ( this, tr ( "Add Directory" ), dir  ,  QFileDialog::ShowDirsOnly );
369 
370 		if ( tmpdir.isEmpty() )
371 			return; // user choose to cancel the import process
372 
373 		dir = tmpdir; // only set dir if importing wasn't cancelled
374 		settings.setValue ( "Places/LastUsedFolder", dir );
375 
376 
377 		QStringList dirList;
378 		if(recursive)
379 			dirList =  fontmatrix::exploreDirs ( dir,0 ) ;
380 		else
381 			dirList.append(dir);
382 		// 	qDebug() << dirList.join ( "\n" );
383 
384 		QStringList yetHereFonts;
385 // 		for(int i=0;i < fontMap.count() ; ++i)
386 // 			yetHereFonts << fontMap[i]->path();
387 		yetHereFonts = FMFontDb::DB()->AllFontNames();
388 
389 		QStringList filters;
390 		filters << "*.otf" << "*.pfb" << "*.ttf" << "*.ttc";
391 		foreach ( QString dr, dirList )
392 		{
393 			QDir d ( dr );
394 			QFileInfoList fil= d.entryInfoList ( filters );
395 			foreach ( QFileInfo fp, fil )
396 			{
397 				if ( ( !yetHereFonts.contains ( fp.absoluteFilePath() ) ) )
398 				{
399 					if ( fp.isSymLink() ) // #12232
400 					{
401 						QFileInfo fsym ( fp.symLinkTarget() );
402 						if ( ( !fsym.isSymLink() ) // hey, donnot try to fool us with nested symlinks :)
403 						        && ( fsym.exists() )
404 						        && ( !yetHereFonts.contains ( fsym.absoluteFilePath() ) ) )
405 							pathList <<  fsym.absoluteFilePath();
406 
407 					}
408 					else
409 						pathList <<  fp.absoluteFilePath();
410 				}
411 			}
412 		}
413 	}
414 	else if ( finfo.isFile() )
415 		pathList <<  finfo.absoluteFilePath();
416 
417 	// It can happen that you wrongly select a dir, it is time to let the user cancel the import.
418 	// I want it :) - pm
419 	if ( /*( pathList.count() > 1 )
420 		&&*/ ( QMessageBox::question ( this,
421 	                                     QString ( "Fontmatrix - %1" ).arg ( tr ( "Confirmation" ) ) ,
422 	                                     tr ( "Do you confirm you want to import %n font(s)?", "", pathList.count()),
423 	                                     QMessageBox::Yes | QMessageBox::No,
424 	                                     QMessageBox::No )
425 	             != QMessageBox::Yes ) )
426 	{
427 		return;
428 	}
429 
430 	/* Everybody say it’s useless...
431 		NO IT'S NOT. I'm a keen fan of this feature. Let's make it optional */
432 	QStringList tagsList ( FMFontDb::DB()->getTags() );
433 	if ( useInitialTags && shouldAskTali )
434 	{
435 		ImportTags imp ( this,tagsList );
436 		imp.exec();
437 		tali = imp.tags();
438 		shouldAskTali = false;
439 	}
440 
441 	QProgressDialog progress ( tr ( "Importing font files... " ), tr ( "cancel" ), 0, pathList.count(), this );
442 	bool showProgress = pathList.count() > 1;
443 	if ( showProgress ) // show progress bar only if there's more than one font
444 	{
445 		progress.setWindowModality ( Qt::WindowModal );
446 		progress.setAutoReset ( false );
447 		progress.setValue ( 0 );
448 		progress.show();
449 	}
450 	FMFontDb::DB()->TransactionBegin();
451 	QString importstring ( tr ( "Import" ) +  " %1" );
452 	FMFontDb *DB ( FMFontDb::DB() );
453 	QList<FontItem*> nf;
454 	for ( int i = 0 ; i < pathList.count(); ++i )
455 	{
456 		QString pathCur ( pathList.at ( i ) );
457 		if ( showProgress )
458 		{
459 			progress.setLabelText ( importstring.arg ( pathCur ) );
460 			progress.setValue ( i );
461 			if ( progress.wasCanceled() )
462 				break;
463 		}
464 
465 
466 
467 		{
468 			QFile ff ( pathCur );
469 			QFileInfo fi ( pathCur );
470 			{
471 				FontItem *fitem ( DB->Font ( fi.absoluteFilePath(), true ) );
472 				if ( fitem )
473 				{
474 					nf << fitem;
475 					fitem->setActivated ( false );
476 					if ( announce || collect )
477 						nameList << fitem->fancyName();
478 				}
479 				else
480 				{
481 					QString errorFont ( tr ( "Cannot import this font because it is broken:" ) +" "+fi.fileName() );
482 					statusBar()->showMessage ( errorFont );
483 					if ( announce || collect )
484 						nameList << "__FAILEDTOLOAD__" + fi.fileName();
485 				}
486 			}
487 		}
488 	}
489 
490 	QStringList tl;
491 	foreach ( QString tag, tali )
492 	{
493 		tl.clear();
494 		foreach ( FontItem* f, nf )
495 		{
496 			tl << f->path();
497 		}
498 		DB->addTag ( tl, tag );
499 	}
500 	DB->TransactionEnd();
501 	progress.close();
502 
503 	if ( announce )
504 	{
505 		if ( showFontListDialog )
506 		{
507 			// The User needs and deserves to know what fonts hve been imported
508 			ImportedFontsDialog ifd ( this, nameList );
509 			ifd.exec();
510 		}
511 		else   // show info in the statusbar
512 		{
513 			statusBar()->showMessage ( tr ( "Fonts imported: %1" ).arg ( nameList.count() ), 3000 );
514 		}
515 		nameList.clear();
516 		tali.clear();
517 		shouldAskTali = true;
518 	}
519 	emit newFontsArrived();
520 }
521 
importFiles()522 void typotek::importFiles()
523 {
524 	QStringList flist = QFileDialog::getOpenFileNames(this,
525 							  tr("Select Files to Import"),
526 							  QDir::homePath(),
527 							 QString("%1 (*.otf *.ttf *.ttc *.pfb)").arg(tr("Font Files")));
528 	if(!flist.isEmpty())
529 		openList(flist);
530 }
531 
532 /// Import files in a drop event.
openList(QStringList files)533 void typotek::openList ( QStringList files )
534 {
535 	QStringList pathList;
536 	QStringList nameList;
537 	QStringList tali;
538 	QStringList tagsList ( FMFontDb::DB()->getTags() );
539 	if ( useInitialTags )
540 	{
541 		ImportTags imp ( this,tagsList );
542 		imp.exec();
543 		tali = imp.tags();
544 	}
545 
546 	FMFontDb *DB ( FMFontDb::DB() );
547 	QStringList fontMap ( DB->AllFontNames() );
548 	foreach ( QString file, files )
549 	{
550 		QFileInfo fp ( file );
551 		if ( ( !fontMap.contains ( fp.absoluteFilePath() ) ) )
552 		{
553 			if ( fp.isSymLink() ) // #12232
554 			{
555 				QFileInfo fsym ( fp.symLinkTarget() );
556 				if ( ( !fsym.isSymLink() )
557 				        && ( fsym.exists() )
558 				        && ( !fontMap.contains ( fsym.absoluteFilePath() ) ) )
559 					pathList <<  fsym.absoluteFilePath();
560 
561 			}
562 			else
563 				pathList <<  fp.absoluteFilePath();
564 		}
565 	}
566 
567 	DB->TransactionBegin();
568 	QProgressDialog progress ( tr ( "Importing font files... " ),tr ( "cancel" ), 0, pathList.count(), this );
569 	progress.setWindowModality ( Qt::WindowModal );
570 	progress.setAutoReset ( false );
571 
572 	QList<FontItem*> nf;
573 	QString importstring ( tr ( "Import" ) +" %1" );
574 	for ( int i = 0 ; i < pathList.count(); ++i )
575 	{
576 		progress.setLabelText ( importstring.arg ( pathList.at ( i ) ) );
577 		progress.setValue ( i );
578 		if ( progress.wasCanceled() )
579 			break;
580 
581 		QFile ff ( pathList.at ( i ) );
582 		QFileInfo fi ( pathList.at ( i ) );
583 
584 		FontItem *fitem = DB->Font ( fi.absoluteFilePath() ,true );
585 		if ( fitem )
586 		{
587 			nf << fitem;
588 			nameList << fitem->fancyName();
589 		}
590 		else
591 		{
592 			QString errorFont ( tr ( "Cannot import this font because it is broken: " ) +" "+fi.fileName() );
593 //			statusBar()->showMessage ( errorFont );
594 			nameList << "__FAILEDTOLOAD__" + fi.fileName();
595 		}
596 	}
597 	QStringList tl;
598 	foreach ( QString tag, tali )
599 	{
600 		tl.clear();
601 		foreach ( FontItem* f, nf )
602 		{
603 			tl << f->path();
604 		}
605 		DB->addTag ( tl, tag );
606 	}
607 	DB->TransactionEnd();
608 	progress.close();
609 
610 	// The User needs and deserves to know what fonts hve been imported
611 	if ( showFontListDialog )
612 	{
613 		// The User needs and deserves to know what fonts hve been imported
614 		ImportedFontsDialog ifd ( this, nameList );
615 		ifd.exec();
616 	}
617 	else   // show info in the statusbar
618 	{
619 		statusBar()->showMessage ( tr ( "Fonts imported: %1" ).arg ( nameList.count() ), 3000 );
620 	}
621 	emit newFontsArrived();
622 
623 }
624 
625 /// EXPORT
slotExportFontSet()626 void typotek::slotExportFontSet()
627 {
628 //	QStringList tagsList(FMFontDb::DB()->getTags());
629 //	QStringList items ( tagsList );
630 //	bool ok;
631 //	QString item = QInputDialog::getItem ( this, tr ( "Fontmatrix Tags" ),
632 //	                                       tr ( "Choose the tag for filter exported fonts" ), items, 0, false, &ok );
633 //	if ( ok && !item.isEmpty() )
634 //	{
635 
636 
637 //		QString dir( QDir::homePath() );
638 //		dir = QFileDialog::getExistingDirectory ( this, tr ( "Choose Directory" ), dir  ,  QFileDialog::ShowDirsOnly );
639 //		if ( dir.isEmpty() )
640 //			return;
641 
642 //		DataExport dx(dir,item);
643 //		dx.doExport();
644 //	}
645 	new DataExport(this);
646 }
647 
648 
about()649 void typotek::about()
650 {
651 	AboutWidget aabout(this);
652 	aabout.exec();
653 }
654 
createActions()655 void typotek::createActions()
656 {
657 	Shortcuts *scuts = Shortcuts::getInstance();
658 
659 	openAct = new QAction ( QIcon ( ":/fontmatrix_import_icon" ), tr ( "&Import Directory..." ), this );
660 	openAct->setShortcut ( Qt::CTRL + Qt::Key_O );
661 	openAct->setToolTip( tr ( "Import a directory" ) );
662 	scuts->add(openAct);
663 	connect ( openAct, SIGNAL ( triggered() ), this, SLOT ( open() ) );
664 
665 	importFilesAction = new QAction(QIcon ( ":/fontmatrix_import_icon" ), tr ( "Import &Files..." ), this );
666 	importFilesAction->setShortcut( Qt::CTRL + Qt::SHIFT + Qt::Key_O );
667 	importFilesAction->setToolTip(tr("Import Files"));
668 	scuts->add(importFilesAction);
669 	connect(importFilesAction, SIGNAL(triggered()), this, SLOT(importFiles()));
670 
671 	exportFontSetAct = new QAction(tr("Export &fonts"),this);
672 	exportFontSetAct->setStatusTip(tr("Export a fontset"));
673 	scuts->add(exportFontSetAct);
674 	connect( exportFontSetAct,SIGNAL(triggered( )),this,SLOT(slotExportFontSet()));
675 
676 
677 	fontBookAct = new QAction ( QIcon ( ":/fontmatrix_fontbookexport_icon.png" ), tr ( "Export font book..." ),this );
678 	fontBookAct->setStatusTip ( tr ( "Export a PDF document that shows selected fonts" ) );
679 	scuts->add(fontBookAct);
680 	connect ( fontBookAct, SIGNAL ( triggered() ), this, SLOT ( fontBook() ) );
681 
682 	dumpInfoAct = new QAction(tr("Export font info for packaging..."), this);
683 	dumpInfoAct->setStatusTip ( tr ( "Fill a template file with metadata for packaging currently selected font to a Linux distribution" ) );
684 	connect(dumpInfoAct, SIGNAL(triggered()), this, SLOT(slotDumpInfo()));
685 
686 	exitAct = new QAction ( tr ( "E&xit" ), this );
687 	exitAct->setShortcut ( Qt::CTRL + Qt::Key_Q );
688 	exitAct->setStatusTip ( tr ( "Exit the application" ) );
689         exitAct->setMenuRole(QAction::QuitRole);
690 	scuts->add(exitAct);
691 	connect ( exitAct, SIGNAL ( triggered() ), this, SLOT ( close() ) );
692 
693 
694 	aboutAct = new QAction ( tr ( "&About" ), this );
695 	aboutAct->setStatusTip ( tr ( "Show information about Fontmatrix" ) );
696         aboutAct->setMenuRole(QAction::AboutRole);
697 	scuts->add(aboutAct);
698 	connect ( aboutAct, SIGNAL ( triggered() ), this, SLOT ( about() ) );
699 
700 	aboutQtAct = new QAction ( tr ( "About &Qt" ), this );
701 	aboutQtAct->setStatusTip ( tr ( "Show information about Qt" ) );
702         aboutQtAct->setMenuRole(QAction::AboutQtRole);
703 	scuts->add(aboutQtAct);
704 	connect (aboutQtAct,SIGNAL(triggered()), QApplication::instance(),SLOT(aboutQt()));
705 
706 	helpAct = new QAction ( tr ( "Help" ), this );
707 	helpAct->setShortcut ( Qt::Key_F1 );
708 	helpAct->setStatusTip ( tr ( "Read documentation on Fontmatrix" ) );
709 	helpAct->setCheckable(true);
710 	helpAct->setChecked(false);
711 	scuts->add(helpAct);
712 	connect ( helpAct,SIGNAL ( triggered( ) ),this,SLOT ( helpBegin() ) );
713 
714 // 	tagsetAct = new QAction ( tr ( "&Tag Sets" ),this );
715 // 	tagsetAct->setIcon ( QIcon ( ":/fontmatrix_tagseteditor_icon.png" ) );
716 // 	scuts->add(tagsetAct);
717 // 	connect ( tagsetAct,SIGNAL ( triggered( ) ),this,SLOT ( popupTagsetEditor() ) );
718 
719 	activCurAct = new QAction ( tr ( "Activate all current" ),this );
720 	activCurAct->setStatusTip ( tr ( "Activate all currently visible fonts" ) );
721 	scuts->add(activCurAct);
722 	connect ( activCurAct,SIGNAL ( triggered( ) ),this,SLOT ( slotActivateCurrents() ) );
723 
724 	deactivCurAct = new QAction ( tr ( "Deactivate all current" ),this );
725 	deactivCurAct->setStatusTip ( tr ( "Deactivate all currently visible fonts" ) );
726 	scuts->add(deactivCurAct);
727 	connect ( deactivCurAct,SIGNAL ( triggered( ) ),this,SLOT ( slotDeactivateCurrents() ) );
728 
729 	fonteditorAct = new QAction ( tr ( "Edit current font" ),this );
730 	scuts->add(fonteditorAct);
731 	connect ( fonteditorAct,SIGNAL ( triggered( ) ),this,SLOT ( slotEditFont() ) );
732 	if ( QFile::exists ( fonteditorPath ) )
733 	{
734 		fonteditorAct->setStatusTip ( tr ( "Edit currently selected font in a font editor of your choice" ) );
735 	}
736 	else
737 	{
738 		fonteditorAct->setEnabled ( false );
739 		fonteditorAct->setStatusTip ( tr ( "You don't seem to have a font editor installed. Path to font editor can be set in Preferences dialog." ) );
740 	}
741 
742 	reloadAct = new QAction( tr ("Reload Filtered"), this );
743 	reloadAct->setStatusTip(tr ("Reload informations for filtered fonts from the font files they belong to"));
744 	scuts->add(reloadAct);
745 	connect(reloadAct, SIGNAL(triggered()), this, SLOT(slotReloadFiltered()));
746 
747 	reloadSingleAct = new QAction(tr("Reload Selected"), this);
748 	reloadSingleAct->setStatusTip(tr ("Reload informations for selected font from the font file"));
749 	scuts->add(reloadSingleAct);
750 	connect(reloadSingleAct, SIGNAL(triggered()), this, SLOT(slotReloadSingle()));
751 
752 	prefsAct = new QAction ( tr ( "Preferences" ),this );
753 	prefsAct->setStatusTip ( tr ( "Setup Fontmatrix" ) );
754         prefsAct->setMenuRole(QAction::PreferencesRole);
755 	scuts->add(prefsAct);
756 	connect ( prefsAct,SIGNAL ( triggered() ),this,SLOT ( slotPrefsPanelDefault() ) );
757 
758 	repairAct = new QAction ( tr("Check Database"), this);
759 	repairAct->setStatusTip ( tr ( "Check Fontmatrix database for dead links to font files" ) );
760 	scuts->add(repairAct);
761 	connect( repairAct, SIGNAL ( triggered() ),this,SLOT (slotRepair()));
762 
763 //	if ( systray )
764 //		connect ( theMainView, SIGNAL ( newTag ( QString ) ), systray, SLOT ( newTag ( QString ) ) );
765 
766 	tagAll = new QAction(tr("Tag All Filtered..."), this);
767 	tagAll->setStatusTip ( tr ( "Tag all currently visible files" ) );
768 	scuts->add(tagAll);
769 	connect(tagAll,SIGNAL(triggered()),this,SLOT(slotTagAll()));
770 
771 	showTTTAct = new QAction(tr("Show TrueType tables"),this);
772 	showTTTAct->setStatusTip ( tr ( "View hexadecimal values of TrueType tables for currently selected font file" ) );
773 	scuts->add(showTTTAct);
774 	connect(showTTTAct,SIGNAL(triggered( )),this,SLOT(slotShowTTTables()));
775 
776 	editPanoseAct = new QAction(tr("Edit PANOSE metadata"), this);
777 	editPanoseAct->setStatusTip ( tr ( "Edit PANOSE metadata without saving changes to font files" ) );
778 	scuts->add(editPanoseAct);
779 	connect(editPanoseAct, SIGNAL(triggered()), this, SLOT(slotEditPanose()));
780 
781 
782 	playAction = new QAction(tr("Playground"), this);
783 	playAction->setShortcut(Qt::CTRL + Qt::Key_G);
784 	playAction->setToolTip(tr("Show/Hide Playground"));
785 	playAction->setCheckable(true);
786 	playAction->setChecked(false);
787 	scuts->add(playAction);
788 	connect(playAction, SIGNAL(triggered(bool)), PlayWidget::getInstance(), SLOT(setVisible(bool)));
789 
790 	compareAction = new QAction(tr("Compare"), this);
791 	compareAction->setShortcut(Qt::CTRL + Qt::Key_R);
792 	compareAction->setToolTip(tr("Show/Hide Compare glyphs"));
793 	compareAction->setCheckable(true);
794 	compareAction->setChecked(false);
795 	scuts->add(compareAction);
796 	connect(compareAction, SIGNAL(triggered(bool)), FontCompareWidget::getInstance(), SLOT(setVisible(bool)));
797 
798 	closeAllFloat = new QAction(tr("Close All"), this);
799 	closeAllFloat->setToolTip(tr("Close all floating windows"));
800 	scuts->add(closeAllFloat);
801 	connect(closeAllFloat, SIGNAL(triggered()), this, SLOT(closeAllFloatings()));
802 
803 	showAllFloat = new QAction(tr("Show All"), this);
804 	showAllFloat->setToolTip(tr("Show all floating windows"));
805 	scuts->add(showAllFloat);
806 	connect(showAllFloat, SIGNAL(triggered()), this, SLOT(showAllFloatings()));
807 
808 	hideAllFloat = new QAction(tr("Hide All"), this);
809 	hideAllFloat->setToolTip(tr("Hide all floating windows"));
810 	scuts->add(hideAllFloat);
811 	connect(hideAllFloat, SIGNAL(triggered()), this, SLOT(hideAllFloatings()));
812 
813 	floatSep = new QAction(this);
814 	floatSep->setSeparator(true);
815 
816 
817 	extractFontAction = new QAction(tr("Extract fonts..."),this);
818 	extractFontAction->setStatusTip ( tr ( "Extract fonts from documents like PDF to PFM file format" ) );
819 	scuts->add(extractFontAction);
820 	connect(extractFontAction,SIGNAL(triggered()),this,SLOT(slotExtractFont()));
821 
822 	matchRasterAct = new QAction(tr("Find a font using raster sample..."), this); // FIXME find a name for it
823 	matchRasterAct->setStatusTip ( tr ( "Find a font using a raster sample of a letter" ) );
824 	scuts->add(matchRasterAct);
825 	connect(matchRasterAct,SIGNAL(triggered()),this,SLOT(slotMatchRaster()));
826 
827 
828 #ifdef HAVE_PYTHONQT
829 	execScriptAct = new QAction(tr("Execute Script..."),this);
830 	execScriptAct->setStatusTip ( tr ( "Execute a Python script" ) );
831 	scuts->add(execScriptAct);
832 	connect(execScriptAct,SIGNAL(triggered()),this,SLOT(slotExecScript()));
833 
834 	execLastScriptAct = new QAction(tr("Execute Last Script"),this);
835 	execLastScriptAct->setStatusTip ( tr ( "Execute the last chosen Python script" ) );
836 	scuts->add(execLastScriptAct);
837 	connect(execLastScriptAct,SIGNAL(triggered()),this,SLOT(slotExecLastScript()));
838 
839 	scriptConsoleAct = new QAction(tr("Script Console..."), this);
840 	scriptConsoleAct->setStatusTip ( tr ( "Open Python scripting console" ) );
841 	scriptConsoleAct->setCheckable(true);
842 	scuts->add(scriptConsoleAct);
843 	connect(scriptConsoleAct, SIGNAL(triggered()), this, SLOT(slotSwitchScriptConsole()));
844 
845 #endif
846 }
847 
createMenus()848 void typotek::createMenus()
849 {
850 	fileMenu = menuBar()->addMenu ( tr ( "&File" ) );
851 
852 	fileMenu->addAction ( openAct );
853 	fileMenu->addAction ( importFilesAction );
854 	fileMenu->addAction ( exportFontSetAct );
855 	fileMenu->addSeparator();
856 
857 	fileMenu->addAction ( fontBookAct );
858 	fileMenu->addAction ( dumpInfoAct );
859 	fileMenu->addSeparator();
860 	fileMenu->addAction ( exitAct );
861 
862 	editMenu = menuBar()->addMenu ( tr ( "&Edit" ) );
863 // 	editMenu->addAction ( tagsetAct );
864 	editMenu->addSeparator();
865 	editMenu->addAction( tagAll );
866 	editMenu->addAction ( activCurAct );
867 	editMenu->addAction ( deactivCurAct );
868 	editMenu->addSeparator();
869 	editMenu->addAction ( fonteditorAct );
870 	editMenu->addAction ( editPanoseAct );
871 	editMenu->addSeparator();
872 	editMenu->addAction(reloadSingleAct);
873 	editMenu->addAction(reloadAct);
874 	editMenu->addSeparator();
875 	editMenu->addAction ( prefsAct );
876 
877 	viewMenu = menuBar()->addMenu(tr("&View"));
878 	viewMenu->addAction(playAction);
879 	viewMenu->addAction(compareAction);
880 	viewMenu->addSeparator();
881 	connect(viewMenu, SIGNAL(aboutToShow()), this,SLOT(updateFloatingStatus()));
882 
883 #ifdef HAVE_PYTHONQT
884 	scriptMenu = menuBar()->addMenu ( tr ( "&Scripts" ) );;
885 	scriptMenu->addAction(execScriptAct);
886 	scriptMenu->addAction(scriptConsoleAct);
887 	scriptMenu->addAction(execLastScriptAct);
888 #endif
889 
890 	servicesMenu =  menuBar()->addMenu ( tr ( "&Service" ) );
891 	servicesMenu->addAction(extractFontAction);
892 	servicesMenu->addAction(matchRasterAct);
893 #ifdef PLATFORM_APPLE
894 	// TODO
895 #elif _WIN32
896 	// TODO
897 #else
898 	servicesMenu->addAction( repairAct );
899 #endif
900 	servicesMenu->addAction(showTTTAct);
901 	servicesMenu->addSeparator();
902 //	servicesMenu->addAction(layOptAct);
903 
904 	helpMenu = menuBar()->addMenu ( tr ( "&Help" ) );
905 	helpMenu->addAction ( helpAct );
906 	helpMenu->addAction ( aboutAct );
907 	helpMenu->addAction ( aboutQtAct );
908 
909 }
910 
createStatusBar()911 void typotek::createStatusBar()
912 {
913 //	statusBar()->showMessage ( tr ( "Ready" ) );
914 
915 	statusProgressBar = new QProgressBar(this);
916 	statusProgressBar->setMaximumSize(200,20);
917 	statusBar()->addPermanentWidget(statusProgressBar);
918 	statusProgressBar->hide();
919 
920 	QFont statusFontFont ( "sans-serif", 10 );
921 	curFontPresentation = new QLabel ( "" );
922 	curFontPresentation->setFrameShape(QFrame::StyledPanel);
923 	curFontPresentation->setAlignment ( Qt::AlignRight );
924 	curFontPresentation->setFont ( statusFontFont );
925 	statusBar()->insertWidget ( 0, curFontPresentation );
926 
927 	countFilteredFonts = new QLabel ( "" );
928 	countFilteredFonts->setFrameShape(QFrame::StyledPanel);
929 	countFilteredFonts->setAlignment ( Qt::AlignRight );
930 	countFilteredFonts->setFont ( statusFontFont );
931 	statusBar()->addPermanentWidget ( countFilteredFonts );
932 
933 	toggleMainViewButton = new QToolButton(this);
934 	toggleMainViewButton->setText(tr("Browse Directories"));
935 	toggleMainViewButton->setCheckable(true);
936 	toggleMainViewButton->setToolTip(tr("Toggle Files/Collection view"));
937 	statusBar()->addPermanentWidget(toggleMainViewButton);
938 }
939 
readSettings()940 void typotek::readSettings()
941 {
942 	relayStartingStepIn(tr("Load settings"));
943 	QSettings settings;
944 	QPoint pos = settings.value ( "WState/pos", QPoint ( 200, 200 ) ).toPoint();
945 	QSize size = settings.value ( "WState/size", QSize ( 400, 400 ) ).toSize();
946 	resize ( size );
947 	move ( pos );
948 
949 	fonteditorPath = settings.value ( "FontEditor", "/usr/bin/fontforge" ).toString();
950 	useInitialTags = settings.value ( "UseInitialTags", false ).toBool();
951 	showFontListDialog = settings.value("ShowImportedFonts", true).toBool();
952 	previewSize = settings.value("Preview/Size", 28.0).toDouble();
953 	previewRTL = settings.value("Preview/RTL", false).toBool();
954 	previewSubtitled = settings.value("Preview/Subtitled", false).toBool();
955 	m_theWord = settings.value("Preview/Word", "<name>" ).toString();
956 
957 //	QStringList dl;
958 //	dl << "Main" << "Tags" << "Panose";
959 //	foreach(const QString & ds, dl)
960 //	{
961 //		dockArea[ds] =  settings.value("Docks/"+ds+"Pos", "Left").toString();
962 //		dockVisible[ds] = settings.value("Docks/"+ds+"Visible", true).toBool();
963 //		dockGeometry[ds] = settings.value("Docks/"+ds+"Geometry", QRect()).toRect();
964 //		qDebug()<<ds<< dockArea[ds] << dockVisible[ds] <<dockGeometry[ds];
965 //	}
966 
967 	panoseMatchTreshold = settings.value("Panose/MatchTreshold" , 1000 ).toInt();
968 
969 	webBrowser = settings.value("Info/Browser", "Fontmatrix").toString();
970 	webBrowserOptions = settings.value("Info/BrowserOptions", "").toString();
971 	previewInfoFontSize = settings.value("Info/PreviewSize", 20.0).toDouble();
972 
973 	infoStyle = settings.value("Info/Style", FMPaths::ResourcesDir() + "info.css").toString();
974 
975 	templatesDir = settings.value ( "Places/TemplatesDir", "./").toString();
976 	m_welcomeURL = settings.value("Places/WelcomeURL").toString();
977 	m_remoteTmpDir = settings.value("Places/RemoteTmpDir", QDir::tempPath()).toString();
978 
979 	defaultOTFScript = settings.value("OTF/Script").toString();
980 	defaultOTFLang = settings.value("OTF/Lang").toString();
981 	defaultOTFGPOS = settings.value("OTF/GPOS").toString().split(";",QString::SkipEmptyParts);
982 	defaultOTFGSUB = settings.value("OTF/GSUB").toString().split(";",QString::SkipEmptyParts);
983 	chartInfoFontSize = settings.value("ChartInfoFontSize", 8).toInt();
984 	chartInfoFontName = settings.value("ChartInfoFontFamily", QFont().family() ).toString();
985 
986 
987 	databaseDriver = settings.value("Database/Driver","QSQLITE").toString();
988 	databaseHostname = settings.value("Database/Hostname","").toString();
989 	databaseDbName = settings.value("Database/DbName", ownDir.absolutePath()+ QDir::separator() + "Data.sql").toString();
990 	databaseUser = settings.value("Database/User","").toString();
991 	databasePassword = settings.value("Database/Password","").toString();
992 	if( !QSqlDatabase::drivers().contains(databaseDriver) )
993 	{
994 		qDebug()<<"The SQL driver you request is not available("<< databaseDriver <<")";
995 	}
996 
997 }
998 
writeSettings()999 void typotek::writeSettings()
1000 {
1001 	QSettings settings;
1002 	settings.setValue( "WState/pos", pos() );
1003 	settings.setValue( "WState/size", size() );
1004 	theMainView->saveSplitterState();
1005 
1006 //	QStringList dl;
1007 //	dl << "Main" << "Tags" << "Panose";
1008 //	foreach(const QString & ds, dl)
1009 //	{
1010 //		if(dockWidget[ds]->isFloating())
1011 //		{
1012 //			dockArea[ds] = "Float";
1013 //		}
1014 //		settings.setValue( "Docks/"+ds+"Pos", dockArea[ds] );
1015 //		settings.setValue( "Docks/"+ds+"Visible", dockWidget[ds]->isVisible());
1016 //		settings.setValue( "Docks/"+ds+"Geometry", dockWidget[ds]->geometry());
1017 //	}
1018 
1019 
1020 	settings.setValue("Info/PreviewSize", previewInfoFontSize );
1021 	settings.setValue("Info/Style", infoStyle );
1022 
1023 	settings.setValue("Preview/Word", m_theWord);
1024 
1025 	settings.setValue( "Panose/MatchTreshold", panoseMatchTreshold);
1026 
1027 	settings.setValue( "Database/Driver",databaseDriver);
1028 	settings.setValue( "Database/Hostname",databaseHostname);
1029 	settings.setValue( "Database/DbName",databaseDbName);
1030 	settings.setValue( "Database/User",databaseUser);
1031 	settings.setValue( "Database/Password",databasePassword);
1032 
1033 	if(theMainView->selectedFont())
1034 		settings.setValue("CurrentFont", theMainView->selectedFont()->path());
1035 
1036 
1037 }
1038 
maybeSave()1039 bool typotek::maybeSave()
1040 {
1041 
1042 	return true;
1043 }
1044 
~typotek()1045 typotek::~typotek()
1046 {
1047 }
1048 
fillTagsList()1049 void typotek::fillTagsList()
1050 {
1051 
1052 }
1053 
checkOwnDir()1054 void typotek::checkOwnDir()
1055 {
1056 	relayStartingStepIn(tr("Check for Fontmatrix own dir"));
1057 	QString sep(QDir::separator());
1058 
1059 #ifdef PLATFORM_APPLE
1060 
1061 	QString rootDir(QDir::homePath() + sep + "Library" + sep + "Fontmatrix" + sep);
1062 	managedDir.setPath(QDir::homePath() + sep + "Library" + sep + "Fonts");
1063 	ownDir.setPath(rootDir);
1064 	if ( !managedDir.exists() )
1065 		managedDir.mkpath ( QDir::homePath() + sep + "Library" + sep + "Fonts" );
1066 	if(!ownDir.exists())
1067 		ownDir.mkpath (rootDir);
1068 
1069 	ResourceFile.setFileName ( rootDir + "Resource.xml" );
1070 
1071 #elif _WIN32
1072 	// For win we do not hide things because it does
1073 	// not work yet. So if you need to debug it will be simpler.
1074 	QString fontmanaged ( sep + "fontmatrix" );
1075 	managedDir.setPath ( QDir::homePath() + fontmanaged );
1076 	if ( !managedDir.exists() )
1077 		managedDir.mkpath ( QDir::homePath() + fontmanaged );
1078 	ownDir = managedDir;
1079 	ResourceFile.setFileName ( QDir::homePath() + sep +"fontmatrix.data" );
1080 #else
1081 	QString rootDir(QDir::homePath() + sep + ".Fontmatrix" + sep);
1082 	ownDir.setPath(rootDir);
1083 	// Where activated fonts are sym-linked
1084 	managedDir.setPath ( rootDir + "Activated" );
1085 	if ( !managedDir.exists() )
1086 		managedDir.mkpath ( rootDir + "Activated"  );
1087 
1088 	addFcDirItem( managedDir.absolutePath() );
1089 
1090 	ResourceFile.setFileName ( rootDir + "Resource.xml" );
1091 #endif
1092 }
1093 
addFcDirItem(const QString & dirPath)1094 void typotek::addFcDirItem(const QString & dirPath)
1095 {
1096 #ifdef HAVE_FONTCONFIG
1097 	QFile fcfile ( QDir::homePath() + "/.config/fontconfig/fonts.conf" );
1098 	if ( !fcfile.open ( QFile::ReadWrite ) )
1099 	{
1100 		return;
1101 	}
1102 	else
1103 	{
1104 		QDomDocument fc ( "fontconfig" );
1105 
1106 		// .fonts.conf is empty, it seems that we just created it.
1107 		// Wed have to populate it a bit
1108 		if ( fcfile.size() == 0 )
1109 		{
1110 			QString ds ( "<?xml version='1.0'?><!DOCTYPE fontconfig SYSTEM 'fonts.dtd'><fontconfig></fontconfig>" );
1111 			fc.setContent ( ds );
1112 		}
1113 		else
1114 		{
1115 			fc.setContent ( &fcfile );
1116 		}
1117 
1118 		bool isconfigured = false;
1119 		QDomNodeList dirlist = fc.elementsByTagName ( "dir" );
1120 		for ( int i=0;i < dirlist.count();++i )
1121 		{
1122 			if ( dirlist.at ( i ).toElement().text() == dirPath )
1123 				isconfigured = true;
1124 		}
1125 		if ( !isconfigured )
1126 		{
1127 			QDomElement root = fc.documentElement();
1128 			QDomElement direlem = fc.createElement ( "dir" );
1129 			QDomText textelem = fc.createTextNode ( dirPath );
1130 			direlem.appendChild ( textelem );
1131 			root.appendChild ( direlem );
1132 			fcfile.resize ( 0 );
1133 
1134 			QTextStream ts ( &fcfile );
1135 			fc.save ( ts,4 );
1136 
1137 		}
1138 		fcfile.close();
1139 	}
1140 #endif
1141 }
1142 
getSystemFontDirs()1143 QStringList typotek::getSystemFontDirs()
1144 {
1145 	QStringList retList;
1146 #ifdef HAVE_FONTCONFIG // For Unices (OSX excluded)
1147 	QStringList tmpList;
1148 	FcConfig* FcInitLoadConfig();
1149 	FcStrList *sysDirList = FcConfigGetFontDirs(0);
1150 	QString sysDir( (char*)FcStrListNext(sysDirList) );
1151 	while(!sysDir.isEmpty())
1152 	{
1153 		if(!sysDir.contains("Fontmatrix"))
1154 		{
1155 			tmpList << sysDir;
1156 		}
1157 		sysDir = ( (char*)FcStrListNext(sysDirList) );
1158 	}
1159 	// Because we will go recursivly through these directories, we just want to list the top most ones.
1160 	foreach(QString path, tmpList)
1161 	{
1162 // 		qDebug()<< "PATH"<<path;
1163 		bool root(true);
1164 		foreach(QString ref, tmpList)
1165 		{
1166 			if(path != ref)
1167 			{
1168 				if(path.startsWith(ref))
1169 				{
1170 					root = false;
1171 					break;
1172 				}
1173 // 				qDebug()<<"\tREF"<<ref<<root;
1174 			}
1175 		}
1176 		if(root)
1177 			retList << path;
1178 	}
1179 
1180 #endif //HAVE_FONTCONFIG
1181 #ifdef PLATFORM_APPLE
1182 	retList << "/Library/Fonts";
1183 	retList << "/System/Library/Fonts";
1184 #endif // PLATFORM_APPLE
1185 #if _WIN32
1186 	retList << getWin32SystemFontDir();
1187 #endif // _WIN32
1188 
1189 	qDebug()<<retList.join("\n");
1190 	return retList;
1191 }
1192 
isSysFont(FontItem * f)1193 bool typotek::isSysFont(FontItem * f)
1194 {
1195 	if(f)
1196 	{
1197 		if(sysFontList.contains(f->path()))
1198 			return true;
1199 	}
1200 	return false;
1201 }
1202 
initDir()1203 void typotek::initDir()
1204 {
1205 	/// let’s load system fonts
1206 #define SYSTEM_FONTS 1
1207 	if(SYSTEM_FONTS)
1208 	{
1209 		relayStartingStepIn ( tr ( "Loading System Fonts") );
1210 		m_sysTagName = tr ( "System Fonts" );
1211 		QStringList tagsList(FMFontDb::DB()->getTags());
1212 
1213 		QList<FontItem*> sysFontPtrs;
1214 
1215 		QStringList sysDir ( getSystemFontDirs() );
1216 
1217 		QStringList yetHereFonts;
1218 		QList<FontItem*> fontMap(FMFontDb::DB()->AllFonts());
1219 		for ( int i=0;i < fontMap.count() ; ++i )
1220 			yetHereFonts << fontMap[i]->path();
1221 
1222 		for ( int sIdx ( 0 ); sIdx < sysDir.count(); ++sIdx )
1223 		{
1224 			QDir theDir ( sysDir[sIdx] );
1225 			QStringList syspathList;
1226 			QStringList nameList;
1227 
1228 			QStringList dirList ( fontmatrix::exploreDirs ( theDir,0 ) );
1229 			QStringList filters;
1230 			filters << "*.otf" << "*.pfb" << "*.ttf" << "*.ttc";
1231 			foreach ( QString dr, dirList )
1232 			{
1233 				QDir d ( dr );
1234 				QFileInfoList fil= d.entryInfoList ( filters );
1235 				foreach ( QFileInfo fp, fil )
1236 				{
1237 					if ( !yetHereFonts.contains ( fp.absoluteFilePath() ) )
1238 						syspathList <<  fp.absoluteFilePath();
1239 					sysFontList << fp.absoluteFilePath();
1240 				}
1241 			}
1242 
1243 			int sysFontCount ( syspathList.count() );
1244 			if(sysFontCount > 0)
1245 			{
1246 				relayStartingStepIn ( tr ( "Adding" ) +" "+ QString::number ( sysFontCount ) +" "+tr ( "fonts from","followed by a directory name" )  +" "+sysDir[sIdx]);
1247 				qDebug()<< ( tr ( "Adding" ) +" "+ QString::number ( sysFontCount ) +" "+tr ( "fonts from","followed by a directory name" )  +" "+sysDir[sIdx]);
1248 				FMFontDb::DB()->TransactionBegin();
1249 				for ( int i = 0 ; i < sysFontCount; ++i )
1250 				{
1251 					QFile ff ( syspathList.at ( i ) );
1252 					QFileInfo fi ( syspathList.at ( i ) );
1253 					{
1254 						FontItem *fitem = FMFontDb::DB()->Font( fi.absoluteFilePath(), false );
1255 						if ( fitem )
1256 						{
1257 // 							qDebug()<<"\t"<<fitem <<fitem->path();
1258 							fitem->setActivated ( true );
1259 // 							fitem->addTag ( m_sysTagName );
1260 							sysFontPtrs << fitem;
1261 						}
1262 						else
1263 						{
1264 							qDebug() << "Cannot open this font because its broken: " << fi.fileName() ;
1265 						}
1266 					}
1267 				}
1268 				FMFontDb::DB()->TransactionEnd();
1269 			}
1270 		}
1271 
1272 		if(sysFontPtrs.count() > 0)
1273 			relayStartingStepIn ( QString::number ( sysFontPtrs.count() ) + " " + tr ( "system fonts added." ) );
1274 
1275 		// So much complicated only because otherwise, tags were added twice with SQLite ???
1276 		QStringList tl;
1277 		foreach(FontItem* sfp, sysFontPtrs)
1278 		{
1279 			tl << sfp->path();
1280 		}
1281 		FMFontDb::DB()->addTag(tl, m_sysTagName);
1282 	}
1283 
1284 
1285 // 	qDebug()<<"TIME(fonts) : "<<fontsTime.elapsed();
1286 	/// Remote dirs
1287 	//TODO
1288 // 	QSettings settings;
1289 // 	QStringList remoteDirV ( settings.value ( "RemoteDirectories" ).toStringList() );
1290 // 	if ( !remoteDirV.isEmpty() )
1291 // 	{
1292 // 		relayStartingStepIn ( tr ( "Catching" ) +" "+ QString::number ( remoteDirV.count() ) +" "+tr ( "font descriptions from network" ) );
1293 // 		remoteDir = new RemoteDir ( remoteDirV );
1294 // 		connect ( remoteDir,SIGNAL ( listIsReady() ),this,SLOT ( slotRemoteIsReady() ) );
1295 // 		remoteDir->run();
1296 // 	}
1297 }
1298 
1299 static bool slotRemoteIsReadyRunOnce = false;
slotRemoteIsReady()1300 void typotek::slotRemoteIsReady()
1301 {
1302 	if(!slotRemoteIsReadyRunOnce)
1303 		slotRemoteIsReadyRunOnce = true;
1304 	else
1305 		return;
1306 	QStringList tagsList(FMFontDb::DB()->getTags());
1307 
1308 // 	qDebug()<<"typotek::slotRemoteIsReady()";
1309 	QList<RemoteDir::FontInfo> listInfo(remoteDir->rFonts());
1310 // 	qDebug()<< "Have got "<< listInfo.count() <<"remote font descriptions";
1311 	for(int rf(0) ;rf < listInfo.count(); ++rf)
1312 	{
1313 // 		qDebug()<< rf <<" : " <<listInfo[rf].dump();
1314 		FontItem *fi = new FontItem ( listInfo[rf].file , true );
1315 		if(!fi->isValid())
1316 		{
1317 			qDebug() << "ERROR loading : " << listInfo[rf].file;
1318 			continue;
1319 		}
1320 		fi->fileRemote(listInfo[rf].family,listInfo[rf].variant,listInfo[rf].type, listInfo[rf].info, listInfo[rf].pix);
1321 // 		fontMap.append ( fi );
1322 // 		realFontMap[fi->path() ] = fi;
1323 		fi->setTags ( listInfo[rf].tags );
1324 		foreach(QString tag, listInfo[rf].tags)
1325 		{
1326 			if(!tag.isEmpty() && !tagsList.contains(tag))
1327 			{
1328 				tagsList << tag;
1329 			}
1330 		}
1331 	}
1332 //	theMainView->slotReloadFontList();
1333 	showStatusMessage( QString::number(listInfo.count())+ " " +  tr("font descriptions imported from network"));
1334 // 	qDebug()<<"END OF slotRemoteIsReady()";
1335 }
1336 
1337 
fontBook()1338 void typotek::fontBook()
1339 {
1340 	FontBook fontbook;
1341 	fontbook.doBook(FontBook::Full);
1342 }
1343 
1344 
1345 
getSelectedFont()1346 FontItem * typotek::getSelectedFont()
1347 {
1348 	return theMainView->selectedFont();
1349 }
1350 
keyPressEvent(QKeyEvent * event)1351 void typotek::keyPressEvent ( QKeyEvent * event )
1352 {
1353 // 	qDebug() << "typotek::keyPressEvent(QKeyEvent * "<<event<<")";
1354 	if(/*event->modifiers().testFlag(Qt::ControlModifier) &&*/ event->key() == Qt::Key_J)
1355 		qDebug()<<"NUM FACES OPENED:"<<fm_num_face_opened;
1356 }
1357 
slotActivateCurrents()1358 void typotek::slotActivateCurrents()
1359 {
1360 	if ( QMessageBox::question ( this,tr ( "Fontmatrix care" ),tr ( "You are about to activate a bunch of fonts,\nit is time to cancel if it was not your intent" ), QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Ok )
1361 		theMainView->slotActivateAll();
1362 }
1363 
slotDeactivateCurrents()1364 void typotek::slotDeactivateCurrents()
1365 {
1366 	if ( QMessageBox::question ( this,tr ( "Fontmatrix care" ),tr ( "You are about to deactivate a bunch of fonts,\nit is time to cancel if it was not your intent" ),QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Ok )
1367 		theMainView->slotDesactivateAll();
1368 }
1369 
helpBegin()1370 void typotek::helpBegin()
1371 {
1372 	theHelp = new HelpBrowser(this,tr("Fontmatrix Help"));
1373 	helpAct->setChecked(true);
1374 
1375 	connect( theHelp, SIGNAL( closed() ), this, SLOT(helpEnd()) );
1376 
1377 	disconnect ( helpAct,SIGNAL ( triggered( ) ),this,SLOT ( helpBegin() ) );
1378 	connect ( helpAct,SIGNAL ( triggered( ) ),this,SLOT ( helpEnd() ) );
1379 
1380 	theHelp->show();
1381 }
1382 
helpEnd()1383 void typotek::helpEnd()
1384 {
1385 	helpAct->setChecked(false);
1386 
1387 	disconnect ( helpAct,SIGNAL ( triggered( ) ),this,SLOT ( helpEnd() ) );
1388 	connect ( helpAct,SIGNAL ( triggered( ) ),this,SLOT ( helpBegin() ) );
1389 
1390 	theHelp->deleteLater();
1391 }
1392 
slotEditFont()1393 void typotek::slotEditFont()
1394 {
1395 	FontItem *item = theMainView->selectedFont();
1396 	if ( !item )
1397 	{
1398 		statusBar()->showMessage ( tr ( "There is no font selected" ), 3000 );
1399 		return;
1400 	}
1401 
1402 	QStringList arguments;
1403 	arguments << "-nosplash" << item->path() ;
1404 
1405 	QProcess *myProcess = new QProcess ( this );
1406 	myProcess->start ( fonteditorPath, arguments );
1407 }
1408 
setupDrop()1409 void typotek::setupDrop()
1410 {
1411 	setAcceptDrops ( true );
1412 	// was pretty hard!
1413 }
1414 
dropEvent(QDropEvent * event)1415 void typotek::dropEvent ( QDropEvent * event )
1416 {
1417 
1418 	qDebug() << "typotek::dropEvent ("<< event->mimeData()->text() <<")";
1419 // 	qDebug()<<"F: "<<event->mimeData()->formats().join(";");
1420 
1421 // 	event->acceptProposedAction();
1422 	QStringList uris = event->mimeData()->text().split ( "\n" );
1423 	QStringList ret;
1424 
1425 	for ( int i = 0; i < uris.count() ; ++i )
1426 	{
1427 		qDebug() << "dropped uri["<< i <<"] -> "<< uris[i];
1428 		QUrl url ( uris[i].trimmed() );
1429 		qDebug() << "\tURL -> " << url.toLocalFile();
1430 		if ( url.scheme() == "file" )
1431 		{
1432 			if ( url.toLocalFile().endsWith ( "ttf",Qt::CaseInsensitive ) )
1433 			{
1434 				ret << url.toLocalFile();
1435 			}
1436 			else if ( url.toLocalFile().endsWith ( "ttc",Qt::CaseInsensitive ) )
1437 			{
1438 				ret << url.toLocalFile();
1439 			}
1440 			else if ( url.toLocalFile().endsWith ( "otf",Qt::CaseInsensitive ) )
1441 			{
1442 				ret << url.toLocalFile();
1443 			}
1444 			else if ( url.toLocalFile().endsWith ( "pfb",Qt::CaseInsensitive ) )
1445 			{
1446 				ret << url.toLocalFile();
1447 			}
1448 			else
1449 			{
1450 				qDebug() << url.toLocalFile ()  << "is not a supported font file";
1451 			}
1452 		}
1453 		else if ( url.scheme() == "http" )
1454 		{
1455 			// TODO Get fonts over http
1456 			qDebug() << "Support of DragNDrop over http is sheduled";
1457 			statusBar()->showMessage ( tr ( "Support of DragNDrop over http is sheduled but not yet effective" ), 3000 );
1458 		}
1459 		else
1460 		{
1461 			qDebug() << "Protocol not supported";
1462 		}
1463 	}
1464 
1465 // 	qDebug() << ret.join("||");
1466 	if ( ret.count() )
1467 		openList( ret );
1468 
1469 }
1470 
dragEnterEvent(QDragEnterEvent * event)1471 void typotek::dragEnterEvent ( QDragEnterEvent * event )
1472 {
1473 	qDebug() << event->mimeData()->formats().join ( "|" );
1474 	if ( event->mimeData()->hasFormat ( "text/uri-list" ) )
1475 	{
1476 		event->acceptProposedAction();
1477 		qDebug() << "dragEnterEvent accepted " ;
1478 	}
1479 	else
1480 	{
1481 		qDebug() << "dragEnterEvent refused";
1482 		statusBar()->showMessage ( tr ( "You bring something over me I can’t handle" ), 3000 );
1483 	}
1484 }
1485 
slotPrefsPanel(PrefsPanelDialog::PAGE page)1486 void typotek::slotPrefsPanel(PrefsPanelDialog::PAGE page)
1487 {
1488 	PrefsPanelDialog pp ( this );
1489 
1490 	// FIXME if Systray is not available, systray->whatever() will segault
1491 	if ( QSystemTrayIcon::isSystemTrayAvailable() )
1492 		pp.initSystrayPrefs ( QSystemTrayIcon::isSystemTrayAvailable(),
1493 		                      systray->isVisible(),
1494 		                      systray->hasActivateAll(),
1495 		                      systray->allConfirmation(),
1496 		                      systray->tagsConfirmation() );
1497 	else
1498 		pp.initSystrayPrefs ( false,false,false,false,false );
1499 	pp.initSampleTextPrefs();
1500 	pp.initFilesAndFolders();
1501 	pp.initShortcuts();
1502 	pp.showPage(page);
1503 	pp.exec();
1504 }
1505 
slotPrefsPanelDefault()1506 void typotek::slotPrefsPanelDefault()
1507 {
1508 	slotPrefsPanel(PrefsPanelDialog::PAGE_GENERAL);
1509 }
1510 
forwardUpdateView()1511 void typotek::forwardUpdateView()
1512 {
1513 //	theMainView->slotView ( true );
1514 }
1515 
setSystrayVisible(bool isVisible)1516 void typotek::setSystrayVisible ( bool isVisible )
1517 {
1518 	systray->slotSetVisible ( isVisible );
1519 }
1520 
showActivateAllSystray(bool isVisible)1521 void typotek::showActivateAllSystray ( bool isVisible )
1522 {
1523 	systray->slotSetActivateAll ( isVisible );
1524 }
1525 
systrayAllConfirmation(bool isEnabled)1526 void typotek::systrayAllConfirmation ( bool isEnabled )
1527 {
1528 	systray->requireAllConfirmation ( isEnabled );
1529 }
1530 
systrayTagsConfirmation(bool isEnabled)1531 void typotek::systrayTagsConfirmation ( bool isEnabled )
1532 {
1533 	systray->requireTagsConfirmation ( isEnabled );
1534 }
1535 
slotCloseToSystray(bool isEnabled)1536 void typotek::slotCloseToSystray ( bool isEnabled )
1537 {
1538 	QSettings settings ;
1539 	settings.setValue ( "Systray/CloseToTray", isEnabled );
1540 	settings.setValue ( "Systray/CloseNoteShown", false );
1541 }
1542 
slotSystrayStart(bool isEnabled)1543 void typotek::slotSystrayStart( bool isEnabled )
1544 {
1545 	QSettings settings ;
1546 	settings.setValue ( "Systray/StartToTray", isEnabled );
1547 }
1548 
1549 
namedSample(QString name)1550 QString typotek::namedSample ( QString name )
1551 {
1552 	QString cn(name);
1553 	if(cn == QString("NEW_SAMPLE"))
1554 		return tr("Edit me!");
1555 	if(cn.isEmpty())
1556 		cn = currentNamedSample;
1557 	else
1558 		currentNamedSample = cn;
1559 
1560 	if(!dataLoader)
1561 		dataLoader = new DataLoader();
1562 
1563 	const QMap<QString,QString>& us(dataLoader->userSamples());
1564 	foreach(const QString& k, us.keys())
1565 	{
1566 		QString id(QString("User::") + k);
1567 //		qDebug()<<"\t"<<id;
1568 		if(id == cn)
1569 		{
1570 			return us[k];
1571 		}
1572 	}
1573 
1574 	const QMap<QString, QMap<QString,QString> >& ss(dataLoader->systemSamples());
1575 	foreach(const QString& pk, ss.keys())
1576 	{
1577 		foreach(const QString& sk, ss[pk].keys())
1578 		{
1579 			QString id(pk + QString("::") + sk);
1580 //			qDebug()<<"\t"<<id;
1581 			if(id == cn)
1582 			{
1583 				return ss[pk][sk];
1584 			}
1585 		}
1586 	}
1587 	return namedSample(defaultSampleName());
1588 }
1589 
namedSamplesNames()1590 QMap<QString,QList<QString> > typotek::namedSamplesNames()
1591 {
1592 	if(!dataLoader)
1593 		dataLoader = new DataLoader();
1594 
1595 	QMap<QString,QList<QString> > ret;
1596 	const QMap<QString,QString>& us(dataLoader->userSamples());
1597 	const QMap<QString, QMap<QString,QString> >& ss(dataLoader->systemSamples());
1598 	foreach(const QString& key, ss.keys())
1599 	{
1600 		ret[key] << ss[key].keys();
1601 	}
1602 	ret[QString("User")] << us.keys();
1603 	return ret;
1604 }
1605 
addNamedSample(QString name,QString sample)1606 void typotek::addNamedSample ( QString name, QString sample )
1607 {
1608 	if(!dataLoader)
1609 		dataLoader = new DataLoader();
1610 
1611 	dataLoader->update(name, sample);
1612 //	theMainView->refillSampleList();
1613 }
1614 
removeNamedSample(const QString & key)1615 void typotek::removeNamedSample(const QString& key)
1616 {
1617 	if(!dataLoader)
1618 		dataLoader = new DataLoader();
1619 
1620 	dataLoader->remove(key);
1621 //	theMainView->refillSampleList();
1622 }
1623 
changeSample(QString name,QString text)1624 void typotek::changeSample ( QString name, QString text )
1625 {
1626 	if(!dataLoader)
1627 		dataLoader = new DataLoader();
1628 
1629 	dataLoader->update(name, text);
1630 //	theMainView->refillSampleList();
1631 }
1632 
defaultSampleName()1633 QString typotek::defaultSampleName()
1634 {
1635 	if(!dataLoader)
1636 		dataLoader = new DataLoader();
1637 
1638 	const QMap<QString,QString>& us(dataLoader->userSamples());
1639 	if(us.contains(tr("default")))
1640 		return QString("User::") + QString("default");
1641 	else if(us.count() > 0)
1642 		return QString("User::") + us.keys().first();
1643 	else
1644 	{
1645 		const QMap<QString, QMap<QString,QString> >& ss(dataLoader->systemSamples());
1646 		QString l(QLocale::system().language());
1647 		if((ss.contains(l)) && (ss[l].count() > 0))
1648 			return l + QString("::") + ss[l].keys().first();
1649 		else
1650 		{
1651 			foreach(QString k, ss.keys())
1652 			{
1653 				if(ss[k].count() > 0)
1654 					return k +  QString("::") +ss[k].keys().first();
1655 			}
1656 		}
1657 	}
1658 	return QString();
1659 }
1660 
setWord(QString s,bool updateView)1661 void typotek::setWord ( QString s, bool updateView )
1662 {
1663 	if(s == m_theWord)
1664 		return;
1665 	m_theWord = s;
1666 	QList<FontItem*> fontMap(FMFontDb::DB()->AllFonts());
1667 	for(int i(0); i < fontMap.count(); ++i)
1668 		fontMap[i]->clearPreview() ;
1669 
1670 	emit previewHasChanged();
1671 }
1672 
setPreviewSize(double d)1673 void typotek::setPreviewSize(double d)
1674 {
1675 	if(previewSize == d)
1676 		return;
1677 
1678 //	previewSize = d;
1679 //	if(previewSize != ListDockWidget::getInstance()->previewSize->value())
1680 //		ListDockWidget::getInstance()->previewSize->setValue(previewSize);
1681 	QList<FontItem*> fontMap(FMFontDb::DB()->AllFonts());
1682 	for(int i(0); i < fontMap.count(); ++i)
1683 		fontMap[i]->clearPreview() ;
1684 	emit previewHasChanged();
1685 }
1686 
setPreviewRTL(bool d)1687 void typotek::setPreviewRTL(bool d)
1688 {
1689 	if(previewRTL == d)
1690 		return;
1691 	previewRTL = d;
1692 	QList<FontItem*> fontMap(FMFontDb::DB()->AllFonts());
1693 	for(int i(0); i < fontMap.count(); ++i)
1694 		fontMap[i]->clearPreview() ;
1695 	emit previewHasChanged();
1696 }
1697 
setPreviewSubtitled(bool d)1698 void typotek::setPreviewSubtitled(bool d)
1699 {
1700 	if(previewSubtitled == d)
1701 		return;
1702 	previewSubtitled = d;
1703 	QList<FontItem*> fontMap(FMFontDb::DB()->AllFonts());
1704 	for(int i(0); i < fontMap.count(); ++i)
1705 		fontMap[i]->clearPreview() ;
1706 	emit previewHasChanged();
1707 }
1708 
setFontEditorPath(const QString & path)1709 void typotek::setFontEditorPath ( const QString &path )
1710 {
1711 	fonteditorPath = path;
1712 	if ( QFile::exists ( fonteditorPath ) )
1713 	{
1714 		fonteditorAct->setEnabled ( true );
1715 		fonteditorAct->setStatusTip ( tr ( "Try to run font editor with the selected font as argument" ) );
1716 	}
1717 	else
1718 	{
1719 		fonteditorAct->setEnabled ( false );
1720 		fonteditorAct->setStatusTip ( tr ( "You don't seem to have font editor installed. Path to font editor can be set in preferences." ) );
1721 	}
1722 	QSettings settings ;
1723 	settings.setValue ( "FontEditor", fonteditorPath );
1724 }
1725 
slotUseInitialTags(bool isEnabled)1726 void typotek::slotUseInitialTags ( bool isEnabled )
1727 {
1728 	useInitialTags = isEnabled;
1729 	QSettings settings ;
1730 	settings.setValue ( "UseInitialTags", isEnabled );
1731 }
1732 
showImportedFonts(int show)1733 void typotek::showImportedFonts(int show) // 0 == show dialog, 2 == do not show
1734 {
1735 	bool doShow = true;
1736 	if (show == Qt::Checked)
1737 		doShow = false;
1738 	showFontListDialog = doShow;
1739 	QSettings settings;
1740 	settings.setValue("ShowImportedFonts", doShow);
1741 }
1742 
showImportedFonts()1743 bool typotek::showImportedFonts()
1744 {
1745 	return showFontListDialog;
1746 }
1747 
setTemplatesDir(const QString & dir)1748 void typotek::setTemplatesDir(const QString & dir)
1749 {
1750 	templatesDir = dir;
1751 	QSettings settings;
1752 	settings.setValue("Places/TemplatesDir", templatesDir);
1753 
1754 }
1755 
changeFontSizeSettings(double fSize,double lSize)1756 void typotek::changeFontSizeSettings(double fSize, double lSize)
1757 {
1758 	QSettings settings;
1759 	settings.setValue("Sample/FontSize", fSize);
1760 	settings.setValue("Sample/Interline", lSize);
1761 //	theMainView->reSize(fSize,lSize);
1762 }
1763 
relayStartingStepIn(QString s)1764 void typotek::relayStartingStepIn(QString s)
1765 {
1766 	int i( Qt::AlignRight | Qt::AlignBottom );
1767 	QColor c(Qt::white);
1768 	emit relayStartingStepOut( s, i , c );
1769 }
1770 
removeFontItem(QString key)1771 void typotek::removeFontItem(QString key)
1772 {
1773 // 	FontItem *fit = realFontMap.value(key);
1774 // 	if(!fit)
1775 // 		return;
1776 // 	fontMap.removeAll(fit);
1777 // 	delete fit;
1778 // 	realFontMap.remove(key);
1779 // 	qDebug()<< key << "has been removed";
1780 	FMFontDb::DB()->Remove(key);
1781 }
1782 
removeFontItem(QStringList keyList)1783 void typotek::removeFontItem(QStringList keyList)
1784 {
1785 	foreach(QString key, keyList)
1786 	{
1787 		removeFontItem(key);
1788 	}
1789 }
1790 
showStatusMessage(const QString & message)1791 void typotek::showStatusMessage(const QString & message)
1792 {
1793 	statusBar()->showMessage(message, 3000);
1794 }
1795 
setRemoteTmpDir(const QString & s)1796 void typotek::setRemoteTmpDir(const QString & s)
1797 {
1798 	if(s.isEmpty())
1799 		m_remoteTmpDir = QDir::temp().path();
1800 	else
1801 		m_remoteTmpDir = s;
1802 
1803 	QSettings settings;
1804 	settings.setValue("Places/RemoteTmpDir", m_remoteTmpDir);
1805 }
1806 
slotRepair()1807 void typotek::slotRepair()
1808 {
1809 	FmRepair repair(this);
1810 	repair.exec();
1811 }
1812 
slotTagAll()1813 void typotek::slotTagAll()
1814 {
1815 	QStringList tagsList(FMFontDb::DB()->getTags());
1816 	ImportTags imp(this,tagsList);
1817 	imp.exec();
1818 	QStringList tali = imp.tags();
1819 
1820 	if(tali.isEmpty())
1821 		return;
1822 	for(int t(0); t < tali.count(); ++t)
1823 	{
1824 		if(!tagsList.contains(tali[t]))
1825 		{
1826 			tagsList.append(tali[t]);
1827 		}
1828 	}
1829 
1830 	FMFontDb::DB()->TransactionBegin();
1831 	QList<FontItem*> curfonts = theMainView->curFonts();
1832 	for(int i(0) ; i < curfonts.count(); ++i)
1833 	{
1834 		for(int t(0); t < tali.count(); ++t)
1835 		{
1836 			curfonts[i]->addTag(tali[t]);
1837 		}
1838 
1839 	}
1840 	FMFontDb::DB()->TransactionEnd();
1841 //	TagsWidget::getInstance()->newTag();
1842 }
1843 
1844 
1845 //void typotek::printFamily()
1846 //{
1847 //	FontItem * font(theMainView->selectedFont());
1848 //	if(!font)
1849 //		return;
1850 //	QPrinter thePrinter ( QPrinter::HighResolution );
1851 //	QPrintDialog dialog(&thePrinter, this);
1852 //	dialog.setWindowTitle("Fontmatrix - " + tr("Print Family") +" - " + font->family());
1853 
1854 //	if ( dialog.exec() != QDialog::Accepted )
1855 //		return;
1856 
1857 //	thePrinter.setFullPage ( true );
1858 //	QPainter aPainter ( &thePrinter );
1859 
1860 //	QGraphicsScene tmpScene(thePrinter.paperRect());
1861 //	QGraphicsScene pScene(thePrinter.paperRect());
1862 
1863 //	qDebug()<<thePrinter.paperRect();
1864 
1865 //	QMap<int , double> logWidth;
1866 //	QMap<int , double> logAscend;
1867 //	QMap<int , double> logDescend;
1868 //	QMap<int , QString> sampleString;
1869 //	QMap<int , FontItem*> sampleFont;
1870 
1871 //	QStringList stl1(namedSample ( theMainView->sampleName() ).split ( QRegExp("\\W") ));
1872 //	if(stl1.count() < 10 )
1873 //	{
1874 //		QMessageBox::information(this,"Fontmatrix",tr("Not enough text to make a sample"));
1875 //		return;
1876 //	}
1877 //	QStringList stl;
1878 //	int idxS(0);
1879 //	int idxE( qrand() % 9 );
1880 //	while((idxS + idxE) < stl1.count())
1881 //	{
1882 //		QString t(QStringList(stl1.mid(idxS,idxE)).join( " " ));
1883 //		qDebug()<<"s e T"<<idxS<<idxE<<t;
1884 //		if(!t.isEmpty())
1885 //			stl << t;
1886 
1887 //		idxS += idxE;
1888 //		idxE = qrand() % 9;
1889 //	}
1890 //	QList<FontItem*> familyFonts(FMFontDb::DB()->Fonts(theMainView->selectedFont()->family(), FMFontDb::Family ));
1891 
1892 //// 	if(familyFonts.count() > stl.count())
1893 //	{
1894 //		int diff ( familyFonts.count()  );
1895 //		for (int i(0); i < diff; ++i)
1896 //		{
1897 //			sampleString[i] = stl[ i % stl.count() ];
1898 //		}
1899 //	}
1900 
1901 //	// first we’ll get widths for font size 1000
1902 //	for(int fidx(0); fidx < familyFonts.count(); ++fidx)
1903 //	{
1904 //		sampleFont[fidx] = familyFonts[fidx];
1905 //		bool rasterState(sampleFont[fidx]->rasterFreetype());
1906 //		sampleFont[fidx]->setFTRaster(false);
1907 //		sampleFont[fidx]->setRenderReturnWidth(true);
1908 //		logWidth[fidx] =  familyFonts[fidx]->renderLine(&tmpScene, sampleString[fidx], QPointF(0.0, 1000.0) , 999999.0, 1000.0, 1) ;
1909 //		sampleFont[fidx]->setRenderReturnWidth(false);
1910 //		sampleFont[fidx]->setFTRaster(rasterState);
1911 //		logAscend[fidx] = 1000.0 - tmpScene.itemsBoundingRect().top();
1912 //		logDescend[fidx] = tmpScene.itemsBoundingRect().bottom() - 1000.0;
1913 //		qDebug()<< sampleString[fidx] << logWidth[fidx];
1914 //		QList<QGraphicsItem*> lgit(tmpScene.items());
1915 //		foreach(QGraphicsItem* git, lgit)
1916 //		{
1917 //			tmpScene.removeItem(git);
1918 //			delete git;
1919 //		}
1920 //	}
1921 //	double defWidth(0.8 * pScene.width() );
1922 //	double defHeight(0.9 * pScene.height() );
1923 //	double xOff( 0.1 * pScene.width() );
1924 //	double yPos(0.1 * pScene.height() );
1925 
1926 //	QFont nameFont;
1927 //	nameFont.setPointSizeF(100.0);
1928 //	nameFont.setItalic(true);
1929 
1930 //	for(int fidx(0); fidx < familyFonts.count(); ++fidx)
1931 //	{
1932 //		double scaleFactor(1000.0 / logWidth[fidx] );
1933 //		double fSize( defWidth *  scaleFactor );
1934 //		double fAscend(logAscend[fidx] * fSize / 1000.0);
1935 //		double fDescend(logDescend[fidx] * fSize  / 1000.0 );
1936 //		if( yPos + fAscend + fDescend > defHeight)
1937 //		{
1938 //			pScene.render(&aPainter);
1939 //			thePrinter.newPage();
1940 //			QList<QGraphicsItem*> lgit(pScene.items());
1941 //			foreach(QGraphicsItem* git, lgit)
1942 //			{
1943 //				pScene.removeItem(git);
1944 //				delete git;
1945 //			}
1946 //			yPos = 0.1 * pScene.height();
1947 
1948 //		}
1949 
1950 //		yPos +=  fAscend;
1951 //		QPointF origine(xOff,  yPos );
1952 
1953 //		qDebug()<< sampleString[fidx] << fSize;
1954 
1955 //		bool rasterState(sampleFont[fidx]->rasterFreetype());
1956 //		sampleFont[fidx]->setFTRaster(false);
1957 //		sampleFont[fidx]->renderLine(&pScene, sampleString[fidx], origine, pScene.width(), fSize, 100);
1958 //		pScene.addLine(QLineF(origine, QPointF(xOff + defWidth, yPos)));
1959 //		sampleFont[fidx]->setFTRaster(rasterState);
1960 
1961 //		yPos +=  fDescend ;
1962 
1963 //		QGraphicsSimpleTextItem * nameText = pScene.addSimpleText( familyFonts[fidx]->fancyName(), nameFont) ;
1964 //		nameText->setPos(xOff, yPos);
1965 //// 		nameText->setBrush(Qt::gray);
1966 //		yPos += nameText->boundingRect().height();
1967 //	}
1968 
1969 //	pScene.render(&aPainter);
1970 //}
1971 
showEvent(QShowEvent * event)1972 void typotek::showEvent(QShowEvent * event)
1973 {
1974 	QMainWindow::showEvent(event);
1975 }
1976 
slotDockAreaChanged(Qt::DockWidgetArea area)1977 void typotek::slotDockAreaChanged(Qt::DockWidgetArea area)
1978 {
1979 	QDockWidget * dw(reinterpret_cast<QDockWidget*>(sender()));
1980 
1981 	if(dw)
1982 	{
1983 		QString wId(dw->objectName());
1984 		if(area == Qt::LeftDockWidgetArea)
1985 			dockArea[wId] = "Left";
1986 		else if(area ==Qt::RightDockWidgetArea)
1987 			dockArea[wId] ="Right";
1988 		else if(area == Qt::TopDockWidgetArea)
1989 			dockArea[wId] ="Top";
1990 		else if(area == Qt::BottomDockWidgetArea)
1991 			dockArea[wId] = "Bottom";
1992 	}
1993 }
1994 
1995 
getHyphenator() const1996 FMHyphenator* typotek::getHyphenator() const
1997 {
1998 	return hyphenator;
1999 }
2000 
2001 //void typotek::slotSwitchLayOptVisible()
2002 //{
2003 //	if(FMLayout::getLayout()->optionDialog->isVisible())
2004 //		FMLayout::getLayout()->optionDialog->setVisible(false);
2005 //	else
2006 //		FMLayout::getLayout()->optionDialog->setVisible(true);
2007 //	slotUpdateLayOptStatus();
2008 //}
2009 
2010 //void typotek::slotUpdateLayOptStatus()
2011 //{
2012 //	if(FMLayout::getLayout()->optionDialog->isVisible())
2013 //		layOptAct->setChecked(true);
2014 //	else
2015 //		layOptAct->setChecked(false);
2016 //}
2017 
2018 #ifdef HAVE_PYTHONQT
slotSwitchScriptConsole()2019 void typotek::slotSwitchScriptConsole()
2020 {
2021 	if(FMScriptConsole::getInstance()->isVisible())
2022 		FMScriptConsole::getInstance()->setVisible(false);
2023 	else
2024 		FMScriptConsole::getInstance()->setVisible(true);
2025 	slotUpdateScriptConsoleStatus();
2026 }
2027 
slotUpdateScriptConsoleStatus()2028 void typotek::slotUpdateScriptConsoleStatus()
2029 {
2030 	if(FMScriptConsole::getInstance()->isVisible())
2031 		scriptConsoleAct->setChecked(true);
2032 	else
2033 		scriptConsoleAct->setChecked(false);
2034 }
2035 #else
slotSwitchScriptConsole()2036 void typotek::slotSwitchScriptConsole(){}
slotUpdateScriptConsoleStatus()2037 void typotek::slotUpdateScriptConsoleStatus(){}
2038 #endif
2039 
getDefaultOTFScript() const2040 QString typotek::getDefaultOTFScript() const
2041 {
2042 	return defaultOTFScript;
2043 }
2044 
setDefaultOTFScript(const QString & theValue)2045 void typotek::setDefaultOTFScript ( const QString& theValue )
2046 {
2047 	if(theValue != defaultOTFScript)
2048 	{
2049 		QSettings st;
2050 		st.setValue("OTF/Script" , theValue);
2051 	}
2052 	defaultOTFScript = theValue;
2053 
2054 }
2055 
getDefaultOTFLang() const2056 QString typotek::getDefaultOTFLang() const
2057 {
2058 	return defaultOTFLang;
2059 }
2060 
setDefaultOTFLang(const QString & theValue)2061 void typotek::setDefaultOTFLang ( const QString& theValue )
2062 {
2063 	if(theValue != defaultOTFLang)
2064 	{
2065 		QSettings st;
2066 		st.setValue("OTF/Lang" , theValue);
2067 	}
2068 	defaultOTFLang = theValue;
2069 }
2070 
getDefaultOTFGPOS() const2071 QStringList typotek::getDefaultOTFGPOS() const
2072 {
2073 	return defaultOTFGPOS;
2074 }
2075 
setDefaultOTFGPOS(const QStringList & theValue)2076 void typotek::setDefaultOTFGPOS ( const QStringList& theValue )
2077 {
2078 	if(theValue != defaultOTFGPOS)
2079 	{
2080 		QSettings st;
2081 		st.setValue("OTF/GPOS" , theValue.join(";"));
2082 	}
2083 	defaultOTFGPOS = theValue;
2084 }
2085 
getDefaultOTFGSUB() const2086 QStringList typotek::getDefaultOTFGSUB() const
2087 {
2088 	return defaultOTFGSUB;
2089 }
2090 
setDefaultOTFGSUB(const QStringList & theValue)2091 void typotek::setDefaultOTFGSUB ( const QStringList& theValue )
2092 {
2093 	if(theValue != defaultOTFGSUB)
2094 	{
2095 		QSettings st;
2096 		st.setValue("OTF/GSUB" , theValue.join(";"));
2097 	}
2098 	defaultOTFGSUB = theValue;
2099 }
2100 
startProgressJob(int max)2101 void typotek::startProgressJob(int max)
2102 {
2103 	statusProgressBar->reset();
2104 	statusProgressBar->setRange(0,max);
2105 	statusProgressBar->show();
2106 }
2107 
runProgressJob(int i)2108 void typotek::runProgressJob(int i)
2109 {
2110 	if(i)
2111 	{
2112 		statusProgressBar->setValue(i);
2113 	}
2114 	else
2115 	{
2116 		int v(statusProgressBar->value());
2117 		statusProgressBar->setValue( ++v );
2118 	}
2119 }
2120 
endProgressJob()2121 void typotek::endProgressJob()
2122 {
2123 	statusProgressBar->hide();
2124 	statusProgressBar->reset();
2125 }
2126 
slotShowTTTables()2127 void typotek::slotShowTTTables()
2128 {
2129 	if(theMainView->selectedFont())
2130 	{
2131 		QDialog dia(this);
2132 		QGridLayout glayout(&dia);
2133 		TTTableView tv(theMainView->selectedFont(),&dia);
2134 		QPushButton pbutton(tr("Close"),&dia);
2135 		glayout.addWidget(&tv,0,0,3,3);
2136 		glayout.addWidget(&pbutton,3,2);
2137 		pbutton.setDefault(true);
2138 
2139 		QRect drect(dia.rect());
2140 		drect.setX(this->geometry().x() + 32);
2141 		drect.setY(this->geometry().y() + 32);
2142 		drect.setWidth(tv.rect().width() * 1.2);
2143 		drect.setHeight(tv.rect().height() * 1.2);
2144 		dia.setGeometry(drect);
2145 		connect(&pbutton,SIGNAL(released()),&dia,SLOT(close()));
2146 		dia.exec();
2147 	}
2148 }
2149 
slotEditPanose()2150 void typotek::slotEditPanose()
2151 {
2152 	if(theMainView->selectedFont())
2153 	{
2154 		FMPanoseDialog dia(theMainView->selectedFont(), this);
2155 		dia.exec();
2156 		if(dia.getOk() && ( dia.getSourcePanose() != dia.getTargetPanose() ))
2157 		{
2158 // 			qDebug()<< "Update Panose"<<theMainView->selectedFont()->path();
2159 			FMFontDb::DB()->setValue(theMainView->selectedFont()->path(), FMFontDb::Panose, dia.getTargetPanose());
2160 //			theMainView->slotInfoFont();
2161 		}
2162 	}
2163 }
2164 
slotDumpInfo()2165 void typotek::slotDumpInfo()
2166 {
2167 	if(theMainView->selectedFont())
2168 	{
2169 		FMDumpDialog dia(theMainView->selectedFont(), this);
2170 		if(dia.exec() != QDialog::Accepted)
2171 		{
2172 			qDebug()<< "Dump not saved";
2173 		}
2174 	}
2175 
2176 }
2177 
slotReloadFiltered()2178 void typotek::slotReloadFiltered()
2179 {
2180 	FontItem * cf(theMainView->selectedFont());
2181 	QString cfName;
2182 	if(cf)
2183 		cf->path();
2184 
2185 	QStringList toReload;
2186 	QApplication::changeOverrideCursor(Qt::WaitCursor);
2187 	QMap<QString, QStringList> tagsRec;
2188 	FMFontDb *db(FMFontDb::DB());
2189 	foreach(FontItem* f, theMainView->curFonts())
2190 	{
2191 		toReload << f->path();
2192 		tagsRec[f->path()] = f->tags();
2193 		db->Remove(f->path());
2194 	}
2195 	QList<FontItem*> renewedFonts;
2196 	foreach(QString p, toReload)
2197 	{
2198 		FontItem * it(db->Font(p, true));
2199 		if(it)
2200 		{
2201 			renewedFonts << it;
2202 		}
2203 	}
2204 	db->TransactionBegin();
2205 	foreach(FontItem* it, renewedFonts)
2206 	{
2207 		it->setTags(tagsRec[it->path()]);
2208 	}
2209 	db->TransactionEnd();
2210 
2211 	if(toReload.count() > renewedFonts.count())
2212 	{
2213 		//! Number of fonts we failed to reload
2214 		showStatusMessage(tr("Failed to reload %n fonts", "", toReload.count() - renewedFonts.count()));
2215 //		theMainView->slotReloadFontList();
2216 	}
2217 	if(!cfName.isEmpty())
2218 	{
2219 //			theMainView->forceReloadSelection();
2220 			theMainView->slotFontSelectedByName(cfName);
2221 	}
2222 
2223 	QApplication::restoreOverrideCursor();
2224 
2225 }
2226 
slotReloadSingle()2227 void typotek::slotReloadSingle()
2228 {
2229 	FontItem * cf(theMainView->selectedFont());
2230 	if(cf)
2231 	{
2232 		QString curName(cf->path());
2233 		QStringList t(cf->tags());
2234 		FMFontDb::DB()->Remove(curName);
2235 		cf = FMFontDb::DB()->Font(curName, true);
2236 		if(cf)
2237 		{
2238 			cf->setTags(t);
2239 //			theMainView->forceReloadSelection();
2240 			theMainView->slotFontSelectedByName(curName);
2241 		}
2242 	}
2243 }
2244 
slotExtractFont()2245 void typotek::slotExtractFont()
2246 {
2247 	FMFontExtract ex(this);
2248 	ex.exec();
2249 }
2250 
slotMatchRaster()2251 void typotek::slotMatchRaster()
2252 {
2253 	FMMatchRaster mr(this);
2254 	mr.exec();
2255 }
2256 
2257 
2258 #ifdef HAVE_PYTHONQT
slotExecScript()2259 void typotek::slotExecScript()
2260 {
2261 	lastScript = QFileDialog::getOpenFileName(this,"Fontmatrix",QDir::homePath(),tr("Python scripts (*.py)"));
2262 	if(!lastScript.isEmpty())
2263 	{
2264 		if((recentScripts.count() < MAX_RECENT_PYSCRIPTS) && (!recentScripts.values().contains(lastScript)))
2265 		{
2266 			QFileInfo fInfo(lastScript);
2267 			QAction * sca (new QAction(fInfo.baseName(), this));
2268 			recentScripts[sca] = lastScript;
2269 			connect(sca, SIGNAL(triggered()), this, SLOT(slotExecRecentScript()));
2270 			scriptMenu->addAction(sca);
2271 		}
2272 		FMPythonW::getInstance()->runFile(lastScript);
2273 	}
2274 	else
2275 		qDebug()<<"Error: Script path empty";
2276 }
slotExecLastScript()2277 void typotek::slotExecLastScript()
2278 {
2279 	if(!lastScript.isEmpty())
2280 	{
2281 		FMPythonW::getInstance()->runFile(lastScript);
2282 	}
2283 	else
2284 		qDebug()<<"Error: Script path empty";
2285 }
slotExecRecentScript()2286 void typotek::slotExecRecentScript()
2287 {
2288 	if(sender())
2289 	{
2290 		QAction * sca = reinterpret_cast<QAction*>(sender());
2291 		if(sca)
2292 		{
2293 			if(recentScripts.contains(sca))
2294 			{
2295 				lastScript = recentScripts[sca];
2296 				FMPythonW::getInstance()->runFile(lastScript);
2297 			}
2298 		}
2299 	}
2300 }
2301 #else
slotExecScript()2302 void typotek::slotExecScript(){}
slotExecLastScript()2303 void typotek::slotExecLastScript(){}
slotExecRecentScript()2304 void typotek::slotExecRecentScript(){}
2305 #endif
2306 
showToltalFilteredFonts()2307 void typotek::showToltalFilteredFonts()
2308 {
2309 	countFilteredFonts->setText( tr( "Filtered Font(s): %n", "number of filtererd fonts showed in status bar", FMFontDb::DB()->countFilteredFonts() ) );
2310 }
2311 
presentFontName(QString s)2312 void typotek::presentFontName(QString s)
2313 {
2314 	curFontPresentation->setText(QString("%1 : <b>%2</b>")
2315 				     .arg(tr("Current Font", "followed by currently selected font name (in status bar)"))
2316 				     .arg(s));
2317 }
2318 
2319 
getPanoseMatchTreshold() const2320 int typotek::getPanoseMatchTreshold() const
2321 {
2322 	return panoseMatchTreshold;
2323 }
2324 
2325 
setPanoseMatchTreshold(int theValue)2326 void typotek::setPanoseMatchTreshold ( int theValue )
2327 {
2328 	panoseMatchTreshold = theValue;
2329 }
2330 
2331 
getWebBrowser() const2332 QString typotek::getWebBrowser() const
2333 {
2334 	return webBrowser;
2335 }
2336 
2337 
setWebBrowser(const QString & theValue)2338 void typotek::setWebBrowser ( const QString& theValue )
2339 {
2340 	webBrowser = theValue;
2341 }
2342 
2343 
getWebBrowserOptions() const2344 QString typotek::getWebBrowserOptions() const
2345 {
2346 	return webBrowserOptions;
2347 }
2348 
2349 
setWebBrowserOptions(const QString & theValue)2350 void typotek::setWebBrowserOptions ( const QString& theValue )
2351 {
2352 	webBrowserOptions = theValue;
2353 }
2354 
hide()2355 void typotek::hide()
2356 {
2357 	foreach(const QString& k, dockWidget.keys())
2358 	{
2359 		dockVisible[k] = dockWidget[k]->isVisible();
2360 		dockWidget[k]->hide();
2361 	}
2362 	visibleFloatingWidgets.clear();
2363 	foreach(FloatingWidget* f, FloatingWidgetsRegister::AllWidgets())
2364 	{
2365 		visibleFloatingWidgets[f] = f->isVisible();
2366 		f->setVisible(false);
2367 	}
2368 
2369 	playVisible = PlayWidget::getInstance()->isVisible();
2370 
2371 	QMainWindow::hide();
2372 }
2373 
show()2374 void typotek::show()
2375 {
2376 	foreach(const QString& k, dockWidget.keys())
2377 	{
2378 		dockWidget[k]->setVisible(dockVisible[k]);
2379 	}
2380 	foreach(FloatingWidget *f, visibleFloatingWidgets.keys())
2381 	{
2382 		f->setVisible(visibleFloatingWidgets[f]);
2383 	}
2384 
2385 	PlayWidget::getInstance()->setVisible(playVisible);
2386 
2387 	QMainWindow::show();
2388 }
2389 
setInfoStyle(const QString & theValue)2390 void typotek::setInfoStyle ( const QString& theValue )
2391 {
2392 	infoStyle = theValue;
2393 }
2394 
word(FontItem * item,const QString & alt)2395 QString typotek::word(FontItem * item, const QString& alt)
2396 {
2397 	if(item)
2398 	{
2399 		QString word(m_theWord);
2400 		if(word.isEmpty() && !alt.isEmpty())
2401 			word = alt;
2402 		word.replace("<name>", item->fancyName());
2403 		word.replace("<family>", item->family());
2404 		word.replace("<variant>", item->variant());
2405 		return word;
2406 	}
2407 
2408 	return m_theWord;
2409 }
2410 
2411 
updateFloatingStatus()2412 void typotek::updateFloatingStatus()
2413 {
2414 	playAction->setChecked( PlayWidget::getInstance()->isVisible() );
2415 	compareAction->setChecked(FontCompareWidget::getInstance()->isVisible());
2416 
2417 	viewMenu->removeAction(closeAllFloat);
2418 	viewMenu->removeAction(showAllFloat);
2419 	viewMenu->removeAction(hideAllFloat);
2420 	viewMenu->removeAction(floatSep);
2421 
2422 	QList<FloatingWidget*> fwl(FloatingWidgetsRegister::AllWidgets());
2423 	foreach(FloatingWidget* f, floatingWidgets.keys())
2424 	{
2425 		if(!fwl.contains(f))
2426 		{
2427 			viewMenu->removeAction(floatingWidgets[f]);
2428 			floatingWidgets.remove(f);
2429 		}
2430 	}
2431 
2432 	foreach(FloatingWidget* f, fwl)
2433 	{
2434 		if(floatingWidgets.contains(f))
2435 		{
2436 			floatingWidgets[f]->setChecked(f->isVisible());
2437 		}
2438 		else
2439 		{
2440 			QAction *wa(new QAction(f->getActionName(),this));
2441 			wa->setCheckable(true);
2442 			connect(f, SIGNAL(visibilityChange()), this, SLOT(updateFloatingStatus()));
2443 			connect(wa, SIGNAL(triggered(bool)), f, SLOT(activate(bool)));
2444 			floatingWidgets.insert(f,  wa);
2445 			floatingWidgets[f]->setChecked(f->isVisible());
2446 			viewMenu->addAction(wa);
2447 		}
2448 	}
2449 	if(floatingWidgets.count() > 0)
2450 	{
2451 		viewMenu->addAction(floatSep);
2452 		viewMenu->addAction(closeAllFloat);
2453 	}
2454 	if(floatingWidgets.count() > 1)
2455 	{
2456 		viewMenu->addAction(showAllFloat);
2457 		viewMenu->addAction(hideAllFloat);
2458 	}
2459 }
2460 
2461 
closeAllFloatings()2462 void typotek::closeAllFloatings()
2463 {
2464 	foreach(FloatingWidget* f, floatingWidgets.keys())
2465 	{
2466 		f->close();
2467 	}
2468 }
2469 
showAllFloatings()2470 void typotek::showAllFloatings()
2471 {
2472 	foreach(FloatingWidget* f, floatingWidgets.keys())
2473 	{
2474 		f->setVisible(true);
2475 	}
2476 }
2477 
hideAllFloatings()2478 void typotek::hideAllFloatings()
2479 {
2480 	foreach(FloatingWidget* f, floatingWidgets.keys())
2481 	{
2482 		f->setVisible(false);
2483 	}
2484 }
2485 
2486 
toggleMainView(bool v)2487 void typotek::toggleMainView(bool v)
2488 {
2489 	if(v)
2490 		mainStack->setCurrentWidget(theBrowser);
2491 	else
2492 		mainStack->setCurrentWidget(theMainView);
2493 }
2494 
pushObject(QObject * o)2495 void typotek::pushObject(QObject *o)
2496 {
2497 	o->moveToThread(sender()->thread());
2498 }
2499