Crossfire Server, Trunk  R20513
CREResourcesWindow.cpp
Go to the documentation of this file.
1 #include <Qt>
2 #include <QtGui>
3 
4 #include "CREResourcesWindow.h"
5 #include "CREUtils.h"
6 #include "CREPixmap.h"
7 
8 #include "CREFilter.h"
9 #include "CREFilterDialog.h"
10 #include "CREFilterDefinition.h"
11 
12 #include "CRESettings.h"
13 
14 #include "CREReportDialog.h"
15 #include "CREReportDisplay.h"
16 #include "CREReportDefinition.h"
17 
18 #include "CRETreeItemEmpty.h"
19 #include "CRETreeItemQuest.h"
20 
21 #include "CREAnimationPanel.h"
22 #include "CREArchetypePanel.h"
23 #include "CRETreasurePanel.h"
24 #include "CREArtifactPanel.h"
25 #include "CREFormulaePanel.h"
26 #include "CREFacePanel.h"
27 #include "CREMapPanel.h"
28 #include "CRERegionPanel.h"
29 #include "CREQuestPanel.h"
30 #include "CREMessagePanel.h"
31 #include "CREScriptPanel.h"
32 
33 #include "CREWrapperObject.h"
34 #include "CREWrapperArtifact.h"
35 #include "CREWrapperFormulae.h"
36 
38 #include "Quest.h"
39 #include "QuestManager.h"
40 #include "MessageFile.h"
41 #include "ScriptFileManager.h"
42 
43 #include "CREScriptEngine.h"
44 
45 #include "CRERandomMap.h"
46 #include "CRERandomMapPanel.h"
47 
48 extern "C" {
49 #include "global.h"
50 #include "recipe.h"
51 #include "MessageManager.h"
52 #include "ResourcesManager.h"
53 #include "ScriptFile.h"
54 }
55 
57 {
58  QApplication::setOverrideCursor(Qt::WaitCursor);
59 
60  myDisplay = mode;
61 
62  Q_ASSERT(store);
63  myStore = store;
64  Q_ASSERT(quests);
65  myQuests = quests;
66  Q_ASSERT(messages);
67  myMessages = messages;
68  Q_ASSERT(resources);
69  myResources = resources;
70  Q_ASSERT(scripts);
71  myScripts = scripts;
72 
73  setAttribute(Qt::WA_DeleteOnClose);
74 
75  QVBoxLayout* layout = new QVBoxLayout(this);
76 
77  myFiltersMenu = new QMenu(this);
78  QHBoxLayout* buttons = new QHBoxLayout();
79  myFilterButton = new QPushButton(tr("Filter..."), this);
80  myFilterButton->setMenu(myFiltersMenu);
81  buttons->addWidget(myFilterButton);
82 
83  myReportsMenu = new QMenu(this);
84  QPushButton* report = new QPushButton(tr("Report"), this);
85  report->setMenu(myReportsMenu);
86  buttons->addWidget(report);
87 
88  layout->addLayout(buttons);
89 
90  mySplitter = new QSplitter(this);
91  layout->addWidget(mySplitter);
92  myTree = new QTreeWidget(this);
93  mySplitter->addWidget(myTree);
94  myTree->setIconSize(QSize(32, 32));
95  myTree->setHeaderLabel(tr("All resources"));
96 // myTree->sortByColumn(0, Qt::AscendingOrder);
97 
98 // myTree->setSortingEnabled(true);
99  myTree->setContextMenuPolicy(Qt::CustomContextMenu);
100  connect(myTree, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(treeCustomMenu(const QPoint&)));
101  connect(myTree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(tree_currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
102 
103  /* dummy panel to display for empty items */
104  CREPanel* dummy = new CREPanel();
105  QVBoxLayout* dl = new QVBoxLayout(dummy);
106  dl->addWidget(new QLabel(tr("No details available."), dummy));
107  addPanel("(dummy)", dummy);
108  dummy->setVisible(true);
109  myCurrentPanel = dummy;
110 
111  fillData();
112 
113  connect(&myFiltersMapper, SIGNAL(mapped(QObject*)), this, SLOT(onFilterChange(QObject*)));
114  updateFilters();
115  connect(&myReportsMapper, SIGNAL(mapped(QObject*)), this, SLOT(onReportChange(QObject*)));
116  updateReports();
117 
118  QApplication::restoreOverrideCursor();
119 }
120 
122 {
123  qDeleteAll(myTreeItems);
124  myTreeItems.clear();
125  qDeleteAll(myDisplayedItems);
126  myDisplayedItems.clear();
127 }
128 
130 {
131  QApplication::setOverrideCursor(Qt::WaitCursor);
132 
133  myTree->clear();
134  qDeleteAll(myTreeItems);
135  myTreeItems.clear();
136  qDeleteAll(myDisplayedItems);
137  myDisplayedItems.clear();
138 
139  QString title;
141  {
142  title = tr("Archetypes");
143  fillArchetypes();
144  }
146  {
147  title = tr("Animations");
148  fillAnimations();
149  }
151  {
152  title = tr("Treasures");
153  fillTreasures();
154  }
156  {
157  title = tr("Formulae");
158  fillFormulae();
159  }
161  {
162  title = tr("Artifacts");
163  fillArtifacts();
164  }
165  if (myDisplay & DisplayFaces)
166  {
167  title = tr("Faces");
168  fillFaces();
169  }
170  if (myDisplay & DisplayMaps)
171  {
172  title = tr("Maps");
173  fillMaps();
174  }
175  if (myDisplay & DisplayQuests)
176  {
177  title = tr("Quests");
178  fillQuests();
179  }
181  {
182  title = tr("NPC dialogs");
183  fillMessages();
184  }
186  {
187  title = tr("Scripts");
188  fillScripts();
189  }
191  {
192  title = tr("Random maps");
193  fillRandomMaps();
194  }
195 
196  if (myDisplay == DisplayAll)
197  title = tr("All resources");
198 
199  if (myTree->topLevelItemCount() == 1)
200  myTree->topLevelItem(0)->setExpanded(true);
201 
202  setWindowTitle(title);
203 
204  myTree->resizeColumnToContents(0);
205 
206  QApplication::restoreOverrideCursor();
207 }
208 
210 {
211  if (myCurrentPanel != NULL)
213 }
214 
215 void CREResourcesWindow::tree_currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem*)
216 {
217  if (!current || current->data(0, Qt::UserRole).value<void*>() == NULL)
218  return;
219  CRETreeItem* item = reinterpret_cast<CRETreeItem*>(current->data(0, Qt::UserRole).value<void*>());
220  if (!item)
221  return;
222 
223  commitData();
224 
225  CREPanel* newPanel = myPanels[item->getPanelName()];
226  if (!newPanel)
227  {
228 // printf("no panel for %s\n", qPrintable(item->getPanelName()));
229  return;
230  }
231 
232  item->fillPanel(newPanel);
233 
234  if (myCurrentPanel != newPanel)
235  {
236  if (myCurrentPanel)
237  myCurrentPanel->setVisible(false);
238  newPanel->setVisible(true);
239  myCurrentPanel = newPanel;
240  }
241 }
242 
244 {
245  QTreeWidgetItem* animationsNode = CREUtils::animationNode(NULL);
246  myTreeItems.append(new CRETreeItemEmpty());
247  animationsNode->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
248  myTree->addTopLevelItem(animationsNode);
249 
250  QTreeWidgetItem* item;
251 
252  QStringList animations = myResources->allAnimations();
253  // There is the "bug" animation to consider
254  foreach(QString name, animations)
255  {
256  const animations_struct* anim = myResources->animation(name);
257  item = CREUtils::animationNode(anim, animationsNode);
258  myTreeItems.append(new CRETTreeItem<const animations_struct>(anim, "Animation"));
259  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
260  }
261 
262  addPanel("Animation", new CREAnimationPanel());
263 }
264 
266 {
267  QTreeWidgetItem* item, *sub;
268  const treasurelist* list;
269  const treasure* treasure;
270 
271  QTreeWidgetItem* treasures = CREUtils::treasureNode(NULL);
272  myTreeItems.append(new CRETreeItemEmpty());
273  treasures->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
274  myTree->addTopLevelItem(treasures);
275 
276  QStringList names = myResources->treasureLists();
277 
278  foreach(QString name, names)
279  {
280  list = myResources->treasureList(name);
281  item = CREUtils::treasureNode(list, treasures);
282 
283  myTreeItems.append(new CRETTreeItem<const treasurelist>(list, "Treasure"));
284  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
285  //item->setData(0, Qt::UserRole, allTreasures[t]);
286  if (list->total_chance != 0)
287  item->setText(1, QString::number(list->total_chance));
288 
289  for (treasure = list->items; treasure; treasure = treasure->next)
290  {
291  sub = CREUtils::treasureNode(treasure, list, item);
292  if (treasure->chance)
293  sub->setText(1, QString::number(treasure->chance));
294  myTreeItems.append(new CRETTreeItem<const treasurelist>(list, "Treasure"));
295  sub->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
296  }
297  }
298 
299  addPanel("Treasure", new CRETreasurePanel());
300 }
301 
303 {
304  QTreeWidgetItem* item, *root, *sub;
305  const archt* arch;
306  int added = 0, count = 0;
307 
308  root = CREUtils::archetypeNode(NULL);
309  myTreeItems.append(new CRETreeItemEmpty());
310  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
311  myTree->addTopLevelItem(root);
312 
313  CREWrapperObject* wrapper = NULL;
314 
315  QStringList archs = myResources->archetypes();
316 
317  foreach(QString name, archs)
318  {
319  arch = myResources->archetype(name);
320  count++;
321  if (!wrapper)
322  wrapper = new CREWrapperObject();
323  wrapper->setObject(&arch->clone);
324  if (!myFilter.showItem(wrapper))
325  continue;
326 
327  item = CREUtils::archetypeNode(arch, root);
328  myTreeItems.append(new CRETTreeItem<const archt>(arch, "Archetype"));
329  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
330 
331  for (archt* more = arch->more; more; more = more->more)
332  {
333  sub = CREUtils::archetypeNode(more, item);
334  myTreeItems.append(new CRETTreeItem<const archt>(more, "Archetype"));
335  sub->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
336  }
337  myDisplayedItems.append(wrapper);
338  wrapper = NULL;
339  added++;
340  }
341 
342  delete wrapper;
343  addPanel("Archetype", new CREArchetypePanel(myStore));
344  if (added == count)
345  root->setText(0, tr("%1 [%2 items]").arg(root->text(0)).arg(count));
346  else
347  root->setText(0, tr("%1 [%2 items out of %3]").arg(root->text(0)).arg(added).arg(count));
348 }
349 
351 {
352  const recipe* r;
353  QTreeWidgetItem* root, *form, *sub;
354  CREWrapperFormulae* wrapper = NULL;
355  int count = 0, added = 0, subCount, subAdded;
356 
357  form = new QTreeWidgetItem(myTree, QStringList(tr("Formulae")));
358  myTreeItems.append(new CRETreeItemEmpty());
359  form->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
360 // myTree->addTopLevelItem(form);
361 
362  for (int ing = 1; ing <= myResources->recipeMaxIngredients() ; ing++)
363  {
364  root = new QTreeWidgetItem(form, QStringList(tr("%1 ingredients").arg(ing)));
365  subCount = 0;
366  subAdded = 0;
367 
368  QStringList recipes = myResources->recipes(ing);
369 
370  foreach(QString name, recipes)
371  {
372  r = myResources->recipe(ing, name);
373  subCount++;
374  count++;
375  if (!wrapper)
376  wrapper = new CREWrapperFormulae();
377  wrapper->setFormulae(r);
378  if (!myFilter.showItem(wrapper))
379  continue;
380 
381  sub = CREUtils::formulaeNode(r, root);
382  myTreeItems.append(new CRETTreeItem<const recipe>(r, "Formulae"));
383  sub->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
384  myDisplayedItems.append(wrapper);
385  wrapper = NULL;
386  subAdded++;
387  added++;
388  }
389  if (subCount == subAdded)
390  root->setText(0, tr("%1 [%2 items]").arg(root->text(0)).arg(subCount));
391  else
392  root->setText(0, tr("%1 [%2 items out of %3]").arg(root->text(0)).arg(added).arg(subCount));
393  }
394 
395  delete wrapper;
396  addPanel("Formulae", new CREFormulaePanel());
397  if (added == count)
398  form->setText(0, tr("%1 [%2 items]").arg(form->text(0)).arg(count));
399  else
400  form->setText(0, tr("%1 [%2 items out of %3]").arg(form->text(0)).arg(added).arg(count));
401 }
402 
404 {
405  QTreeWidgetItem* item, *root, *sub;
406  artifactlist* list;
407  const typedata* data;
408  int count = 0, added = 0;
409 
410  root = new QTreeWidgetItem(myTree, QStringList(tr("Artifacts")));
411  myTreeItems.append(new CRETreeItemEmpty());
412  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
413 
414  CREWrapperArtifact wrapper;
415 
416  for (list = first_artifactlist; list; list = list->next)
417  {
418  int subCount = 0, subAdded = 0;
419  data = get_typedata(list->type);
420 
421  item = new QTreeWidgetItem(root, QStringList(data ? data->name : tr("type %1").arg(list->type)));
422 
423  for (artifact* art = list->items; art; art = art->next)
424  {
425  count++;
426  subCount++;
427  wrapper.setArtifact(art);
428  if (!myFilter.showItem(&wrapper))
429  continue;
430 
431  sub = CREUtils::artifactNode(art, item);
432  myTreeItems.append(new CRETTreeItem<artifact>(art, "Artifact"));
433  sub->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
434  added++;
435  subAdded++;
436  }
437 
438  if (subCount == subAdded)
439  item->setText(0, tr("%1 [%2 items]").arg(item->text(0)).arg(subCount));
440  else
441  item->setText(0, tr("%1 [%2 items out of %3]").arg(item->text(0)).arg(subAdded).arg(subCount));
442  }
443 
444  addPanel("Artifact", new CREArtifactPanel());
445  if (added == count)
446  root->setText(0, tr("%1 [%2 items]").arg(root->text(0)).arg(count));
447  else
448  root->setText(0, tr("%1 [%2 items out of %3]").arg(root->text(0)).arg(added).arg(count));
449 }
450 
452 {
453  QTreeWidgetItem* item, *root;
454  const New_Face* face;
455 
456  root = CREUtils::faceNode(NULL);
457  myTreeItems.append(new CRETreeItemEmpty());
458  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
459  myTree->addTopLevelItem(root);
460 
461  QStringList faces = myResources->faces();
462 
463  foreach(QString name, faces)
464  {
465  face = myResources->face(name);
466  item = CREUtils::faceNode(face, root);
467  myTreeItems.append(new CRETTreeItem<const New_Face>(face, "Face"));
468  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
469  }
470 
471  addPanel("Face", new CREFacePanel());
472 }
473 
475 {
476  return left->displayName().compare(right->displayName(), Qt::CaseInsensitive) < 0;
477 }
478 
480 {
481  bool full = false;
482  if (myDisplay == DisplayMaps)
483  {
484  QStringList headers;
485  headers << tr("Maps") << tr("Experience");
486  myTree->setHeaderLabels(headers);
487  myTree->sortByColumn(0, Qt::AscendingOrder);
488  full = true;
489  }
490 
491  QTreeWidgetItem* regionNode, *root, *leaf;
492 
493  root = CREUtils::mapNode(NULL);
494  myTreeItems.append(new CRETreeItemEmpty());
495  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
496  myTree->addTopLevelItem(root);
497 
498  QHash<QString, region*> regions;
499  for (region* reg = first_region; reg; reg = reg->next)
500  {
501  regions[reg->name] = reg;
502  }
503 
504  QStringList names = regions.keys();
505  names.sort();
506 
507  foreach(QString name, names)
508  {
509  QList<CREMapInformation*> maps = myStore->getMapsForRegion(name);
510  qSort(maps.begin(), maps.end(), sortMapInformation);
511  regionNode = CREUtils::regionNode(name, maps.size(), root);
512  myTreeItems.append(new CRETTreeItem<region>(regions[name], "Region"));
513  regionNode->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
514  foreach(CREMapInformation* map, maps)
515  {
516  leaf = CREUtils::mapNode(map, regionNode);
517  myTreeItems.append(new CRETTreeItem<CREMapInformation>(map, "Map"));
518  leaf->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
519  if (full)
520  leaf->setText(1, tr("%1").arg(QString::number(map->experience()), 20));
521 
523  myDisplayedItems.append(map->clone());
524  }
525  }
526 
527  if (full)
528  {
529  root->setExpanded(true);
530  myTree->resizeColumnToContents(0);
531  myTree->resizeColumnToContents(1);
532  }
533 
534  addPanel("Region", new CRERegionPanel());
535  addPanel("Map", new CREMapPanel(myScripts));
536 }
537 
539 {
540  QTreeWidgetItem* item, *root;
541 
542  root = CREUtils::questsNode();
543  myTreeItems.append(new CRETreeItemQuest(NULL, root, this));
544  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
545  myTree->addTopLevelItem(root);
546 
547  QStringList codes;
548  const New_Face* face;
549 
550  foreach(Quest* quest, myQuests->quests())
551  {
552  face = myResources->face(quest->face());
553  if (face != NULL)
554  quest->setFaceNumber(face->number);
555  codes.append(quest->code());
556  }
557  codes.sort();
558 
559  foreach(QString code, codes)
560  {
561  Quest* quest = myQuests->getByCode(code);
562  item = CREUtils::questNode(quest, root);
563  myTreeItems.append(new CRETreeItemQuest(quest, item, this));
564  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
565  }
566 
567  addPanel("Quest", new CREQuestPanel(myQuests, myMessages));
568 }
569 
571 {
572  QTreeWidgetItem* item, *root;
573 
574  root = CREUtils::messagesNode();
575  myTreeItems.append(new CRETreeItemEmpty());
576  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
577  myTree->addTopLevelItem(root);
578 
579  foreach(MessageFile* message, myMessages->messages())
580  {
581  item = CREUtils::messageNode(message, root);
582  myTreeItems.append(new CRETTreeItem<MessageFile>(message, "Message"));
583  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
584  }
585 
586  addPanel("Message", new CREMessagePanel(myMessages, myQuests));
587 }
588 
589 static bool scriptLessThan(const ScriptFile* left, const ScriptFile* right)
590 {
591  return left->path().compare(right->path()) < 0;
592 }
593 
595 {
596  QTreeWidgetItem* item, *root;
597 
598  root = CREUtils::scriptsNode();
599  myTreeItems.append(new CRETreeItemEmpty());
600  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
601  myTree->addTopLevelItem(root);
602 
603  QList<ScriptFile*> scripts = myScripts->scripts();
604  qSort(scripts.begin(), scripts.end(), scriptLessThan);
605 
606  foreach(ScriptFile* script, scripts)
607  {
608  item = CREUtils::scriptNode(script, root);
609  myTreeItems.append(new CRETTreeItem<ScriptFile>(script, "Script"));
610  item->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
611  }
612 
613  addPanel("Script", new CREScriptPanel());
614 }
615 
616 void CREResourcesWindow::addPanel(QString name, CREPanel* panel)
617 {
618  panel->setVisible(false);
619  myPanels[name] = panel;
620  mySplitter->addWidget(panel);
621 }
622 
624 {
625  CREFilterDialog dlg;
626  if (dlg.exec() != QDialog::Accepted)
627  return;
628 
629  /* sending this signal will ultimately call our own updateFilters() */
630  emit filtersModified();
631 }
632 
634 {
635  CREReportDialog dlg;
636  if (dlg.exec() != QDialog::Accepted)
637  return;
638 
639  /* sending this signal will ultimately call our own updateReports() */
640  emit reportsModified();
641 }
642 
644 {
646  settings.loadFilters(myFilters);
647 
648  myFiltersMenu->clear();
649 
650  if (myFilters.filters().size() > 0)
651  {
652  QAction* clear = new QAction(tr("(none)"), this);
653  connect(clear, SIGNAL(triggered()), this, SLOT(clearFilter()));
654  myFiltersMenu->addAction(clear);
655 
656  foreach(CREFilterDefinition* filter, myFilters.filters())
657  {
658  QAction* a = new QAction(filter->name(), this);
659  myFiltersMenu->addAction(a);
660  myFiltersMapper.setMapping(a, filter);
661  connect(a, SIGNAL(triggered()), &myFiltersMapper, SLOT(map()));
662  }
663 
664  myFiltersMenu->addSeparator();
665  }
666 
667  QAction* quick = new QAction(tr("Quick filter..."), this);
668  connect(quick, SIGNAL(triggered()), this, SLOT(onQuickFilter()));
669  myFiltersMenu->addAction(quick);
670  QAction* dialog = new QAction(tr("Filters definition..."), this);
671  connect(dialog, SIGNAL(triggered()), this, SLOT(onFilter()));
672  myFiltersMenu->addAction(dialog);
673 
674  clearFilter();
675 }
676 
678 {
679  CREFilterDefinition* filter = qobject_cast<CREFilterDefinition*>(object);
680  if (filter == NULL)
681  return;
682  myFilter.setFilter(filter->filter());
683  fillData();
684  myFilterButton->setText(tr("Filter: %1").arg(filter->name()));
685 }
686 
688 {
689  bool ok;
690  QString filter = QInputDialog::getText(this, tr("Quick filter"), tr("Filter:"), QLineEdit::Normal, myFilter.filter(), &ok);
691  if (!ok)
692  return;
693  if (filter.isEmpty())
694  {
695  clearFilter();
696  return;
697  }
698  myFilter.setFilter(filter);
699  fillData();
700  myFilterButton->setText(tr("Filter: %1").arg(filter));
701 }
702 
704 {
705  myFilter.setFilter(QString());
706  fillData();
707  myFilterButton->setText(tr("Filter..."));
708 }
709 
711 {
713  settings.loadReports(myReports);
714 
715  myReportsMenu->clear();
716 
717  if (myReports.reports().size() > 0)
718  {
719  foreach(CREReportDefinition* report, myReports.reports())
720  {
721  QAction* a = new QAction(report->name(), this);
722  myReportsMenu->addAction(a);
723  myReportsMapper.setMapping(a, report);
724  connect(a, SIGNAL(triggered()), &myReportsMapper, SLOT(map()));
725  }
726 
727  myReportsMenu->addSeparator();
728  }
729 
730  QAction* dialog = new QAction(tr("Reports definition..."), this);
731  connect(dialog, SIGNAL(triggered()), this, SLOT(onReport()));
732  myReportsMenu->addAction(dialog);
733 }
734 
736 {
737  CREReportDefinition* report = qobject_cast<CREReportDefinition*>(object);
738  if (report == NULL)
739  return;
740 
741  QProgressDialog progress(tr("Generating report..."), tr("Abort report"), 0, myDisplayedItems.size() * 2, this);
742  progress.setWindowTitle(tr("Report: '%1'").arg(report->name()));
743  progress.setWindowModality(Qt::WindowModal);
744 
745  QStringList headers = report->header().split("\n");
746  QStringList fields = report->itemDisplay().split("\n");
747  QString sort = report->itemSort();
748 
749  QString text("<table><thead><tr>");
750 
751  foreach(QString header, headers)
752  {
753  text += "<th>" + header + "</th>";
754  }
755  text += "</tr></thead><tbody>";
756 
757  CREScriptEngine engine;
758 
759  progress.setLabelText(tr("Sorting items..."));
760 
761  engine.pushContext();
762 
763  sort = "(function(left, right) { return " + sort + "; })";
764  QScriptValue sortFun = engine.evaluate(sort);
765  QScriptValueList args;
766 
767  QList<QObject*> data;
768  int pos;
769  for (int i = 0; i < myDisplayedItems.size(); i++)
770  {
771  if (progress.wasCanceled())
772  return;
773 
774  args.clear();
775 
776  QScriptValue left = engine.newQObject(myDisplayedItems[i]);
777  args.append(left);
778 // engine.globalObject().setProperty("left", left);
779 
780  pos = 0;
781  while (pos < data.size())
782  {
783  QScriptValue right = engine.newQObject(data[pos]);
784  args.push_back(right);
785  //engine.globalObject().setProperty("right", right);
786  bool still = sortFun.call(QScriptValue(), args).toBoolean();
787  args.pop_back();
788  if (still == false)
789  break;
790  pos++;
791  }
792  if (pos == data.size())
793  data.append(myDisplayedItems[i]);
794  else
795  data.insert(pos, myDisplayedItems[i]);
796 
797  progress.setValue(i + 1);
798  }
799  engine.popContext();
800 
801  progress.setLabelText(tr("Generating items text..."));
802  foreach(QObject* item, data)
803  {
804  if (progress.wasCanceled())
805  return;
806 
807  text += "<tr>";
808 
809  engine.pushContext();
810  QScriptValue engineValue = engine.newQObject(item);
811  engine.globalObject().setProperty("item", engineValue);
812 
813  foreach(QString field, fields)
814  {
815  text += "<td>";
816  QString data = engine.evaluate(field).toString();
817  if (!engine.hasUncaughtException())
818  {
819  text += data;
820  }
821  text += "</td>\n";
822  }
823  engine.popContext();
824  text += "</tr>\n";
825 
826  progress.setValue(progress.value() + 1);
827  }
828  text += "</tbody></table>";
829  qDebug() << "report finished";
830 
831  CREReportDisplay display(text, tr("Report: '%1'").arg(report->name()));
832  display.exec();
833 }
834 
835 void CREResourcesWindow::fillItem(const QPoint& pos, QMenu* menu)
836 {
837  QTreeWidgetItem* node = myTree->itemAt(pos);
838  if (!node || node->data(0, Qt::UserRole).value<void*>() == NULL)
839  return;
840  CRETreeItem* item = reinterpret_cast<CRETreeItem*>(node->data(0, Qt::UserRole).value<void*>());
841  if (!item)
842  return;
843 
844  item->fillContextMenu(menu);
845 }
846 
847 void CREResourcesWindow::treeCustomMenu(const QPoint & pos)
848 {
849  QMenu menu;
850 
852  {
853  QAction* addMessage = new QAction("add message", &menu);
854  connect(addMessage, SIGNAL(triggered(bool)), this, SLOT(addMessage(bool)));
855  menu.addAction(addMessage);
856  }
857 
858  if (myDisplay & DisplayQuests)
859  {
860  QAction* addQuest = new QAction("add quest", &menu);
861  connect(addQuest, SIGNAL(triggered(bool)), this, SLOT(addQuest(bool)));
862  menu.addAction(addQuest);
863  }
864 
865  fillItem(pos, &menu);
866 
867  if (menu.actions().size() == 0)
868  return;
869  menu.exec(myTree->mapToGlobal(pos));
870 }
871 
873 {
875  /*
876  myQuests->quests().removeAll(quest);
877  fillData();
878  delete quest;
879  */
880 }
881 
883 {
884  Quest* quest = new Quest();
885  quest->setCode("(new quest)");
886  myQuests->quests().append(quest);
887  fillData();
888 }
889 
891 {
892  MessageFile* file = new MessageFile("<new file>");
893  file->setModified();
894  myMessages->messages().append(file);
895  fillData();
896 }
897 
899 {
900  return myResources;
901 }
902 
903 static bool sortRandomMap(const CRERandomMap* left, const CRERandomMap* right)
904 {
905  int name = left->map()->displayName().compare(right->map()->displayName(), Qt::CaseInsensitive);
906  if (name == 0)
907  {
908  if (left->x() < right->x())
909  return true;
910  if (left->x() == right->x() && left->y() < right->y())
911  return true;
912  return false;
913  }
914  return name < 0;
915 }
916 
918 {
919  bool full = false;
921  {
922  QStringList headers;
923  headers << tr("Random maps") << tr("Final map") << tr("Depth");
924  myTree->setHeaderLabels(headers);
925  myTree->sortByColumn(0, Qt::AscendingOrder);
926  full = true;
927  }
928 
929  QTreeWidgetItem* root = CREUtils::mapNode(NULL);
930  myTreeItems.append(new CRETreeItemEmpty());
931  root->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
932  myTree->addTopLevelItem(root);
933 
934  QList<CRERandomMap*> maps = myStore->randomMaps();
935  qSort(maps.begin(), maps.end(), sortRandomMap);
936  foreach(CRERandomMap* map, maps)
937  {
938  QString source(tr("from %1 [%2, %3]").arg(map->map()->name()).arg(map->x()).arg(map->y()));
939  QStringList data(source);
940  if (full)
941  {
942  data << map->parameters()->final_map << QString::number(map->parameters()->dungeon_depth);
943  }
944  QTreeWidgetItem* leaf = new QTreeWidgetItem(root, QStringList(data));
945  myTreeItems.append(new CRETTreeItem<CRERandomMap>(map, "Random map"));
946  leaf->setData(0, Qt::UserRole, QVariant::fromValue<void*>(myTreeItems.last()));
947  }
948 
949  root->setText(0, tr("Random maps [%1]").arg(maps.size()));
950 
951  if (full)
952  {
953  root->setExpanded(true);
954  myTree->resizeColumnToContents(0);
955  }
956 
957  addPanel("Random map", new CRERandomMapPanel());
958 }
const QString & name() const
void deleteQuest(Quest *quest)
const CREMapInformation * map() const
QHash< QString, QPointer< CREPanel > > myPanels
uint8_t type
Object type that this list represents.
Definition: artifact.h:27
QStringList archetypes() const
QList< MessageFile * > & messages()
int x() const
treasureliststruct represents one logical group of items to be generated together.
Definition: treasure.h:82
CREResourcesWindow(CREMapInformationManager *store, QuestManager *quests, MessageManager *messages, ResourcesManager *resources, ScriptFileManager *scripts, DisplayMode mode=DisplayAll)
const New_Face * face(const QString &name) const
static QTreeWidgetItem * animationNode(QTreeWidgetItem *parent)
Definition: CREUtils.cpp:182
static QTreeWidgetItem * archetypeNode(QTreeWidgetItem *parent)
Definition: CREUtils.cpp:15
static QTreeWidgetItem * artifactNode(QTreeWidgetItem *parent)
Definition: CREUtils.cpp:42
const QString & filter() const
Definition: Quest.h:32
const QString & code() const
Definition: Quest.cpp:63
const treasurelist * treasureList(const QString &name)
const animations_struct * animation(const QString &name) const
QList< CREReportDefinition * > & reports()
struct artifactstruct * items
Artifacts for this type.
Definition: artifact.h:30
char final_map[RM_SIZE]
If not empty, the path of the final map this whole maze leads to.
Definition: random_map.h:52
QStringList recipes(int count) const
void tree_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
Manage scripts for items.
QList< CREMapInformation * > getMapsForRegion(const QString &region)
static QTreeWidgetItem * questsNode()
Definition: CREUtils.cpp:212
object clone
An object from which to do object_copy()
Definition: object.h:470
Information about a script file.
Definition: ScriptFile.h:31
const QString & face() const
Definition: Quest.cpp:89
int recipeMaxIngredients() const
static bool sortRandomMap(const CRERandomMap *left, const CRERandomMap *right)
QSignalMapper myFiltersMapper
treasure is one element in a linked list, which together consist of a complete treasure-list.
Definition: treasure.h:63
virtual QString getPanelName() const =0
static struct struct_region_info ** regions
Found regions.
Definition: mapper.c:459
static QTreeWidgetItem * formulaeNode(const recipe *recipe, QTreeWidgetItem *parent)
Definition: CREUtils.cpp:141
Global type definitions and header inclusions.
Link an object type with skill needed to identify, and general name.
Definition: define.h:89
QStringList allAnimations() const
struct obj object
Main Crossfire structure, one ingame object.
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:465
static QTreeWidgetItem * faceNode(QTreeWidgetItem *parent)
Definition: CREUtils.cpp:169
const QString & displayName() const
virtual void fillPanel(QWidget *panel)=0
struct titlestruct title
Information on one title.
QList< CREFilterDefinition * > & filters()
uint16_t number
This is the image id.
Definition: face.h:15
static QTreeWidgetItem * questNode(const Quest *quest, QTreeWidgetItem *parent)
Definition: CREUtils.cpp:217
const typedata * get_typedata(int itemtype)
Definition: item.c:334
int16_t total_chance
If non-zero, only 1 item on this list should be generated.
Definition: treasure.h:84
const QString & header() const
CREMapInformationManager * myStore
void onReportChange(QObject *object)
void setModified(bool modified=true)
const archt * archetype(const QString &name) const
struct artifactliststruct * next
Next list of artifacts.
Definition: artifact.h:29
void setFilter(const QString &filter)
Definition: CREFilter.cpp:33
bool showItem(QObject *item)
Definition: CREFilter.cpp:8
CREFilterDefinitionManager myFilters
void setObject(const object *obj)
QList< CRETreeItem * > myTreeItems
static char root[500]
Path to store generated files.
Definition: mapper.c:365
const QString & itemSort() const
void onFilterChange(QObject *object)
static QTreeWidgetItem * scriptNode(const ScriptFile *script, QTreeWidgetItem *parent)
Definition: CREUtils.cpp:239
struct regiondef * next
Pointer to next region, NULL for the last one.
Definition: map.h:277
This is a game region.
Definition: map.h:276
MessageManager * myMessages
struct archt * more
Next part of a linked object.
Definition: object.h:469
const RMParms * parameters() const
static QTreeWidgetItem * scriptsNode()
Definition: CREUtils.cpp:235
This represents one animation.
Definition: face.h:26
QSignalMapper myReportsMapper
EXTERN Animations * animations
Definition: global.h:165
QList< ScriptFile * > scripts() const
const QString & path() const
Definition: ScriptFile.cpp:36
This represents all archetypes for one particular object type.
Definition: artifact.h:26
Alchemy recipe structures.
void setCode(const QString &code)
Definition: Quest.cpp:68
EXTERN artifactlist * first_artifactlist
First artifact.
Definition: global.h:121
static bool scriptLessThan(const ScriptFile *left, const ScriptFile *right)
QuestManager * myQuests
This is one artifact, ie one special item.
Definition: artifact.h:14
void setFormulae(const recipe *rec)
void addPanel(QString name, CREPanel *panel)
struct treasurestruct * items
Items in this list, linked.
Definition: treasure.h:90
QStringList treasureLists() const
QList< QObject * > myDisplayedItems
uint8_t chance
Percent chance for this item.
Definition: treasure.h:70
CREMapInformation * clone() const
const char * name
Object name.
Definition: define.h:91
QList< CRERandomMap * > randomMaps()
static QTreeWidgetItem * messagesNode()
Definition: CREUtils.cpp:225
struct treasurestruct treasure
treasure is one element in a linked list, which together consist of a complete treasure-list.
QList< const Quest * > quests() const
ScriptFileManager * myScripts
int y() const
ResourcesManager * myResources
int dungeon_depth
Definition: random_map.h:80
void treeCustomMenu(const QPoint &pos)
DisplayMode
bool sortMapInformation(const CREMapInformation *left, const CREMapInformation *right)
struct Settings settings
Server settings.
Definition: init.c:40
static QTreeWidgetItem * regionNode(const QString &name, int count, QTreeWidgetItem *parent)
Definition: CREUtils.cpp:197
virtual void commitData()
Definition: CREPanel.cpp:11
void setFaceNumber(int face)
Definition: Quest.cpp:107
QPushButton * myFilterButton
QStringList faces() const
New face structure - this enforces the notion that data is face by face only - you can not change the...
Definition: face.h:14
static quest_definition * quests
All known quests.
Definition: quest.c:93
static QTreeWidgetItem * messageNode(const MessageFile *message, QTreeWidgetItem *parent)
Definition: CREUtils.cpp:230
static QTreeWidgetItem * treasureNode(QTreeWidgetItem *parent)
Definition: CREUtils.cpp:83
EXTERN region * first_region
First region.
Definition: global.h:119
const ResourcesManager * resourcesManager() const
CREReportDefinitionManager myReports
void loadFilters(CREFilterDefinitionManager &filters)
Definition: CRESettings.cpp:48
struct treasurestruct * next
Next treasure-item in a linked list.
Definition: treasure.h:66
void setArtifact(const artifact *art)
virtual void fillContextMenu(QMenu *)
Definition: CRETreeItem.h:16
const QString & filter() const
Definition: CREFilter.cpp:28
const QString & itemDisplay() const
const QString & name() const
void fillItem(const QPoint &pos, QMenu *menu)
const recipestruct * recipe(int ingredients, const QString &name) const
void loadReports(CREReportDefinitionManager &reports)
Definition: CRESettings.cpp:60
struct artifactstruct * next
Next artifact in the list.
Definition: artifact.h:18
Quest * getByCode(const QString &code)
One alchemy recipe.
Definition: recipe.h:10
static QTreeWidgetItem * mapNode(QTreeWidgetItem *parent)
Definition: CREUtils.cpp:202
Definition: main.c:88