[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project
klfliblegacyengine.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * file klfliblegacyengine.cpp
3  * This file is part of the KLatexFormula Project.
4  * Copyright (C) 2011 by Philippe Faist
5  * philippe.faist at bluewin.ch
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the *
19  * Free Software Foundation, Inc., *
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  ***************************************************************************/
22 /* $Id: klfliblegacyengine.cpp 627 2011-04-12 12:36:22Z phfaist $ */
23 
24 
25 #include <QString>
26 #include <QObject>
27 #include <QDataStream>
28 #include <QDir>
29 #include <QFile>
30 #include <QFileInfo>
31 #include <QMessageBox>
32 #include <QApplication> // qApp
33 
34 #include "klflib.h"
35 #include "klflibview.h"
36 #include "klfconfig.h"
37 #include <klfutil.h>
38 #include "klfliblegacyengine.h"
39 #include "klfliblegacyengine_p.h"
40 
41 
70 
71 
72 // debug
73 
74 QDebug& operator<<(QDebug& s, const KLFLegacyData::KLFLibraryItem& item)
75 {
76  return s << "KLFLegacyData::KLFLibraryItem(id="<<item.id<<"; latex="<<item.latex<<")" ;
77 }
78 
79 QDebug& operator<<(QDebug& s, const KLFLegacyData::KLFLibraryResource& res)
80 {
81  return s << "KLFLegacyData::KLFLibraryResource(id="<<res.id<<"; name="<<res.name<<")";
82 }
83 
84 
85 
86 
87 
89 {
90  return stream << item.id << item.datetime
91  << item.latex // category and tags are included.
92  << item.preview << item.style;
93 }
94 
95 // it is important to note that the >> operator imports in a compatible way to KLF 2.0
97 {
98  stream >> item.id >> item.datetime >> item.latex >> item.preview >> item.style;
101  return stream;
102 }
103 
104 
106 {
107  return stream << item.id << item.name;
108 }
110 {
111  return stream >> item.id >> item.name;
112 }
113 
114 
116 {
117  return
118  // a.id == b.id && // don't compare IDs since they should be different.
119  // a.datetime == b.datetime && // same for datetime
120  a.latex == b.latex &&
121  /* the following is unnecessary since category/tags information is contained in .latex
122  a.category == b.category &&
123  a.tags == b.tags &&
124  */
125  // a.preview == b.preview && // don't compare preview: it's unnecessary and overkill
126  a.style == b.style;
127 }
128 
129 
130 
132 {
133  return a.id < b.id;
134 }
136 {
137  return a.id == b.id;
138 }
139 
142 {
143  return a.name == b.name;
144 }
145 
146 
147 KLF_EXPORT QDataStream& operator<<(QDataStream& stream, const KLFLegacyData::KLFStyle& style)
148 {
149  return stream << style.name << (quint32)style.fg_color << (quint32)style.bg_color
150  << style.mathmode << style.preamble << (quint16)style.dpi;
151 }
153 {
154  quint32 fg, bg;
155  quint16 dpi;
156  stream >> style.name;
157  stream >> fg >> bg >> style.mathmode >> style.preamble >> dpi;
158  style.fg_color = fg;
159  style.bg_color = bg;
160  style.dpi = dpi;
161  return stream;
162 }
163 KLF_EXPORT bool operator==(const KLFLegacyData::KLFStyle& a, const KLFLegacyData::KLFStyle& b)
164 {
165  return a.name == b.name &&
166  a.fg_color == b.fg_color &&
167  a.bg_color == b.bg_color &&
168  a.mathmode == b.mathmode &&
169  a.preamble == b.preamble &&
170  a.dpi == b.dpi;
171 }
172 
173 
174 
175 // -------------------------------------------
176 
177 // KLFLibLegacyFileDataPrivate
178 
179 
180 // static
181 QMap<QString,KLFLibLegacyFileDataPrivate*> KLFLibLegacyFileDataPrivate::staticFileDataObjects;
182 
183 
184 
186 {
187  KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+"("+fnm+")") ;
188 
189  QString fname = (!fnm.isEmpty() ? fnm : filename);
190 
191  klfDbg("loading from file "<<fname<<" (our filename="<<filename<<")") ;
192 
193  QFile fimp(fname);
194  if ( ! fimp.open(QIODevice::ReadOnly) ) {
195  qWarning("Unable to open library file %s!", qPrintable(fname));
196  return false;
197  }
198  QDataStream stream(&fimp);
199  // Qt3-compatible stream input
200  stream.setVersion(QDataStream::Qt_3_3);
201  QString s1;
202  stream >> s1;
203  if (s1 == "KLATEXFORMULA_LIBRARY_EXPORT") {
204  // opening an export file (*.klf)
206  qint16 vmaj, vmin;
207  stream >> vmaj >> vmin; // these are not needed, format has not changed in .klf export files.
208  stream >> resources >> library;
209  if (!stream.atEnd() && stream.status() == QDataStream::Ok)
210  stream >> metadata;
211  } else if (s1 == "KLATEXFORMULA_LIBRARY") {
212  // opening a library file (~/.klatexformula/library)
214  qint16 vmaj, vmin;
215  stream >> vmaj >> vmin;
216  if (vmaj <= 2) {
217  stream.setVersion(QDataStream::Qt_3_3);
218  } else {
219  qint16 version;
220  stream >> version;
221  stream.setVersion(version);
222  }
223  quint32 lib_max_id;
224  stream >> lib_max_id; // will not be used...
225  // now read the library itself.
226  stream >> resources >> library;
227  // the meta-data cannot have been written by KLF 3.0--3.1 but we may possibly already have
228  // written to this file with klf 3.2
229  if (!stream.atEnd() && stream.status() == QDataStream::Ok)
230  stream >> metadata;
231  } else if (s1 == "KLATEXFORMULA_HISTORY") {
232  // opening a post-2.0, pre-2.1 "history" file (no "library" yet)
234  qint16 vmaj, vmin;
235  stream >> vmaj >> vmin;
237  quint32 lib_max_id;
238  stream >> lib_max_id >> history;
239 
241  KLFLegacyData::KLFLibraryResource historyresource;
242  historyresource.id = KLFLegacyData::LibResource_History;
243  historyresource.name = tr("History");
244  resources.append(historyresource);
246  library[historyresource] = history;
247 
248  } else {
249  qWarning("Error: Library file `%s' is invalid library file or corrupt!", qPrintable(fname));
250  return false;
251  }
252 
253  // update KLFLibraryItem::MaxId
254  int k;
255  for (k = 0; k < resources.size(); ++k) {
257  int j;
258  for (j = 0; j < ll.size(); ++j) {
259  if (ll[j].id >= KLFLegacyData::KLFLibraryItem::MaxId)
261  }
262  }
263  haschanges = false;
264  return true;
265 }
266 
268 {
269  KLF_DEBUG_TIME_BLOCK(KLF_FUNC_NAME+"("+fnm+")") ;
270 
271  QString fname = (!fnm.isEmpty() ? fnm : filename) ;
272  klfDbg(" saving to file "<<fname<<" a "<<legacyLibType<<"-type library with N="<<resources.size()
273  <<" resources (our filename="<<filename<<")") ;
274  QFile fsav(fname);
275  if ( ! fsav.open(QIODevice::WriteOnly) ) {
276  qWarning("Can't write to file %s!", qPrintable(fname));
277  QMessageBox::critical(NULL, tr("Error"), tr("Can't write to file %1").arg(fname));
278  return false;
279  }
280  QDataStream stream(&fsav);
281 
282  // WE'RE WRITING KLF 2.1 compatible output, so we write as being version 2.1
283  // This also implies that we write with QDataStream version "Qt 3.3"
284 
285  // write Qt 3.3-compatible data
286  stream.setVersion(QDataStream::Qt_3_3);
287 
289 
290  // however, for old versions of klatexformula:
291  QString cfname = canonicalFilePath(fname);
293  (cfname == canonicalFilePath(klfconfig.homeConfigDir+"/library") ||
294  (cfname.startsWith(canonicalFilePath(QDir::homePath()+"/.kde")) &&
295  (cfname.endsWith("/library") || cfname.endsWith("/history"))))) {
296  // the file name is a legacy library or history.
297  if (QFileInfo(fsav).fileName() == "history")
298  llt = LocalHistoryType;
299  if (QFileInfo(fsav).fileName() == "library")
300  llt = LocalLibraryType;
301  klfDbg("adjusted legacy lib type to save to type "<<llt<<" instead of "<<legacyLibType) ;
302  }
303 
304  switch (llt) {
305  case LocalHistoryType:
306  {
308  if (resources.size() == 0) {
309  liblist = KLFLegacyData::KLFLibraryList(); // no resources !
310  } else {
311  liblist = library[resources[0]];
312  }
313  if (resources.size() > 1) {
314  qWarning("%s: Saving an old \"history\" resource. Only one resource can be saved, "
315  "it will be the first: %s", KLF_FUNC_NAME, qPrintable(resources[0].name));
316  QMessageBox::warning(NULL, tr("Warning"),
317  tr("Saving an old \"history\" resource. Only one resource can be saved, "
318  "it will be the first: %1").arg(resources[0].name));
319  }
320  // find history resource in our
321  stream << QString("KLATEXFORMULA_HISTORY") << (qint16)2 << (qint16)0
322  << (quint32)KLFLegacyData::KLFLibraryItem::MaxId << liblist;
323  break;
324  }
325  case LocalLibraryType:
326  {
327  stream << QString("KLATEXFORMULA_LIBRARY") << (qint16)2 << (qint16)1;
328  // don't save explicitely QDataStream version: we're writing KLF 2.1-compatible;
329  // version explicitely saved only since KLF >= 3.x.
330  stream << (quint32)KLFLegacyData::KLFLibraryItem::MaxId << resources << library;
331  // additionally, save our meta-data at the end (this will be ignored by previous versions
332  // of KLF)
333  stream << metadata;
334  break;
335  }
336  case ExportLibraryType:
337  default:
338  if (llt != ExportLibraryType) {
339  qWarning("%s: bad library type %d! Falling back to '.klf'-library-export type",
340  KLF_FUNC_NAME, llt);
341  }
342 
343  stream << QString("KLATEXFORMULA_LIBRARY_EXPORT") << (qint16)2 << (qint16)1
344  << resources << library;
345  // additionally, save our meta-data at the end (this will be ignored by previous versions
346  // of KLF)
347  stream << metadata;
348 
349  klfDbg("saved export-library type. resource count: "<<resources.size()) ;
350 #ifdef KLF_DEBUG
351  if (resources.size()) {
353  klfDbg("in first resource wrote "<<llll.size()<<" items.");
354  }
355 #endif
356  break;
357  }
358 
359  if (fnm.isEmpty() || canonicalFilePath(fnm) == canonicalFilePath(filename))
360  haschanges = false; // saving to the reference file, not a copy
361  return true;
362 }
363 
364 
366 {
367  if ( ! QString::localeAwareCompare(resname, "History") ||
368  ! QString::localeAwareCompare(resname, qApp->translate("KLFMainWin", "History")) ||
369  ! QString::compare(resname, "History", Qt::CaseInsensitive) ||
370  ! QString::compare(resname, qApp->translate("KLFMainWin", "History"), Qt::CaseInsensitive) )
372  if ( ! QString::localeAwareCompare(resname, "Archive") ||
373  ! QString::localeAwareCompare(resname, qApp->translate("KLFMainWin", "Archive")) ||
374  ! QString::compare(resname, "Archive", Qt::CaseInsensitive) ||
375  ! QString::compare(resname, qApp->translate("KLFMainWin", "Archive"), Qt::CaseInsensitive) )
377 
378  return defaultId;
379 }
380 
382 {
383  int k;
384  for (k = 0; k < resources.size() && resources[k].name != resname; ++k)
385  ;
386  return k < resources.size() ? k : -1;
387 }
388 
389 
390 
391 
392 
393 
394 // -------------------------------------------
395 
396 
397 // static
399 {
401 
402  QString fname = klfUrlLocalFilePath(url);
403  if (fname.isEmpty()) {
404  klfDbgSt("Requested empty fname.") ;
405  return NULL;
406  }
407  if ( ! QFileInfo(fname).isReadable() ) {
408  qWarning("%s: file %s does not exist!", KLF_FUNC_NAME, qPrintable(fname));
409  return NULL;
410  }
411 
412  if (url.scheme() != "klf+legacy") {
413  qWarning("KLFLibLegacyEngine::openUrl(): unsupported scheme %s!", qPrintable(url.scheme()));
414  return NULL;
415  }
416 
417  QString legresname;
418  if (url.hasQueryItem("klfDefaultSubResource"))
419  legresname = url.queryItemValue("klfDefaultSubResource");
420 
421  return new KLFLibLegacyEngine(fname, legresname, url, parent);
422 }
423 
424 // static
426  QObject *parent)
427 {
429 
430  QString lrname = legacyResourceName;
431  if (QFile::exists(fileName)) {
432  // fail; we want to _CREATE_ a .klf file. Erase file before calling this function to overwrite.
433  return NULL;
434  }
435 
436  if (fileName.isEmpty()) {
437  qWarning()<<KLF_FUNC_NAME<<": file name "<<fileName<<" is empty!";
438  return NULL;
439  }
440  // if (!QFileInfo(QFileInfo(fileName).absolutePath()).isWritable()) {
441  // qWarning()<<KLF_FUNC_NAME<<": containing directory "<<QFileInfo(fileName).absolutePath()<<" is not writable.";
442  // return NULL;
443  // }
444 
445  QUrl url = QUrl::fromLocalFile(fileName);
446  url.setScheme("klf+legacy");
447 
448  if (lrname.isEmpty())
449  lrname = tr("Default Resource"); // default name...?
450  url.addQueryItem("klfDefaultSubResource", lrname);
451 
452  klfDbgSt("fileName="<<fileName<<"; canonical file path="<<QFileInfo(fileName).canonicalFilePath()
453  <<"; legacyResourceName="<<legacyResourceName);
454 
455  return new KLFLibLegacyEngine(fileName, lrname, url, parent);
456 }
457 
458 
459 // private
460 KLFLibLegacyEngine::KLFLibLegacyEngine(const QString& fileName, const QString& resname, const QUrl& url,
461  QObject *parent)
462  : KLFLibResourceSimpleEngine(url, FeatureReadOnly|FeatureLocked|FeatureSaveTo|FeatureSubResources, parent)
463 {
464  // get the data object
466  if (d == NULL) {
467  qWarning()<<KLF_FUNC_NAME<<": Couldn't get KLFLibLegacyFileDataPrivate instance for "<<fileName<<"! Expect Crash!";
468  return;
469  }
470  d->ref();
471 
472  connect(d, SIGNAL(resourcePropertyChanged(int)), this, SLOT(updateResourceProperty(int)));
473 
475 
476  // add at least one resource (baptized resname) if the library is empty
477  if (d->resources.isEmpty()) {
478  // create a resource
480  res.name = resname;
482  d->resources << res;
483  // and initialize pLibrary to contain this one empty resource.
484  d->library.clear();
486  d->haschanges = true;
487  }
488 
489  klfDbg("Opened KLFLibLegacyEngine resource `"<<fileName<<"': d="<<d<<"; resources="<<d->resources
490  <<" (me="<<this<<", d="<<d<<")\n") ;
491 }
492 
494 {
496 
497  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return ) ;
498 
499  if ( ! d->deref() ) {
500  klfDbg("last reference to the private liblegacyenginedataprivate object d="<<d<<", "
501  "saving(?) and deleting. haschanges="<<d->haschanges) ;
502  klfDbg("resources dump:\n"<<d->resources<<"\nlibrary:\n"<<d->library) ;
503  if (d->haschanges)
504  d->save();
505  delete d;
506  }
507 }
508 
509 uint KLFLibLegacyEngine::compareUrlTo(const QUrl& other, uint interestFlags) const
510 {
511  // we can only test for these flags (see doc for KLFLibResourceEngine::compareUrlTo())
512  interestFlags = interestFlags & (KlfUrlCompareBaseEqual);
513 
514  return klfUrlCompare(url(), other, interestFlags);
515 }
516 
517 
518 bool KLFLibLegacyEngine::canModifyData(const QString& subResource, ModifyType modifytype) const
519 {
520  if ( ! KLFLibResourceEngine::canModifyData(subResource, modifytype) ) {
521  klfDbg("base cannot modify resource engine...") ;
522  return false;
523  }
524 
525  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
526 
527 #ifndef Q_WS_WIN
528  // seems like windows doesn't like to test directories to be writable ...?
529 
530  if ( QFile::exists(d->fileName()) // depending on whether the file itself exists, check if
531  ? ! QFileInfo(d->fileName()).isWritable() // file itself writable
532  : ! QFileInfo(QFileInfo(d->fileName()).absolutePath()).isWritable() ) { // or containing dir writable
533  return false;
534  }
535 #endif
536 
537  return true;
538 }
539 
540 bool KLFLibLegacyEngine::canModifyProp(int propid) const
541 {
542  // all resource properties are stored in QVariantMap
544 }
545 
546 bool KLFLibLegacyEngine::canRegisterProperty(const QString& /*propName*/) const
547 {
548  // all resource properties are stored in QVariantMap
549  return canModifyProp(-1);
550 }
551 
553 {
554  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return KLFLibEntry() ) ;
555 
556  int index = d->findResourceName(resource);
557  if (index < 0)
558  return KLFLibEntry();
559 
561  // find entry with id 'id'
562  int k;
563  for (k = 0; k < ll.size() && ll[k].id != (quint32)id; ++k)
564  ;
565  if (k == ll.size()) {
566  return KLFLibEntry();
567  }
568 
569  return d->toLibEntry(ll[k]);
570 }
571 
572 
573 
575 /* */ KLFLibLegacyEngine::allEntries(const QString& resource, const QList<int>& /*wantedEntryProperties*/)
576 {
577  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return QList<KLFLibEntryWithId>() ) ;
578 
579  int rindex = d->findResourceName(resource);
580  if (rindex < 0)
581  return QList<KLFLibEntryWithId>();
582 
583  QList<KLFLibEntryWithId> entryList;
584  KLFLegacyData::KLFLibraryList ll = d->library[d->resources[rindex]];
585  int k;
586  for (k = 0; k < ll.size(); ++k) {
588  e.entry = d->toLibEntry(ll[k]);
589  e.id = ll[k].id;
590  entryList << e;
591  }
592  return entryList;
593 }
594 
595 
597 {
598  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return QStringList() ) ;
599 
600  QStringList list;
601  int k;
602  for (k = 0; k < d->resources.size(); ++k)
603  list << d->resources[k].name;
604  return list;
605 }
606 
608 {
609  // canModifyData is not sensitive to thses arguments...
610  return canModifyData(QString(), ChangeData);
611 }
612 bool KLFLibLegacyEngine::canRenameSubResource(const QString& subResource) const
613 {
614  return canModifyData(subResource, ChangeData);
615 }
616 bool KLFLibLegacyEngine::canDeleteSubResource(const QString& subResource) const
617 {
618  return subResource.length() && hasSubResource(subResource) &&
619  canModifyData(subResource, DeleteData) && subResourceList().size() > 1;
620 }
621 
623  const QString& /*subResourceTitle*/)
624 {
625  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
626 
627  quint32 newId = KLFLegacyData::LibResourceUSERMIN;
628  bool ok = true;
629  int k;
630  while (!ok && newId <= KLFLegacyData::LibResourceUSERMAX) {
631  for (k = 0; k < d->resources.size() && d->resources[k].id != newId; ++k)
632  ;
633  if (k == d->resources.size())
634  ok = true;
635  ++newId;
636  }
637  if (newId == KLFLegacyData::LibResourceUSERMAX) {
638  qWarning()<<KLF_FUNC_NAME<<"("<<subResource<<",..): no new ID could be found (!?!)";
639  return false;
640  }
642  res.name = subResource;
643  res.id = d->getReservedResourceId(subResource, newId);
644 
645  d->resources.push_back(res);
647  d->haschanges = true;
648 
649  emit subResourceCreated(subResource);
650 
651  return true;
652 }
653 
654 bool KLFLibLegacyEngine::renameSubResource(const QString& subResource, const QString& subResourceNewName)
655 {
656  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
657  int rindex = d->findResourceName(subResource);
658  if (rindex < 0) {
659  qWarning()<<KLF_FUNC_NAME<<": can't find sub-resource "<<subResource<<" in our data.";
660  return false;
661  }
662  KLFLegacyData::KLFLibraryResource & resref = d->resources[rindex];
663  // remove from library lists, keep the list
664  KLFLegacyData::KLFLibraryList liblist = d->library.take(resref);
665 
666  // modify the resource data as requested
667  resref.name = subResourceNewName;
668  // see if the name we gave this resource is a 'reserved' name, eg. "History", or "Archive", that
669  // have specific resource IDs.
670  int possibleNewId = d->getReservedResourceId(subResource, -1);
671  if (possibleNewId != -1)
672  resref.id = possibleNewId;
673 
674  // re-insert into library list
675  d->library[resref] = liblist;
676 
677  emit subResourceRenamed(subResource, subResourceNewName);
678  return true;
679 }
680 
682 {
684  klfDbg("sub-resource: "<<subResource) ;
685 
686  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
687  if (!canDeleteSubResource(subResource)) {
688  klfDbg("Cannot delete sub-resource "<<subResource) ;
689  return false;
690  }
691  int rindex = d->findResourceName(subResource);
692  if (rindex < 0) {
693  qWarning()<<KLF_FUNC_NAME<<": can't find sub-resource "<<subResource<<" in our data.";
694  return false;
695  }
696 
697  // delete the data from our resource list and library
698 
700  // remove from library lists, keep the list
701  d->library.remove(res);
702 
703  emit subResourceDeleted(subResource);
704  return true;
705 }
706 
707 
709 {
710  klfDbg( "() our url="<<url()<<"." ) ;
711  if (isReadOnly()) {
712  qWarning("KLFLibLegacyEngine::save: resource is read-only!");
713  return false;
714  }
715  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
716 
717  return d->save();
718 }
719 
721 {
722  d->autoSaveTimer->stop();
723  if (intervalms > 0) {
724  d->autoSaveTimer->setInterval(intervalms);
725  d->autoSaveTimer->start();
726  }
727 }
728 
730  const KLFLibEntryList& entrylist)
731 {
732  klfDbg("subResource="<<subResource<<"; entrylist="<<entrylist) ;
733 
734  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return QList<entryId>() ) ;
735 
736  if ( entrylist.size() == 0 )
737  return QList<entryId>();
738  if (!canModifyData(subResource, InsertData)) {
739  klfDbg("cannot modify data.") ;
740  return QList<entryId>();
741  }
742 
743  int index = d->findResourceName(subResource);
744  if (index < 0) {
745  klfDbg("cannot find sub-resource: "<<subResource) ;
746  return QList<entryId>();
747  }
748 
749  QList<entryId> newIds;
750 
751  int k;
752  for (k = 0; k < entrylist.size(); ++k) {
753  KLFLegacyData::KLFLibraryItem item = d->toLegacyLibItem(entrylist[k]);
754  d->library[d->resources[index]] << item;
755  newIds << item.id;
756  }
757  d->haschanges = true;
758 
759  emit dataChanged(subResource, InsertData, newIds);
760 
761  klfDbg("finished inserting items. d="<<d<<"; dumping resources:\n"<<d->resources
762  <<"\nand library:\n"<<d->library) ;
763 
764  return newIds;
765 }
766 
767 bool KLFLibLegacyEngine::changeEntries(const QString& subResource, const QList<entryId>& idlist,
768  const QList<int>& properties, const QList<QVariant>& values)
769 {
770  if (idlist.size() == 0)
771  return true;
772  if (!canModifyData(subResource, ChangeData))
773  return false;
774 
775  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
776 
777  int index = d->findResourceName(subResource);
778  if (index < 0)
779  return false;
780 
781  const KLFLegacyData::KLFLibraryList& ll = d->library[d->resources[index]];
782 
783  bool success = true;
784 
785  int k;
786  for (k = 0; k < idlist.size(); ++k) {
787  int libindex;
788  int j;
789  // find the entry
790  for (libindex = 0; libindex < ll.size() && ll[libindex].id != (quint32)idlist[k]; ++libindex)
791  ;
792  if (libindex == ll.size()) {
793  qWarning()<<KLF_FUNC_NAME<<": Can't find entry with id "<<idlist[k];
794  success = false;
795  continue;
796  }
797  // modify this entry as requested.
798  for (j = 0; j < properties.size(); ++j) {
799  switch (properties[j]) {
800  case KLFLibEntry::Latex:
801  // remember that entry.latex has redundancy for category+tags in the form "%: ...\n% ...\n<latex>"
802  { QString curcategory = d->library[d->resources[index]][libindex].category;
803  QString curtags = d->library[d->resources[index]][libindex].tags;
804  d->library[d->resources[index]][libindex].latex =
805  KLFLibEntry::latexAddCategoryTagsComment(values[j].toString(), curcategory, curtags);
806  break;
807  }
809  d->library[d->resources[index]][libindex].datetime = values[j].toDateTime();
810  break;
812  d->library[d->resources[index]][libindex].preview = QPixmap::fromImage(values[j].value<QImage>());
813  break;
815  // remember that entry.latex has redundancy for category+tags in the form "%: ...\n% ...\n<latex>"
816  { QString curlatex =
817  KLFLibEntry::stripCategoryTagsFromLatex(d->library[d->resources[index]][libindex].latex);
818  QString newcategory = values[j].toString();
819  QString curtags = d->library[d->resources[index]][libindex].tags;
820  d->library[d->resources[index]][libindex].latex =
821  KLFLibEntry::latexAddCategoryTagsComment(curlatex, newcategory, curtags);
822  d->library[d->resources[index]][libindex].category = newcategory;
823  break;
824  }
825  case KLFLibEntry::Tags:
826  // remember that entry.latex has redundancy for category+tags in the form "%: ...\n% ...\n<latex>"
827  { QString curlatex =
828  KLFLibEntry::stripCategoryTagsFromLatex(d->library[d->resources[index]][libindex].latex);
829  QString curcategory = d->library[d->resources[index]][libindex].category;
830  QString newtags = values[j].toString();
831  d->library[d->resources[index]][libindex].latex =
832  KLFLibEntry::latexAddCategoryTagsComment(curlatex, curcategory, newtags);
833  d->library[d->resources[index]][libindex].tags = newtags;
834  break;
835  }
836  break;
837  case KLFLibEntry::Style:
838  d->library[d->resources[index]][libindex].style = d->toLegacyStyle(values[j].value<KLFStyle>());
839  break;
840  default:
841  qWarning()<<KLF_FUNC_NAME<<": Cannot set arbitrary property "<<propertyNameForId(properties[j])
842  <<"!";
843  success = false;
844  break;
845  }
846  }
847  }
848 
849 #ifdef KLF_DEBUG
850  klfDbg( ": Changed entries. Dump:" ) ;
851  const KLFLegacyData::KLFLibraryList& ll2 = d->library[d->resources[index]];
852  int kl;
853  for (kl = 0; kl < ll2.size(); ++kl)
854  klfDbg( "\t#"<<kl<<": "<<ll2[kl].latex<<" - "<<ll2[kl].category ) ;
855 #endif
856 
857  d->haschanges = true;
858 
859  emit dataChanged(subResource, ChangeData, idlist);
860 
861  return success;
862 }
863 
864 bool KLFLibLegacyEngine::deleteEntries(const QString& subResource, const QList<entryId>& idlist)
865 {
866  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
867 
868  if (idlist.isEmpty())
869  return true;
870  if (!canModifyData(subResource, DeleteData))
871  return false;
872 
873  int index = d->findResourceName(subResource);
874  if (index < 0)
875  return false;
876 
877  // now remove the requested entries
878 
879  KLFLegacyData::KLFLibraryList *ll = & d->library[d->resources[index]];
880  bool success = true;
881  int k;
882  for (k = 0; k < idlist.size(); ++k) {
883  int j;
884  for (j = 0; j < ll->size() && ll->operator[](j).id != (quint32)idlist[k]; ++j)
885  ;
886  if (j == ll->size()) {
887  qWarning("KLFLibLegacyEngine::deleteEntries: Can't find ID %d in library list in current resource.",
888  idlist[k]);
889  success = false;
890  continue;
891  }
892  // remove this entry from list
893  ll->removeAt(j);
894  }
895 
896  d->haschanges = true;
897 
898  emit dataChanged(subResource, DeleteData, idlist);
899 
900  return success;
901 }
902 
903 bool KLFLibLegacyEngine::saveTo(const QUrl& newPath)
904 {
905  KLF_ASSERT_NOT_NULL( d , "d is NULL!" , return false ) ;
906 
907  if (newPath.scheme() == "klf+legacy") {
908  return d->save(klfUrlLocalFilePath(newPath));
909  }
910  return false;
911 }
912 
914 {
916 
917  QVariantMap m = d->metadata["ResProps"].toMap();
918 
919  QString propName = propertyNameForId(propId);
920  if ( propName.isEmpty() )
921  return false;
922 
923  if (m.contains(propName) && m[propName] == value)
924  return true; // nothing to do
925 
926  m[propName] = value;
927 
928  d->metadata["ResProps"] = QVariant(m);
929  d->haschanges = true;
930 
931  d->emitResourcePropertyChanged(propId);
932 
933  return true;
934 }
935 
937 {
939  klfDbg("property id="<<propId) ;
940 
941  // need KLFPropertizedObject:: explicit scopes to disambiguate from QObject's functions
942 
943  const QMap<QString,QVariant> resprops = d->metadata["ResProps"].toMap();
944 
945  if (propId < 0) {
946  // read and update all the properties
948  // set some default values for some properties if they have not been set
955  } else {
957  KLFPropertizedObject::setProperty(propId, resprops[propName]);
958  }
959  emit resourcePropertyChanged(propId);
960 }
961 
962 
963 // ------------------------------------
964 
965 
967 {
968  klfDbg("file "<<fileName);
969 
970  if (fileName.endsWith(".klf")) {
971  klfDbg("has .klf extension.") ;
972  return QLatin1String("klf+legacy");
973  }
974 
975  QFile f(fileName);
976  if ( ! f.open(QIODevice::ReadOnly) ) {
977  qWarning()<<KLF_FUNC_NAME<<": Can't open file: "<<fileName;
978  return QString();
979  }
980  QDataStream stream(&f);
981  // Qt3-compatible stream input
982  stream.setVersion(QDataStream::Qt_3_3);
983  QString s1;
984  stream >> s1;
985  klfDbg("read line: got magic "<<s1);
986  if (s1 == QLatin1String("KLATEXFORMULA_LIBRARY_EXPORT") ||
987  s1 == QLatin1String("KLATEXFORMULA_LIBRARY") ||
988  s1 == QLatin1String("KLATEXFORMULA_HISTORY"))
989  return QLatin1String("klf+legacy");
990 
991  return QString();
992 }
993 
994 // ------------------------------------
995 
996 
998  : KLFLibEngineFactory(parent)
999 {
1001  f.scheme = QLatin1String("klf+legacy");
1002  f.filepattern = QLatin1String("*.klf");
1003  f.filter = QString("%1 (%2)").arg(schemeTitle(f.scheme), f.filepattern);
1006 }
1007 
1009 {
1010  return QStringList() << QLatin1String("klf+legacy");
1011 }
1012 
1014 {
1015  if (scheme == QLatin1String("klf+legacy"))
1016  return tr("KLatexFormula Library Export File");
1017  return QString();
1018 }
1019 
1020 
1022 {
1023  if (scheme == QLatin1String("klf+legacy"))
1024  return FuncOpen|FuncCreate;
1025  return 0;
1026 }
1027 
1029 {
1030  if (scheme == QLatin1String("klf+legacy"))
1031  return QLatin1String("LocalFile");
1032  return 0;
1033 }
1034 
1035 
1037 {
1038  return KLFLibLegacyEngine::openUrl(location, parent);
1039 }
1040 
1042  const Parameters& parameters,
1043  QObject *parent)
1044 {
1045  QString defsubres = parameters["klfDefaultSubResource"].toString();
1046  if (defsubres.isEmpty())
1047  defsubres = QLatin1String("Table1");
1048 
1049  if (scheme == QLatin1String("klf+legacy")) {
1050  if ( !parameters.contains("Filename") ) {
1051  qWarning()
1052  <<"KLFLibLegacyEngineFactory::createResource: bad parameters. They do not contain `Filename': "
1053  <<parameters;
1054  return NULL;
1055  }
1056  return KLFLibLegacyEngine::createDotKLF(parameters["Filename"].toString(),
1057  defsubres, parent);
1058  }
1059  qWarning()<<"KLFLibLegacyEngineFactory::createResource("<<scheme<<","<<parameters<<","<<parent<<"):"
1060  <<"Bad scheme!";
1061  return NULL;
1062 }
1063 
1064 
1065 
static QString categoryFromLatex(const QString &latex)
Definition: klflib.cpp:122
static KLFLegacyData::KLFStyle toLegacyStyle(const KLFStyle &style)
QList< KLFLibraryResource > KLFLibraryResourceList
contains(const Key &key)
void updateResourceProperty(int propId)
virtual bool canDeleteSubResource(const QString &subResource) const
int findResourceName(const QString &resname)
push_back(const T &value)
virtual QStringList subResourceList() const
KLFConfig klfconfig
Definition: klfconfig.cpp:88
static KLFLibEntry toLibEntry(const KLFLegacyData::KLFLibraryItem &item)
KLF_EXPORT uint klfUrlCompare(const QUrl &url1, const QUrl &url2, uint interestFlags, const QStringList &interestQueryItems)
arg(const QString &a, int fieldWidth=0, const QChar &fillChar=QLatin1Char( ' ')
KLFLib::entryId entryId
Definition: klflib.h:444
virtual bool createSubResource(const QString &subResource, const QString &subResourceTitle)
removeAt(int i)
virtual void setProperty(const QString &propname, const QVariant &value)
#define klfDbg(streamableItems)
void subResourceRenamed(const QString &oldSubResourceName, const QString &newSubResourceName)
Emitted when a sub-resource is renamed.
fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
#define KLF_DEBUG_BLOCK(msg)
static QString stripCategoryTagsFromLatex(const QString &latex)
Definition: klflib.cpp:145
virtual bool saveTo(const QUrl &newPath)
virtual bool deleteSubResource(const QString &subResource)
takeAt(int i)
KLFLegacyData::KLFStyle style
hasQueryItem(const QString &key)
homePath()
static QString tagsFromLatex(const QString &latex)
Definition: klflib.cpp:131
tr(const char *sourceText, const char *comment=0, int n=-1)
virtual KLFLibEntry entry(const QString &resource, entryId id)
bool load(const QString &fname=QString())
virtual uint compareUrlTo(const QUrl &other, uint interestFlags=0xfffffff) const
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
The Latex Code of the equation.
Definition: klflib.h:62
virtual QString toString(uint toStringFlags=0) const
virtual bool isReadOnly() const
query read-only state
Definition: klflib.h:595
static void addLocalFileType(const LocalFileType &fileType)
void dataChanged(const QString &subResource, int modificationType, const QList< KLFLib::entryId > &entryIdList)
Emitted when data has changed.
append(const T &value)
QDebug & operator<<(QDebug &s, const KLFLegacyData::KLFLibraryItem &item)
virtual bool deleteEntries(const QString &subResource, const QList< entryId > &idlist)
void subResourceCreated(const QString &newSubResource)
Emitted when a sub-resource is created.
KLF_EXPORT QString klfUrlLocalFilePath(const QUrl &url)
void subResourceDeleted(const QString &subResource)
Emitted when a sub-resource is deleted.
static KLFLibLegacyFileDataPrivate * instanceFor(const QString fname, bool starttimer)
void resourcePropertyChanged(int propId)
Emitted when a resource property changes.
A known local file type for KLFLibBasicWidgetFactory-created widgets.
Definition: klflibview.h:1141
The Legacy Library support for the KLFLib framework.
KLFLibLegacyEngineFactory(QObject *parent=NULL)
startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive)
setScheme(const QString &scheme)
KLFLegacyData::KLFLibrary library
Open Resources.
Definition: klflib.h:1696
endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive)
compare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs)
static KLFLegacyData::KLFLibraryItem toLegacyLibItem(const KLFLibEntry &entry)
virtual QString schemeTitle(const QString &scheme) const
virtual QList< KLFLibEntryWithId > allEntries(const QString &resource, const QList< int > &wantedEntryProperties=QList< int >())
void emitResourcePropertyChanged(int propId)
KLF_EXPORT bool operator<(const KLFLegacyData::KLFLibraryResource a, const KLFLegacyData::KLFLibraryResource b)
The Category to which eq. belongs (path-style string)
Definition: klflib.h:66
static QString canonicalFilePath(const QString &fname)
open(OpenMode mode)
scheme()
KLFStyle style used.
Definition: klflib.h:68
#define KLF_DEBUG_TIME_BLOCK(msg)
virtual bool canModifyProp(int propid) const
virtual bool changeEntries(const QString &subResource, const QList< entryId > &idlist, const QList< int > &properties, const QList< QVariant > &values)
setVersion(int v)
static QString latexAddCategoryTagsComment(const QString &latex, const QString &category, const QString &tags)
Definition: klflib.cpp:179
virtual bool canModifyData(const QString &subResource, ModifyType modifytype) const
Definition: klflib.cpp:472
#define KLF_FUNC_NAME
Tags about the equation (string)
Definition: klflib.h:67
virtual bool saveResourceProperty(int propId, const QVariant &value)
fromValue(const T &value)
virtual QString correspondingWidgetType(const QString &scheme) const
Provides a simple API for reading library resources.
Definition: klflib.h:1588
virtual QStringList supportedTypes() const
static KLFLibLegacyEngine * openUrl(const QUrl &url, QObject *parent=NULL)
QMap< KLFLibraryResource, KLFLibraryList > KLFLibrary
KLF_EXPORT bool operator==(const KLFLegacyData::KLFLibraryItem &a, const KLFLegacyData::KLFLibraryItem &b)
QString homeConfigDir
Definition: klfconfig.h:151
virtual QList< entryId > insertEntries(const QString &subResource, const KLFLibEntryList &entries)
KLFLegacyData::KLFLibraryResourceList resources
Create New Resources.
Definition: klflib.h:1697
virtual KLFLibResourceEngine * createResource(const QString &scheme, const Parameters &parameters, QObject *parent=NULL)
QString filter
eg. "Local Library Database File (*.klf.db)"
Definition: klflibview.h:1144
An entry (single formula) in the library.
Definition: klflib.h:55
QString guessScheme(const QString &fileName) const
virtual bool hasSubResource(const QString &subResource) const
Definition: klflib.cpp:496
virtual bool renameSubResource(const QString &subResource, const QString &subResourceName)
#define klfDbgSt(streamableItems)
An Image Preview of equation (scaled down QImage)
Definition: klflib.h:64
virtual uint schemeFunctions(const QString &scheme) const
critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
start(int msec)
void setAllProperties(const QMap< QString, QVariant > &propValues)
addQueryItem(const QString &key, const QString &value)
QString scheme
eg. "klf+sqlite"
Definition: klflibview.h:1142
warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
virtual QVariant property(const QString &propName) const
A KLFLibEntry in combination with a KLFLib::entryId.
Definition: klflib.h:447
virtual QUrl url(uint flags=0x0) const
query URL
Definition: klflib.cpp:457
virtual bool canRegisterProperty(const QString &propName) const
virtual bool canModifyData(const QString &subRes, ModifyType modifytype) const
An abstract resource engine.
Definition: klflib.h:440
virtual bool canRenameSubResource(const QString &subResource) const
QString propertyNameForId(int propId) const
The Date/Time at which the equation was evaluated.
Definition: klflib.h:63
virtual bool canCreateSubResource() const
connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type=Qt::AutoCompatConnection)
virtual void setAutoSaveInterval(int intervalms)
KLF_EXPORT QDataStream & operator>>(QDataStream &stream, KLFLegacyData::KLFLibraryItem &item)
QList< KLFLibraryItem > KLFLibraryList
bool save(const QString &fname=QString())
virtual bool canModifyProp(int propId) const
Definition: klflib.cpp:485
take(const Key &key)
queryItemValue(const QString &key)
localeAwareCompare(const QString &s1, const QString &s2)
int getReservedResourceId(const QString &resourceName, int defaultId)
KLF_EXPORT bool resources_equal_for_import(const KLFLegacyData::KLFLibraryResource a, const KLFLegacyData::KLFLibraryResource b)
static KLFLibLegacyEngine * createDotKLF(const QString &fileName, QString legacyResourceName, QObject *parent=NULL)
fromLocalFile(const QString &localFile)
virtual KLFLibResourceEngine * openResource(const QUrl &location, QObject *parent=NULL)
remove(const Key &key)
QString filepattern
eg. "*.klf.db"
Definition: klflibview.h:1143

Generated by doxygen 1.8.6