1 /***************************************************************************
2 * Copyright (C) 2010 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 #include "browserwidget.h"
22 #include "ui_browserwidget.h"
23
24 #include "fmfontdb.h"
25 #include "fontitem.h"
26 #include "fminfodisplay.h"
27 #include "floatingwidgetsregister.h"
28 #include "samplewidget.h"
29 #include "chartwidget.h"
30 #include "typotek.h"
31
32 #include <QDirModel>
33 #include <QDir>
34 #include <QSettings>
35 #include <QFileSystemWatcher>
36 #include <QDebug>
37
BrowserWidget(QWidget * parent)38 BrowserWidget::BrowserWidget(QWidget *parent) :
39 QWidget(parent),
40 ui(new Ui::BrowserWidget)
41 {
42 ui->setupUi(this);
43
44 ui->infoButton->setEnabled(false);
45 ui->sampleButton->setEnabled(false);
46 ui->chartButton->setEnabled(false);
47
48 folderViewContextMenu = 0;
49 currentPage = BROWSER_VIEW_SAMPLE;
50 sample = chart = 0;
51 ffilter << "*.otf" << "*.ttf" << "*.ttc" << "*.pfb";
52 theDirModel = new QDirModel(ffilter, QDir::AllDirs | QDir::Files | QDir::Drives | QDir::NoDotAndDotDot, QDir::DirsFirst | QDir::Name);
53 theDirModel->setLazyChildCount(true);
54 ui->browserView->setModel(theDirModel);
55 ui->browserView->hideColumn(1);
56 ui->browserView->hideColumn(2);
57 ui->browserView->hideColumn(3);
58 ui->browserView->setContextMenuPolicy(Qt::CustomContextMenu);
59
60 QSettings settings;
61 QString lastUsedDir = settings.value("Places/LastUsedFolder", QDir::homePath()).toString();
62 QDir d(lastUsedDir);
63 if (!d.exists())
64 lastUsedDir = QDir::homePath();
65 QModelIndex luIdx(theDirModel->index(lastUsedDir, 0));
66 ui->browserView->setCurrentIndex(luIdx);
67 QModelIndexList hierarchy;
68 while(luIdx.isValid())
69 {
70 hierarchy.prepend(luIdx);
71 luIdx = luIdx.parent();
72 }
73 foreach(QModelIndex idx, hierarchy)
74 ui->browserView->expand(idx);
75
76 dirWatcher = new QFileSystemWatcher(this);
77 initWatcher(theDirModel->index(0,0));
78
79 connect(ui->infoButton, SIGNAL(clicked()), this, SLOT(slotShowInfo()));
80 connect(ui->sampleButton, SIGNAL(clicked()), this, SLOT(slotShowSample()));
81 connect(ui->chartButton, SIGNAL(clicked()), this, SLOT(slotShowChart()));
82
83 connect(ui->importButton, SIGNAL(clicked()), this, SLOT(slotImport()));
84
85 connect(ui->browserView, SIGNAL(activated( const QModelIndex& )), this, SLOT(slotFolderItemclicked(QModelIndex)));
86 connect(ui->browserView, SIGNAL(clicked( const QModelIndex& )), this, SLOT(slotFolderItemclicked(QModelIndex)));
87 connect(ui->browserView,SIGNAL(pressed( const QModelIndex& )),this,SLOT(slotFolderPressed(QModelIndex)));
88
89 connect(ui->browserView, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(slotFolderViewContextMenu(const QPoint &)));
90
91 connect(dirWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(slotFolderRefresh(QString)));
92
93 }
94
~BrowserWidget()95 BrowserWidget::~BrowserWidget()
96 {
97 delete ui;
98 }
99
initWatcher(QModelIndex parent)100 void BrowserWidget::initWatcher(QModelIndex parent)
101 {
102 // qDebug()<<"initWatcher"<<theDirModel->filePath(parent);
103 for(int fIdx(0); fIdx < theDirModel->rowCount(parent); ++fIdx)
104 {
105 QModelIndex mIdx(theDirModel->index(fIdx,0, parent));
106 // qDebug()<<"\t"<<theDirModel->filePath(mIdx)<<folderView->isExpanded(mIdx);
107 if(ui->browserView->isExpanded(mIdx))
108 {
109 QString fp(theDirModel->filePath(mIdx));
110 dirWatcher->addPath(fp);
111 qDebug()<<"***Watch"<<fp;
112 initWatcher(mIdx);
113 }
114 }
115 }
116
slotFolderAddToWatcher(QModelIndex mIdx)117 void BrowserWidget::slotFolderAddToWatcher(QModelIndex mIdx)
118 {
119 qDebug()<<"Add to watcher"<<theDirModel->filePath(mIdx);
120 dirWatcher->addPath(theDirModel->filePath(mIdx));
121 }
122
slotFolderItemclicked(QModelIndex mIdx)123 void BrowserWidget::slotFolderItemclicked(QModelIndex mIdx)
124 {
125 if(curVariant.isEmpty())
126 {
127 ui->infoButton->setEnabled(true);
128 ui->sampleButton->setEnabled(true);
129 ui->chartButton->setEnabled(true);
130 }
131 QString path(theDirModel->data(mIdx,QDirModel::FilePathRole).toString());
132 QFileInfo pf(path);
133 if(!pf.isDir())
134 {
135 if(FMFontDb::DB()->insertTemporaryFont(path))
136 {
137 // emit folderSelectFont(pf.absoluteFilePath());
138 QString fid(pf.absoluteFilePath());
139 if(fid != curVariant)
140 {
141 if(chart != 0)
142 uniBlock = reinterpret_cast<ChartWidget*>(chart)->currentBlock();
143 delete sample;
144 delete chart;
145 sample = chart = 0;
146 curVariant = fid;
147 // currentIndex = index.row();
148 switch(currentPage)
149 {
150 case BROWSER_VIEW_INFO: slotShowInfo();
151 break;
152 case BROWSER_VIEW_SAMPLE: slotShowSample();
153 break;
154 case BROWSER_VIEW_CHART: slotShowChart();
155 break;
156 default:
157 break;
158 }
159
160 // emit fontSelected(curVariant);
161 }
162 }
163 }
164 settingsDir(path);
165 }
166
slotFolderPressed(QModelIndex mIdx)167 void BrowserWidget::slotFolderPressed(QModelIndex mIdx)
168 {
169 currentFIndex = mIdx;
170 }
171
slotFolderRefresh(const QString & dirPath)172 void BrowserWidget::slotFolderRefresh(const QString &dirPath)
173 {
174 if(ui->browserView->isVisible())
175 {
176 qDebug()<<"Refresh"<<dirPath;
177 theDirModel->refresh(theDirModel->index(dirPath, 0 ));
178 }
179 }
180
slotFolderRemoveFromWatcher(QModelIndex mIdx)181 void BrowserWidget::slotFolderRemoveFromWatcher(QModelIndex mIdx)
182 {
183 qDebug()<<"Remove from watcher"<<theDirModel->filePath(mIdx);
184 dirWatcher->removePath(theDirModel->filePath(mIdx));
185 }
186
settingsDir(const QString & path)187 void BrowserWidget::settingsDir(const QString &path)
188 {
189 static QString s;
190 if (s == path)
191 return;
192
193 QFileInfo fi(path);
194 QString dirPath = fi.absoluteFilePath();
195 if (fi.isFile())
196 dirPath = fi.absoluteDir().absolutePath();
197
198 QSettings settings;
199 settings.setValue("Places/LastUsedFolder", dirPath);
200
201 s = path;
202 }
203
204
slotShowInfo()205 void BrowserWidget::slotShowInfo()
206 {
207 FMInfoDisplay fid(FMFontDb::DB()->Font(curVariant));
208 ui->webView->setContent(fid.getHtml().toUtf8(), "application/xhtml+xml");
209 ui->displayStack->setCurrentIndex(BROWSER_VIEW_INFO);
210 currentPage = BROWSER_VIEW_INFO;
211 updateButtons();
212 }
213
slotShowChart()214 void BrowserWidget::slotShowChart()
215 {
216 FloatingWidget * fw(FloatingWidgetsRegister::Widget(curVariant, ChartWidget::Name));
217 if(fw == 0)
218 {
219 if(0 == chart)
220 {
221 ChartWidget *cw(new ChartWidget(curVariant, uniBlock, ui->pageChart));
222 ui->displayStack->insertWidget(BROWSER_VIEW_CHART, cw);
223 chart = cw;
224 connect(chart, SIGNAL(detached()), this, SLOT(slotDetachChart()));
225 }
226 ui->displayStack->setCurrentWidget(chart);
227 }
228 else
229 {
230 fw->show();
231 }
232 currentPage = BROWSER_VIEW_CHART;
233 updateButtons();
234 }
235
236
slotShowSample()237 void BrowserWidget::slotShowSample()
238 {
239 FloatingWidget * fw(FloatingWidgetsRegister::Widget(curVariant, SampleWidget::Name));
240 if(fw == 0)
241 {
242 if(0 == sample)
243 {
244 SampleWidget *sw(new SampleWidget(curVariant, ui->pageSample));
245 ui->displayStack->insertWidget(BROWSER_VIEW_SAMPLE, sw);
246 sample = sw;
247 connect(sample, SIGNAL(detached()), this, SLOT(slotDetachSample()));
248 }
249 ui->displayStack->setCurrentWidget(sample);
250 }
251 else
252 {
253 fw->show();
254 }
255 currentPage = BROWSER_VIEW_SAMPLE;
256 updateButtons();
257 }
258
slotDetachChart()259 void BrowserWidget::slotDetachChart()
260 {
261 disconnect(chart, SIGNAL(detached()), this, SLOT(slotDetachChart()));
262 chart = 0;
263 slotShowInfo();
264 }
265
slotDetachSample()266 void BrowserWidget::slotDetachSample()
267 {
268 disconnect(sample, SIGNAL(detached()), this, SLOT(slotDetachSample()));
269 sample = 0;
270 slotShowInfo();
271 }
272
slotFolderViewContextMenu(const QPoint & p)273 void BrowserWidget::slotFolderViewContextMenu(const QPoint &p)
274 {
275 qDebug()<<"P"<<p;
276 QDirModel *dm = static_cast<QDirModel*>(ui->browserView->model());
277 if (!dm)
278 return;
279
280 QModelIndex mi = ui->browserView->currentIndex();
281 if (!mi.isValid())
282 return;
283
284 slotFolderItemclicked(mi); // make sure the font in question is loaded
285 // with a direct right click it would crash without this
286
287 if (!folderViewContextMenu)
288 folderViewContextMenu = new FolderViewMenu();
289
290 folderViewContextMenu->exec(dm->fileInfo(mi), mapToGlobal(p));
291 }
292
updateButtons()293 void BrowserWidget::updateButtons()
294 {
295 static QList<QToolButton*> buttons;
296 if(buttons.isEmpty())
297 {
298 buttons << ui->sampleButton
299 << ui->infoButton
300 << ui->chartButton;
301 foreach(QToolButton * b, buttons)
302 {
303 b->setCheckable(true);
304 }
305 }
306 foreach(QToolButton * b, buttons)
307 {
308 b->setChecked(false);
309 }
310 switch(currentPage)
311 {
312 case BROWSER_VIEW_SAMPLE: ui->sampleButton->setChecked(true);
313 break;
314 case BROWSER_VIEW_CHART: ui->chartButton->setChecked(true);
315 break;
316 case BROWSER_VIEW_INFO : ui->infoButton->setChecked(true);
317 break;
318 default:break;
319 }
320 }
321
slotImport()322 void BrowserWidget::slotImport()
323 {
324 if(!curVariant.isEmpty())
325 typotek::getInstance()->open(curVariant, false, true);
326 }
327
FolderViewMenu()328 FolderViewMenu::FolderViewMenu() : QMenu()
329 {
330 dirAction = new QAction(tr("Import Directory"), 0);
331 dirRecursiveAction = new QAction(tr("Import recursively"), 0);
332 fileAction = new QAction(tr("Import File"), 0);
333
334 addAction(dirAction);
335 addAction(dirRecursiveAction);
336 addAction(fileAction);
337
338 connect(dirAction, SIGNAL(triggered()), this, SLOT(slotImportDir()));
339 connect(dirRecursiveAction, SIGNAL(triggered()), this, SLOT(slotImportDirRecursively()));
340 connect(fileAction, SIGNAL(triggered()), this, SLOT(slotImportFile()));
341 }
342
exec(const QFileInfo & fi,const QPoint & p)343 void FolderViewMenu::exec(const QFileInfo &fi, const QPoint &p)
344 {
345 if (fi.isDir()) {
346 dirAction->setEnabled(true);
347 dirRecursiveAction->setEnabled(true);
348 fileAction->setEnabled(false);
349 } else if (fi.isFile()) {
350 dirAction->setEnabled(false);
351 dirRecursiveAction->setEnabled(false);
352 fileAction->setEnabled(true);
353 } else
354 return; // not a file or a directory
355
356 selectedFileOrDir = fi;
357
358 QMenu::exec(p);
359 }
360
361
slotImportDir()362 void FolderViewMenu::slotImportDir()
363 {
364 // QDir dir(selectedFileOrDir.absoluteFilePath());
365 // QStringList ffilter;
366 // ffilter << "*.otf" << "*.ttf" << "*.pfb";
367 // QStringList fontList = dir.entryList(ffilter);
368 // if (fontList.count() < 1)
369 // return;
370 // QString lastItem = fontList.at(fontList.count() - 1);
371 // fontList.removeAt(fontList.count() - 1);
372 // foreach(QString tmpFontPath, fontList) {
373 // QString absPath = dir.absolutePath() + "/" + tmpFontPath;
374 // typotek::getInstance()->open(absPath, false, true);
375 // }
376 typotek::getInstance()->open(selectedFileOrDir.absoluteFilePath(),false, true); // import the last font with the announce flag set to true
377 }
378
slotImportDirRecursively()379 void FolderViewMenu::slotImportDirRecursively()
380 {
381 typotek::getInstance()->open(selectedFileOrDir.absoluteFilePath());
382 }
383
slotImportFile()384 void FolderViewMenu::slotImportFile()
385 {
386 typotek::getInstance()->open(selectedFileOrDir.absoluteFilePath());
387 }
388
~FolderViewMenu()389 FolderViewMenu::~FolderViewMenu()
390 {
391
392 }
393