cfgwadalias.cpp
1 //------------------------------------------------------------------------------
2 // cfgwadalias.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library 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 GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2014 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "cfgwadalias.h"
24 #include "ui_cfgwadalias.h"
25 
26 #include "configuration/doomseekerconfig.h"
27 #include "gui/commongui.h"
28 #include "pathfinder/filealias.h"
29 #include <QTimer>
30 
31 DClass<CFGWadAlias> : public Ui::CFGWadAlias
32 {
33 public:
34  enum Columns
35  {
36  ColWad,
37  ColAliases,
38  ColMatchType
39  };
40 
41  QString matchTypeHelp;
42  QTimer resizeTimer;
43 };
44 
45 DPointeredNoCopy(CFGWadAlias)
46 
47 CFGWadAlias::CFGWadAlias(QWidget *parent)
48  : ConfigPage(parent)
49 {
50  d->setupUi(this);
51 
52  d->resizeTimer.setSingleShot(true);
53  d->resizeTimer.setInterval(0);
54  connect(&d->resizeTimer, SIGNAL(timeout()), d->table, SLOT(resizeRowsToContents()));
55 
56  QHeaderView *header = d->table->horizontalHeader();
57  connect(header, SIGNAL(sectionResized(int,int,int)), &d->resizeTimer, SLOT(start()));
58 
59  header->resizeSection(PrivData<CFGWadAlias>::ColWad, 150);
60  header->setSectionResizeMode(PrivData<CFGWadAlias>::ColAliases, QHeaderView::Stretch);
61  header->resizeSection(PrivData<CFGWadAlias>::ColMatchType, 110);
62 
63  d->table->sortByColumn(PrivData<CFGWadAlias>::ColWad, Qt::AscendingOrder);
64 
65  d->matchTypeHelp = CFGWadAlias::tr("Left-to-Right will use the alias files instead of "
66  "the main file but not vice-versa.");
67  d->matchTypeHelp += "\n\n";
68  d->matchTypeHelp += CFGWadAlias::tr("All Equal will treat all files as equal and try to "
69  "match them in any combination.");
70 }
71 
72 CFGWadAlias::~CFGWadAlias()
73 {
74 }
75 
76 void CFGWadAlias::addAliasToTable(const FileAlias &alias)
77 {
78  bool wasSortingEnabled = d->table->isSortingEnabled();
79  d->table->setSortingEnabled(false);
80 
81  int row = findRowWithWad(alias.name());
82  if (row < 0)
83  {
84  row = d->table->rowCount();
85  addNewEntry();
86  applyAliasToRow(row, alias);
87  }
88  else
89  {
90  // Merge.
91  FileAlias existingAlias = aliasFromRow(row);
92  existingAlias.addAliases(alias.aliases());
93  applyAliasToRow(row, existingAlias);
94  }
95 
96  d->table->setSortingEnabled(wasSortingEnabled);
97 }
98 
99 void CFGWadAlias::addDefaults()
100 {
101  QList<FileAlias> aliases = FileAlias::standardWadAliases();
102  for (const FileAlias &alias : aliases)
103  {
104  addAliasToTable(alias);
105  }
106 }
107 
108 void CFGWadAlias::addNewEntry()
109 {
110  bool wasSortingEnabled = d->table->isSortingEnabled();
111  d->table->setSortingEnabled(false);
112 
113  int row = d->table->rowCount();
114  d->table->insertRow(row);
115  d->table->setItem(row, PrivData<CFGWadAlias>::ColWad, new QTableWidgetItem());
116  d->table->setItem(row, PrivData<CFGWadAlias>::ColAliases, new QTableWidgetItem());
117  mkMatchTypeComboBox(row);
118 
119  d->table->setSortingEnabled(wasSortingEnabled);
120  resizeRowToContents(row);
121 }
122 
123 QList<FileAlias> CFGWadAlias::aliases() const
124 {
125  QList<FileAlias> aliases;
126  for (int row = 0; row < d->table->rowCount(); ++row)
127  {
128  FileAlias alias = aliasFromRow(row);
129  if (alias.isValid())
130  aliases << alias;
131  }
132  return FileAliasList::mergeDuplicates(aliases);
133 }
134 
135 FileAlias CFGWadAlias::aliasFromRow(int row) const
136 {
137  FileAlias alias;
138  alias.setName(d->table->item(row, PrivData<CFGWadAlias>::ColWad)->text().trimmed());
139  QStringList candidateAliases = d->table->item(row, PrivData<CFGWadAlias>::ColAliases)->text().split(";");
140  for (const QString &candidateAlias : candidateAliases)
141  {
142  if (!candidateAlias.trimmed().isEmpty())
143  alias.addAlias(candidateAlias.trimmed());
144  }
145  auto cboMatchType = qobject_cast<QComboBox *>(d->table->cellWidget(
147  alias.setMatchType(static_cast<FileAlias::MatchType>(
148  cboMatchType->itemData(cboMatchType->currentIndex()).toInt()));
149  return alias;
150 }
151 
152 void CFGWadAlias::applyAliasToRow(int row, const FileAlias &alias)
153 {
154  d->table->setItem(row, PrivData<CFGWadAlias>::ColWad, toolTipItem(alias.name()));
155  d->table->setItem(row, PrivData<CFGWadAlias>::ColAliases, toolTipItem(alias.aliases().join("; ")));
156 
157  auto cboMatchType = qobject_cast<QComboBox *>(
158  d->table->cellWidget(row, PrivData<CFGWadAlias>::ColMatchType));
159  int matchTypeIdx = qMax(0, cboMatchType->findData(alias.matchType()));
160  cboMatchType->setCurrentIndex(matchTypeIdx);
161 }
162 
163 int CFGWadAlias::findRowWithWad(const QString &wadName)
164 {
165  for (int row = 0; row < d->table->rowCount(); ++row)
166  {
167  if (d->table->item(row, PrivData<CFGWadAlias>::ColWad)->text().trimmed().compare(
168  wadName.trimmed(), Qt::CaseInsensitive) == 0)
169  {
170  return row;
171  }
172  }
173  return -1;
174 }
175 
176 QIcon CFGWadAlias::icon() const
177 {
178  return QApplication::style()->standardIcon(QStyle::SP_DirOpenIcon);
179 }
180 
181 QComboBox *CFGWadAlias::mkMatchTypeComboBox(int row)
182 {
183  auto cboMatchType = new QComboBox();
184  cboMatchType->setToolTip(d->matchTypeHelp);
185  cboMatchType->addItem(tr("Left-to-Right"), FileAlias::LeftToRight);
186  cboMatchType->addItem(tr("All Equal"), FileAlias::AllEqual);
187  d->table->setCellWidget(row, PrivData<CFGWadAlias>::ColMatchType, cboMatchType);
188  return cboMatchType;
189 }
190 
192 {
193  bool wasSortingEnabled = d->table->isSortingEnabled();
194  d->table->setSortingEnabled(false);
195 
196  while (d->table->rowCount() > 0)
197  {
198  d->table->removeRow(0);
199  }
200  // Aliases from configuration are guaranteed to be unique.
201  QList<FileAlias> aliases = gConfig.doomseeker.wadAliases();
202  for (const FileAlias &alias : aliases)
203  {
204  if (alias.isValid())
205  addAliasToTable(alias);
206  }
207 
208  d->table->setSortingEnabled(wasSortingEnabled);
209 }
210 
211 void CFGWadAlias::removeSelected()
212 {
213  CommonGUI::removeSelectedRowsFromQTableWidget(d->table);
214 }
215 
216 void CFGWadAlias::resizeRowsToContents()
217 {
218  #ifdef Q_OS_WIN32
219  d->resizeTimer.start();
220  #else
221  d->table->resizeRowsToContents();
222  #endif
223 }
224 
225 void CFGWadAlias::resizeRowToContents(int row)
226 {
227  #ifdef Q_OS_WIN32
228  resizeRowsToContents(); // resizeRowToContents is not friendly on Windows.
229  #else
230  d->table->resizeRowToContents(row);
231  #endif
232 }
233 
235 {
236  gConfig.doomseeker.setWadAliases(aliases());
237 }
238 
239 void CFGWadAlias::showEvent(QShowEvent *event)
240 {
241  Q_UNUSED(event);
242  resizeRowsToContents();
243 }
244 
245 QTableWidgetItem *CFGWadAlias::toolTipItem(const QString &contents)
246 {
247  auto item = new QTableWidgetItem(contents);
248  item->setToolTip(contents);
249  return item;
250 }