1 /*
2 	Description: settings dialog
3 
4 	Author: Marco Costalba (C) 2005-2007
5 
6 	Copyright: See COPYING file that comes with this distribution
7 
8 */
9 #include <QTextCodec>
10 #include <QFileDialog>
11 #include <QFontDialog>
12 #include <QSettings>
13 #include "common.h"
14 #include "git.h"
15 #include "settingsimpl.h"
16 
17 /*
18 By default, there are two entries in the search path:
19 
20    1. SYSCONF - where SYSCONF is a directory specified when configuring Qt;
21 			by default it is INSTALL/etc/settings.
22    2. $HOME/.qt/ - where $HOME is the user's home directory.
23 */
24 
25 static const char* en[] = { "Latin1", "Big5 -- Chinese", "EUC-JP -- Japanese",
26 	"EUC-KR -- Korean", "GB18030 -- Chinese", "ISO-2022-JP -- Japanese",
27 	"Shift_JIS -- Japanese", "UTF-8 -- Unicode, 8-bit",
28 	"KOI8-R -- Russian", "KOI8-U -- Ukrainian", "ISO-8859-1 -- Western",
29 	"ISO-8859-2 -- Central European", "ISO-8859-3 -- Central European",
30 	"ISO-8859-4 -- Baltic", "ISO-8859-5 -- Cyrillic", "ISO-8859-6 -- Arabic",
31 	"ISO-8859-7 -- Greek", "ISO-8859-8 -- Hebrew, visually ordered",
32 	"ISO-8859-8-i -- Hebrew, logically ordered", "ISO-8859-9 -- Turkish",
33 	"ISO-8859-10", "ISO-8859-13", "ISO-8859-14", "ISO-8859-15 -- Western",
34 	"windows-1250 -- Central European", "windows-1251 -- Cyrillic",
35 	"windows-1252 -- Western", "windows-1253 -- Greek", "windows-1254 -- Turkish",
36 	"windows-1255 -- Hebrew", "windows-1256 -- Arabic", "windows-1257 -- Baltic",
37 	"windows-1258", 0 };
38 
39 using namespace QGit;
40 
SettingsImpl(QWidget * p,Git * g,int defTab)41 SettingsImpl::SettingsImpl(QWidget* p, Git* g, int defTab) : QDialog(p), git(g) {
42 
43 	setupUi(this);
44 	int f = flags(FLAGS_KEY);
45 	checkBoxDiffCache->setChecked(f & DIFF_INDEX_F);
46 	checkBoxNumbers->setChecked(f & NUMBERS_F);
47 	checkBoxSign->setChecked(f & SIGN_PATCH_F);
48 	checkBoxCommitSign->setChecked(f & SIGN_CMT_F);
49 	checkBoxCommitVerify->setChecked(f & VERIFY_CMT_F);
50 	checkBoxCommitUseDefMsg->setChecked(f & USE_CMT_MSG_F);
51 	checkBoxRangeSelectDialog->setChecked(f & RANGE_SELECT_F);
52 	checkBoxReopenLastRepo->setChecked(f & REOPEN_REPO_F);
53 	checkBoxOpenInEditor->setChecked(f & OPEN_IN_EDITOR_F);
54 	checkBoxRelativeDate->setChecked(f & REL_DATE_F);
55 	checkBoxLogDiffTab->setChecked(f & LOG_DIFF_TAB_F);
56 	checkBoxSmartLabels->setChecked(f & SMART_LBL_F);
57 	checkBoxMsgOnNewSHA->setChecked(f & MSG_ON_NEW_F);
58 
59 	QSettings set;
60 	SCRef APOpt(set.value(AM_P_OPT_KEY).toString());
61 	SCRef FPOpt(set.value(FMT_P_OPT_KEY).toString());
62 	SCRef extDiff(set.value(EXT_DIFF_KEY, EXT_DIFF_DEF).toString());
63 	SCRef extEditor(set.value(EXT_EDITOR_KEY, EXT_EDITOR_DEF).toString());
64 	SCRef exFile(set.value(EX_KEY, EX_DEF).toString());
65 	SCRef exPDir(set.value(EX_PER_DIR_KEY, EX_PER_DIR_DEF).toString());
66 	SCRef tmplt(set.value(CMT_TEMPL_KEY, CMT_TEMPL_DEF).toString());
67 	SCRef CMArgs(set.value(CMT_ARGS_KEY).toString());
68 
69 	lineEditApplyPatchExtraOptions->setText(APOpt);
70 	lineEditFormatPatchExtraOptions->setText(FPOpt);
71 	lineEditExternalDiffViewer->setText(extDiff);
72 	lineEditExternalEditor->setText(extEditor);
73 	lineEditExcludeFile->setText(exFile);
74 	lineEditExcludePerDir->setText(exPDir);
75 	lineEditTemplate->setText(tmplt);
76 	lineEditCommitExtraOptions->setText(CMArgs);
77 	lineEditTypeWriterFont->setText(TYPE_WRITER_FONT.toString());
78 	lineEditTypeWriterFont->setCursorPosition(0); // font description could be long
79 
80 	setupCodecsCombo();
81 	checkBoxDiffCache_toggled(checkBoxDiffCache->isChecked());
82 	tabDialog->setCurrentIndex(defTab);
83 	userInfo();
84 	comboBoxGitConfigSource_activated(0);
85 }
86 
userInfo()87 void SettingsImpl::userInfo() {
88 /*
89 	QGit::userInfo() returns a QStringList formed by
90 	triples (defined in, user, email)
91 */
92 	git->userInfo(_uInfo);
93 	if (_uInfo.count() % 3 != 0) {
94 		dbs("ASSERT in SettingsImpl::userInfo(), bad info returned");
95 		return;
96 	}
97 	bool found = false;
98 	int idx = 0;
99 	FOREACH_SL(it, _uInfo) {
100 		comboBoxUserSrc->addItem(*it);
101 		++it;
102 		if (!found && !(*it).isEmpty())
103 			found = true;
104 		if (!found)
105 			idx++;
106 		++it;
107 	}
108 	if (!found)
109 		idx = 0;
110 
111 	comboBoxUserSrc->setCurrentIndex(idx);
112 	comboBoxUserSrc_activated(idx);
113 }
114 
addConfigOption(QTreeWidgetItem * parent,QStringList paths,const QString & value)115 void SettingsImpl::addConfigOption(QTreeWidgetItem* parent, QStringList paths, const QString& value) {
116 
117     if (paths.isEmpty()) {
118         parent->setText(1, value);
119         return;
120     }
121     QString name(paths.first());
122     paths.removeFirst();
123 
124     // Options list is already ordered
125     if (parent->childCount() == 0 || name != parent->child(0)->text(0))
126         parent->addChild(new QTreeWidgetItem(parent, QStringList(name)));
127 
128     addConfigOption(parent->child(parent->childCount() - 1), paths, value);
129 }
130 
readGitConfig(const QString & source)131 void SettingsImpl::readGitConfig(const QString& source) {
132 
133     populatingGitConfig = true;
134     treeWidgetGitConfig->clear();
135     QStringList options(git->getGitConfigList(source == "Global"));
136     options.sort();
137 
138     FOREACH_SL(it, options) {
139 
140         QStringList paths = it->split("=").at(0).split(".");
141         QString value = it->split("=").at(1);
142 
143         if (paths.isEmpty() || value.isEmpty()) {
144             dbp("SettingsImpl::readGitConfig Unable to parse line %1", *it);
145             continue;
146         }
147         QString name(paths.first());
148         paths.removeFirst();
149         QList<QTreeWidgetItem*> items = treeWidgetGitConfig->findItems(name, Qt::MatchExactly);
150         QTreeWidgetItem* item;
151 
152         if (items.isEmpty())
153             item = new QTreeWidgetItem(treeWidgetGitConfig, QStringList(name));
154         else
155             item = items.first();
156 
157         addConfigOption(item, paths, value);
158     }
159     populatingGitConfig = false;
160 }
161 
treeWidgetGitConfig_itemChanged(QTreeWidgetItem * item,int i)162 void SettingsImpl::treeWidgetGitConfig_itemChanged(QTreeWidgetItem* item, int i) {
163 
164     if (populatingGitConfig)
165         return;
166     dbs(item->text(0));dbs(item->text(1));dbp("column %1", i);
167 }
168 
comboBoxUserSrc_activated(int i)169 void SettingsImpl::comboBoxUserSrc_activated(int i) {
170 
171 	lineEditAuthor->setText(_uInfo[i * 3 + 1]);
172 	lineEditMail->setText(_uInfo[i * 3 + 2]);
173 }
174 
comboBoxGitConfigSource_activated(int)175 void SettingsImpl::comboBoxGitConfigSource_activated(int) {
176 
177     readGitConfig(comboBoxGitConfigSource->currentText());
178 }
179 
writeSetting(const QString & key,const QVariant & value)180 void SettingsImpl::writeSetting(const QString& key, const QVariant& value) {
181 
182 	QSettings settings;
183 	settings.setValue(key, value);
184 }
185 
setupCodecList(QStringList & list)186 void SettingsImpl::setupCodecList(QStringList& list) {
187 
188 	int i = 0;
189 	while (en[i] != 0)
190 		list.append(QString::fromLatin1(en[i++]));
191 }
192 
setupCodecsCombo()193 void SettingsImpl::setupCodecsCombo() {
194 
195 	const QString localCodec(QTextCodec::codecForLocale()->name());
196 	QStringList codecs;
197 	codecs.append(QString("Local Codec (" + localCodec + ")"));
198 	setupCodecList(codecs);
199 	comboBoxCodecs->insertItems(0, codecs);
200 
201 	bool isGitArchive;
202 	QTextCodec* tc = git->getTextCodec(&isGitArchive);
203 	if (!isGitArchive) {
204 		comboBoxCodecs->setEnabled(false);
205 		return;
206 	}
207 	const QString curCodec(tc != 0 ? tc->name() : "Latin1");
208 	QRegExp re("*" + curCodec + "*", Qt::CaseInsensitive, QRegExp::Wildcard);
209 	int idx = codecs.indexOf(re);
210 	if (idx == -1) {
211 		dbp("ASSERT: codec <%1> not available, using local codec", curCodec);
212 		idx = 0;
213 	}
214 	comboBoxCodecs->setCurrentIndex(idx);
215 	if (idx == 0) // signal activated() will not fire in this case
216 		comboBoxCodecs_activated(0);
217 }
218 
comboBoxCodecs_activated(int idx)219 void SettingsImpl::comboBoxCodecs_activated(int idx) {
220 
221 	QString codecName(QTextCodec::codecForLocale()->name());
222 	if (idx != 0)
223 		codecName = comboBoxCodecs->currentText().section(" --", 0, 0);
224 
225 	git->setTextCodec(QTextCodec::codecForName(codecName.toLatin1()));
226 }
227 
pushButtonExtDiff_clicked()228 void SettingsImpl::pushButtonExtDiff_clicked() {
229 
230 	QString extDiffName(QFileDialog::getOpenFileName(this,
231 	                    "Select the patch viewer"));
232 	if (!extDiffName.isEmpty())
233 		lineEditExternalDiffViewer->setText(extDiffName);
234 }
235 
pushButtonExtEditor_clicked()236 void SettingsImpl::pushButtonExtEditor_clicked() {
237 
238 	QString extEditorName(QFileDialog::getOpenFileName(this,
239 	                    "Select the external editor"));
240 	if (!extEditorName.isEmpty())
241 		lineEditExternalEditor->setText(extEditorName);
242 }
243 
pushButtonFont_clicked()244 void SettingsImpl::pushButtonFont_clicked() {
245 
246 	bool ok;
247 	QFont fnt = QFontDialog::getFont(&ok, TYPE_WRITER_FONT, this);
248 	if (ok && TYPE_WRITER_FONT != fnt) {
249 
250 		TYPE_WRITER_FONT = fnt;
251 		lineEditTypeWriterFont->setText(fnt.toString());
252 		lineEditTypeWriterFont->setCursorPosition(0);
253 		writeSetting(TYPWRT_FNT_KEY, fnt.toString());
254 
255 		emit typeWriterFontChanged();
256 	}
257 }
258 
changeFlag(uint f,bool b)259 void SettingsImpl::changeFlag(uint f, bool b) {
260 
261 	setFlag(f, b);
262 	emit flagChanged(f);
263 }
264 
checkBoxDiffCache_toggled(bool b)265 void SettingsImpl::checkBoxDiffCache_toggled(bool b) {
266 
267 	lineEditExcludeFile->setEnabled(b);
268 	lineEditExcludePerDir->setEnabled(b);
269 	changeFlag(DIFF_INDEX_F, b);
270 }
271 
checkBoxNumbers_toggled(bool b)272 void SettingsImpl::checkBoxNumbers_toggled(bool b) {
273 
274 	changeFlag(NUMBERS_F, b);
275 }
276 
checkBoxSign_toggled(bool b)277 void SettingsImpl::checkBoxSign_toggled(bool b) {
278 
279 	changeFlag(SIGN_PATCH_F, b);
280 }
281 
checkBoxRangeSelectDialog_toggled(bool b)282 void SettingsImpl::checkBoxRangeSelectDialog_toggled(bool b) {
283 
284 	changeFlag(RANGE_SELECT_F, b);
285 }
286 
checkBoxReopenLastRepo_toggled(bool b)287 void SettingsImpl::checkBoxReopenLastRepo_toggled(bool b) {
288 
289 	changeFlag(REOPEN_REPO_F, b);
290 }
291 
checkBoxOpenInEditor_toggled(bool b)292 void SettingsImpl::checkBoxOpenInEditor_toggled(bool b) {
293 
294 	changeFlag(OPEN_IN_EDITOR_F, b);
295 }
296 
checkBoxRelativeDate_toggled(bool b)297 void SettingsImpl::checkBoxRelativeDate_toggled(bool b) {
298 
299 	changeFlag(REL_DATE_F, b);
300 }
301 
checkBoxLogDiffTab_toggled(bool b)302 void SettingsImpl::checkBoxLogDiffTab_toggled(bool b) {
303 
304 	changeFlag(LOG_DIFF_TAB_F, b);
305 }
306 
checkBoxSmartLabels_toggled(bool b)307 void SettingsImpl::checkBoxSmartLabels_toggled(bool b) {
308 
309 	changeFlag(SMART_LBL_F, b);
310 }
311 
checkBoxMsgOnNewSHA_toggled(bool b)312 void SettingsImpl::checkBoxMsgOnNewSHA_toggled(bool b) {
313 
314 	changeFlag(MSG_ON_NEW_F, b);
315 }
316 
checkBoxCommitSign_toggled(bool b)317 void SettingsImpl::checkBoxCommitSign_toggled(bool b) {
318 
319 	changeFlag(SIGN_CMT_F, b);
320 }
321 
checkBoxCommitVerify_toggled(bool b)322 void SettingsImpl::checkBoxCommitVerify_toggled(bool b) {
323 
324 	changeFlag(VERIFY_CMT_F, b);
325 }
326 
checkBoxCommitUseDefMsg_toggled(bool b)327 void SettingsImpl::checkBoxCommitUseDefMsg_toggled(bool b) {
328 
329 	changeFlag(USE_CMT_MSG_F, b);
330 }
331 
lineEditExternalDiffViewer_textChanged(const QString & s)332 void SettingsImpl::lineEditExternalDiffViewer_textChanged(const QString& s) {
333 
334 	writeSetting(EXT_DIFF_KEY, s);
335 }
336 
lineEditExternalEditor_textChanged(const QString & s)337 void SettingsImpl::lineEditExternalEditor_textChanged(const QString& s) {
338 
339 	writeSetting(EXT_EDITOR_KEY, s);
340 }
341 
lineEditApplyPatchExtraOptions_textChanged(const QString & s)342 void SettingsImpl::lineEditApplyPatchExtraOptions_textChanged(const QString& s) {
343 
344 	writeSetting(AM_P_OPT_KEY, s);
345 }
346 
lineEditFormatPatchExtraOptions_textChanged(const QString & s)347 void SettingsImpl::lineEditFormatPatchExtraOptions_textChanged(const QString& s) {
348 
349 	writeSetting(FMT_P_OPT_KEY, s);
350 }
351 
lineEditExcludeFile_textChanged(const QString & s)352 void SettingsImpl::lineEditExcludeFile_textChanged(const QString& s) {
353 
354 	writeSetting(EX_KEY, s);
355 }
356 
lineEditExcludePerDir_textChanged(const QString & s)357 void SettingsImpl::lineEditExcludePerDir_textChanged(const QString& s) {
358 
359 	writeSetting(EX_PER_DIR_KEY, s);
360 }
361 
lineEditTemplate_textChanged(const QString & s)362 void SettingsImpl::lineEditTemplate_textChanged(const QString& s) {
363 
364 	writeSetting(CMT_TEMPL_KEY, s);
365 }
366 
lineEditCommitExtraOptions_textChanged(const QString & s)367 void SettingsImpl::lineEditCommitExtraOptions_textChanged(const QString& s) {
368 
369 	writeSetting(CMT_ARGS_KEY, s);
370 }
371