1 /**
2 * \file GuiBranches.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
5 *
6 * \author Edwin Leuven
7 * \author Abdelrazak Younes
8 *
9 * Full author contact details are available in file CREDITS.
10 */
11
12 #include <config.h>
13
14 #include "GuiBranches.h"
15
16 #include "ColorCache.h"
17 #include "GuiApplication.h"
18 #include "Validator.h"
19 #include "qt_helpers.h"
20
21 #include "ui_BranchesUnknownUi.h"
22
23 #include "frontends/alert.h"
24
25 #include "Buffer.h"
26 #include "BufferParams.h"
27
28 #include "support/gettext.h"
29 #include "support/lstrings.h"
30
31 #include <QKeyEvent>
32 #include <QListWidget>
33 #include <QTreeWidget>
34 #include <QTreeWidgetItem>
35 #include <QPixmap>
36 #include <QIcon>
37 #include <QColor>
38 #include <QColorDialog>
39
40 #ifdef KeyPress
41 #undef KeyPress
42 #endif
43
44 namespace lyx {
45 namespace frontend {
46
47
GuiBranches(QWidget * parent)48 GuiBranches::GuiBranches(QWidget * parent)
49 : QWidget(parent)
50 {
51 setupUi(this);
52 branchesTW->setColumnCount(3);
53 branchesTW->headerItem()->setText(0, qt_("Branch"));
54 branchesTW->headerItem()->setText(1, qt_("Activated"));
55 branchesTW->headerItem()->setText(2, qt_("Color"));
56 branchesTW->headerItem()->setText(3, qt_("Filename Suffix"));
57 branchesTW->setSortingEnabled(true);
58 branchesTW->resizeColumnToContents(1);
59 branchesTW->resizeColumnToContents(2);
60
61 undef_ = new BranchesUnknownDialog(this);
62 undef_bc_.setPolicy(ButtonPolicy::OkCancelPolicy);
63 undef_bc_.setCancel(undef_->cancelPB);
64
65 connect(undef_->branchesLW, SIGNAL(itemSelectionChanged()),
66 this, SLOT(unknownBranchSelChanged()));
67 connect(undef_->addSelectedPB, SIGNAL(clicked()),
68 this, SLOT(addUnknown()));
69 connect(undef_->addAllPB, SIGNAL(clicked()),
70 this, SLOT(addAllUnknown()));
71 connect(undef_->addSelectedPB, SIGNAL(clicked()),
72 undef_, SLOT(accept()));
73 connect(undef_->addAllPB, SIGNAL(clicked()),
74 undef_, SLOT(accept()));
75 connect(undef_->cancelPB, SIGNAL(clicked()),
76 undef_, SLOT(reject()));
77
78 newBranchLE->installEventFilter(this);
79 newBranchLE->setValidator(new NoNewLineValidator(newBranchLE));
80 }
81
82
eventFilter(QObject * obj,QEvent * event)83 bool GuiBranches::eventFilter(QObject * obj, QEvent * event)
84 {
85 QEvent::Type etype = event->type();
86 if (etype == QEvent::KeyPress
87 && obj == newBranchLE
88 && addBranchPB->isEnabled()) {
89 QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
90 int const keyPressed = keyEvent->key();
91 Qt::KeyboardModifiers const keyModifiers = keyEvent->modifiers();
92
93 if (keyPressed == Qt::Key_Enter || keyPressed == Qt::Key_Return) {
94 if (!keyModifiers) {
95 on_addBranchPB_pressed();
96 } else if (keyModifiers == Qt::ControlModifier
97 || keyModifiers == Qt::KeypadModifier
98 || keyModifiers == (Qt::ControlModifier | Qt::KeypadModifier)) {
99 on_addBranchPB_pressed();
100 newBranchLE->clearFocus();
101 okPressed();
102 }
103 event->accept();
104 return true;
105 }
106 }
107 return QObject::eventFilter(obj, event);
108 }
109
110
update(BufferParams const & params)111 void GuiBranches::update(BufferParams const & params)
112 {
113 branchlist_ = params.branchlist();
114 updateView();
115 }
116
117
updateView()118 void GuiBranches::updateView()
119 {
120 // store the selected branch
121 QTreeWidgetItem * item = branchesTW->currentItem();
122 QString sel_branch;
123 if (item != 0)
124 sel_branch = item->text(0);
125
126 branchesTW->clear();
127
128 BranchList::const_iterator it = branchlist_.begin();
129 BranchList::const_iterator const end = branchlist_.end();
130 for (; it != end; ++it) {
131 QTreeWidgetItem * newItem = new QTreeWidgetItem(branchesTW);
132
133 QString const bname = toqstr(it->branch());
134 newItem->setText(0, bname);
135 newItem->setText(1, it->isSelected() ? qt_("Yes") : qt_("No"));
136
137 QColor const itemcolor = rgb2qcolor(it->color());
138 if (itemcolor.isValid()) {
139 QPixmap coloritem(30, 10);
140 coloritem.fill(itemcolor);
141 newItem->setIcon(2, QIcon(coloritem));
142 }
143 newItem->setText(3, it->hasFileNameSuffix() ? qt_("Yes") : qt_("No"));
144 // restore selected branch
145 if (bname == sel_branch) {
146 branchesTW->setCurrentItem(newItem);
147 branchesTW->setItemSelected(newItem, true);
148 }
149 }
150 unknownPB->setEnabled(!unknown_branches_.isEmpty());
151 bool const have_sel =
152 !branchesTW->selectedItems().isEmpty();
153 removePB->setEnabled(have_sel);
154 renamePB->setEnabled(have_sel);
155 colorPB->setEnabled(have_sel);
156 activatePB->setEnabled(have_sel);
157 suffixPB->setEnabled(have_sel);
158 // emit signal
159 changed();
160 }
161
162
apply(BufferParams & params) const163 void GuiBranches::apply(BufferParams & params) const
164 {
165 params.branchlist() = branchlist_;
166 }
167
168
on_newBranchLE_textChanged(QString)169 void GuiBranches::on_newBranchLE_textChanged(QString)
170 {
171 QString const new_branch = newBranchLE->text();
172 addBranchPB->setEnabled(!new_branch.isEmpty());
173 }
174
175
on_addBranchPB_pressed()176 void GuiBranches::on_addBranchPB_pressed()
177 {
178 QString const new_branch = newBranchLE->text();
179 branchlist_.add(qstring_to_ucs4(new_branch));
180 newBranchLE->clear();
181 addBranchPB->setEnabled(false);
182 updateView();
183 }
184
185
on_removePB_pressed()186 void GuiBranches::on_removePB_pressed()
187 {
188 QTreeWidgetItem * selItem = branchesTW->currentItem();
189 QString sel_branch;
190 if (selItem != 0)
191 sel_branch = selItem->text(0);
192 if (!sel_branch.isEmpty()) {
193 branchlist_.remove(qstring_to_ucs4(sel_branch));
194 newBranchLE->clear();
195 updateView();
196 }
197 }
198
199
on_renamePB_pressed()200 void GuiBranches::on_renamePB_pressed()
201 {
202 QTreeWidgetItem * selItem = branchesTW->currentItem();
203 QString sel_branch;
204 if (selItem != 0)
205 sel_branch = selItem->text(0);
206 if (!sel_branch.isEmpty()) {
207 docstring newname;
208 docstring const oldname = qstring_to_ucs4(sel_branch);
209 if (Alert::askForText(newname, _("Enter new branch name"), oldname)) {
210 if (newname.empty() || oldname == newname)
211 return;
212 bool success = false;
213 if (branchlist_.find(newname)) {
214 docstring text = support::bformat(
215 _("A branch with the name \"%1$s\" already exists.\n"
216 "Do you want to merge branch \"%2$s\" with that one?"),
217 newname, oldname);
218 if (frontend::Alert::prompt(_("Branch already exists"),
219 text, 0, 1, _("&Merge"), _("&Cancel")) == 0)
220 success = branchlist_.rename(oldname, newname, true);
221 } else
222 success = branchlist_.rename(oldname, newname);
223 newBranchLE->clear();
224 updateView();
225
226 if (!success)
227 Alert::error(_("Renaming failed"),
228 _("The branch could not be renamed."));
229 else
230 // emit signal
231 renameBranches(oldname, newname);
232 }
233 }
234 }
235
236
on_activatePB_pressed()237 void GuiBranches::on_activatePB_pressed()
238 {
239 toggleBranch(branchesTW->currentItem());
240 }
241
242
on_suffixPB_pressed()243 void GuiBranches::on_suffixPB_pressed()
244 {
245 toggleSuffix(branchesTW->currentItem());
246 }
247
248
on_branchesTW_itemDoubleClicked(QTreeWidgetItem * item,int col)249 void GuiBranches::on_branchesTW_itemDoubleClicked(QTreeWidgetItem * item, int col)
250 {
251 if (col < 2)
252 toggleBranch(item);
253 else if (col == 2)
254 toggleColor(item);
255 else if (col == 3)
256 toggleSuffix(item);
257 }
258
259
on_branchesTW_itemSelectionChanged()260 void GuiBranches::on_branchesTW_itemSelectionChanged()
261 {
262 bool const have_sel =
263 !branchesTW->selectedItems().isEmpty();
264 removePB->setEnabled(have_sel);
265 renamePB->setEnabled(have_sel);
266 colorPB->setEnabled(have_sel);
267 activatePB->setEnabled(have_sel);
268 suffixPB->setEnabled(have_sel);
269 }
270
271
toggleBranch(QTreeWidgetItem * item)272 void GuiBranches::toggleBranch(QTreeWidgetItem * item)
273 {
274 if (item == 0)
275 return;
276
277 QString sel_branch = item->text(0);
278 if (sel_branch.isEmpty())
279 return;
280
281 Branch * branch = branchlist_.find(qstring_to_ucs4(sel_branch));
282 if (branch && branch->setSelected(!branch->isSelected())) {
283 newBranchLE->clear();
284 updateView();
285 }
286 }
287
288
on_colorPB_clicked()289 void GuiBranches::on_colorPB_clicked()
290 {
291 toggleColor(branchesTW->currentItem());
292 }
293
294
toggleColor(QTreeWidgetItem * item)295 void GuiBranches::toggleColor(QTreeWidgetItem * item)
296 {
297 if (item == 0)
298 return;
299
300 QString sel_branch = item->text(0);
301 if (sel_branch.isEmpty())
302 return;
303
304 docstring current_branch = qstring_to_ucs4(sel_branch);
305 Branch * branch = branchlist_.find(current_branch);
306 if (!branch)
307 return;
308
309 QColor const initial = rgb2qcolor(branch->color());
310 QColor ncol = QColorDialog::getColor(initial, qApp->focusWidget());
311 if (!ncol.isValid())
312 return;
313
314 // add the color to the branchlist
315 branch->setColor(fromqstr(ncol.name()));
316 newBranchLE->clear();
317 updateView();
318 }
319
320
toggleSuffix(QTreeWidgetItem * item)321 void GuiBranches::toggleSuffix(QTreeWidgetItem * item)
322 {
323 if (item == 0)
324 return;
325
326 QString sel_branch = item->text(0);
327 if (sel_branch.isEmpty())
328 return;
329
330 Branch * branch = branchlist_.find(qstring_to_ucs4(sel_branch));
331 if (branch) {
332 branch->setFileNameSuffix(!branch->hasFileNameSuffix());
333 newBranchLE->clear();
334 updateView();
335 }
336 }
337
338
on_unknownPB_pressed()339 void GuiBranches::on_unknownPB_pressed()
340 {
341 undef_->branchesLW->clear();
342 for (int i = 0; i != unknown_branches_.count(); ++i) {
343 if (branchesTW->findItems(unknown_branches_[i], Qt::MatchExactly, 0).empty())
344 undef_->branchesLW->addItem(unknown_branches_[i]);
345 }
346 unknownBranchSelChanged();
347 undef_->exec();
348 }
349
350
addUnknown()351 void GuiBranches::addUnknown()
352 {
353 QList<QListWidgetItem *> selItems =
354 undef_->branchesLW->selectedItems();
355
356 QList<QListWidgetItem *>::const_iterator it = selItems.begin();
357 for (; it != selItems.end() ; ++it) {
358 QListWidgetItem const * new_branch = *it;
359 if (new_branch) {
360 branchlist_.add(qstring_to_ucs4(new_branch->text()));
361 updateView();
362 }
363 }
364 }
365
366
addAllUnknown()367 void GuiBranches::addAllUnknown()
368 {
369 undef_->branchesLW->selectAll();
370 addUnknown();
371 }
372
373
unknownBranchSelChanged()374 void GuiBranches::unknownBranchSelChanged()
375 {
376 undef_->addSelectedPB->setEnabled(
377 !undef_->branchesLW->selectedItems().isEmpty());
378 }
379
380
381 } // namespace frontend
382 } // namespace lyx
383
384 #include "moc_GuiBranches.cpp"
385