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