Mercurial > hg > easyhg
comparison mainwindow.cpp @ 0:a9098eba2ee5
Initial commit.
author | Jari Korhonen <jtkorhonen@gmail.com> |
---|---|
date | Thu, 22 Apr 2010 03:15:35 +0300 |
parents | |
children | c19a4f858aab |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a9098eba2ee5 |
---|---|
1 /**************************************************************************** | |
2 ** | |
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | |
4 ** All rights reserved. | |
5 ** Contact: Nokia Corporation (qt-info@nokia.com) | |
6 ** | |
7 ** This file is part of the examples of the Qt Toolkit. | |
8 ** | |
9 ** $QT_BEGIN_LICENSE:LGPL$ | |
10 ** Commercial Usage | |
11 ** Licensees holding valid Qt Commercial licenses may use this file in | |
12 ** accordance with the Qt Commercial License Agreement provided with the | |
13 ** Software or, alternatively, in accordance with the terms contained in | |
14 ** a written agreement between you and Nokia. | |
15 ** | |
16 ** GNU Lesser General Public License Usage | |
17 ** Alternatively, this file may be used under the terms of the GNU Lesser | |
18 ** General Public License version 2.1 as published by the Free Software | |
19 ** Foundation and appearing in the file LICENSE.LGPL included in the | |
20 ** packaging of this file. Please review the following information to | |
21 ** ensure the GNU Lesser General Public License version 2.1 requirements | |
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
23 ** | |
24 ** In addition, as a special exception, Nokia gives you certain additional | |
25 ** rights. These rights are described in the Nokia Qt LGPL Exception | |
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | |
27 ** | |
28 ** GNU General Public License Usage | |
29 ** Alternatively, this file may be used under the terms of the GNU | |
30 ** General Public License version 3.0 as published by the Free Software | |
31 ** Foundation and appearing in the file LICENSE.GPL included in the | |
32 ** packaging of this file. Please review the following information to | |
33 ** ensure the GNU General Public License version 3.0 requirements will be | |
34 ** met: http://www.gnu.org/copyleft/gpl.html. | |
35 ** | |
36 ** If you have questions regarding the use of this file, please contact | |
37 ** Nokia at qt-info@nokia.com. | |
38 ** $QT_END_LICENSE$ | |
39 ** | |
40 ** Copyright (C) Jari Korhonen, 2010 (HgExplorer specific parts, under lgpl) | |
41 *************************************************************************************/ | |
42 | |
43 #include <QtGui> | |
44 #include <QStringList> | |
45 #include <QDir> | |
46 | |
47 #include "mainwindow.h" | |
48 #include "settingsdialog.h" | |
49 | |
50 | |
51 MainWindow::MainWindow() | |
52 { | |
53 QString wndTitle; | |
54 | |
55 createActions(); | |
56 createMenus(); | |
57 createToolBars(); | |
58 createStatusBar(); | |
59 | |
60 timerId = startTimer(200); | |
61 runner = new HgRunner(this); | |
62 runningAction = ACT_NONE; | |
63 statusBar()->addPermanentWidget(runner); | |
64 | |
65 wndTitle.sprintf("%s %s", APPNAME, APPVERSION); | |
66 setWindowTitle(wndTitle); | |
67 | |
68 remoteRepoPath = ""; | |
69 workFolderPath = ""; | |
70 | |
71 readSettings(); | |
72 | |
73 tabPage = 0; | |
74 hgExp = new HgExpWidget((QWidget *) this, remoteRepoPath, workFolderPath, initialFileTypesBits); | |
75 setCentralWidget(hgExp); | |
76 | |
77 setUnifiedTitleAndToolBarOnMac(true); | |
78 connectActions(); | |
79 enableDisableActions(); | |
80 | |
81 if (firstStart) | |
82 { | |
83 QMessageBox::information(this, tr("First start todo"), tr("Going to \"Settings\" first.")); | |
84 settings(); | |
85 } | |
86 | |
87 hgStat(); | |
88 } | |
89 | |
90 | |
91 void MainWindow::closeEvent(QCloseEvent *) | |
92 { | |
93 writeSettings(); | |
94 } | |
95 | |
96 | |
97 void MainWindow::about() | |
98 { | |
99 QMessageBox::about(this, tr("About HgExplorer"), | |
100 tr("<b>HgExplorer</b> tries to be Mercurial's <b>VSS Explorer:</b> ;-)<br><br>" | |
101 "-Hides command line in normal use<br>" | |
102 "-Makes common operations easier<br><br>" | |
103 "(c) 2010 (lgpl), Jari Korhonen (jtkorhonen@gmail.com)<br><br>" | |
104 "-Needs Mercurial ;-) (thanks Matt Mackall, Bryan O'Sullivan and others !)<br>" | |
105 "-Uses excellent Nuvola icons (c) David Vignoni (Thanks, David !)<br>" | |
106 "-Needs Qt4, mingw (in windows), python, kdiff3 (Thanks to all of you !)<br>")); | |
107 } | |
108 | |
109 | |
110 void MainWindow::hgStat() | |
111 { | |
112 if (hgStatAct -> isEnabled()) | |
113 { | |
114 if (runningAction == ACT_NONE) | |
115 { | |
116 QStringList params; | |
117 | |
118 QString statFlags = hgExp -> getStatFlags(); | |
119 if (statFlags.isEmpty()) | |
120 { | |
121 params << "stat"; | |
122 } | |
123 else | |
124 { | |
125 params << "stat" << "-" + statFlags; | |
126 } | |
127 | |
128 | |
129 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
130 runningAction = ACT_STAT; | |
131 } | |
132 } | |
133 } | |
134 | |
135 void MainWindow::hgHeads() | |
136 { | |
137 if (runningAction == ACT_NONE) | |
138 { | |
139 QStringList params; | |
140 params << "heads"; | |
141 | |
142 //on empty repos, "hg heads" will fail, don't care of that. | |
143 runner -> startProc(getHgBinaryName(), workFolderPath, params, false); | |
144 runningAction = ACT_HEADS; | |
145 } | |
146 } | |
147 | |
148 void MainWindow::hgLog() | |
149 { | |
150 if (runningAction == ACT_NONE) | |
151 { | |
152 QStringList params; | |
153 params << "glog" << "--verbose"; | |
154 | |
155 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
156 runningAction = ACT_LOG; | |
157 } | |
158 } | |
159 | |
160 | |
161 void MainWindow::hgParents() | |
162 { | |
163 if (runningAction == ACT_NONE) | |
164 { | |
165 QStringList params; | |
166 params << "parents"; | |
167 | |
168 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
169 runningAction = ACT_PARENTS; | |
170 } | |
171 } | |
172 | |
173 | |
174 | |
175 void MainWindow::hgRemove() | |
176 { | |
177 if (runningAction == ACT_NONE) | |
178 { | |
179 QStringList params; | |
180 QString currentFile = hgExp -> getCurrentFileListLine(); | |
181 | |
182 if (!currentFile.isEmpty()) | |
183 { | |
184 params << "remove" << currentFile.mid(2); //Jump over status marker characters (e.g "M ") | |
185 | |
186 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
187 runningAction = ACT_REMOVE; | |
188 } | |
189 } | |
190 } | |
191 | |
192 void MainWindow::hgAnnotate() | |
193 { | |
194 if (runningAction == ACT_NONE) | |
195 { | |
196 QStringList params; | |
197 QString currentFile = hgExp -> getCurrentFileListLine(); | |
198 | |
199 if (!currentFile.isEmpty()) | |
200 { | |
201 params << "annotate" << currentFile.mid(2); //Jump over status marker characters (e.g "M ") | |
202 | |
203 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
204 runningAction = ACT_ANNOTATE; | |
205 } | |
206 } | |
207 } | |
208 | |
209 | |
210 void MainWindow::hgResolveMark() | |
211 { | |
212 if (runningAction == ACT_NONE) | |
213 { | |
214 QStringList params; | |
215 QString currentFile = hgExp -> getCurrentFileListLine(); | |
216 | |
217 if (!currentFile.isEmpty()) | |
218 { | |
219 params << "resolve" << "--mark" << currentFile.mid(2); //Jump over status marker characters (e.g "M ") | |
220 | |
221 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
222 runningAction = ACT_RESOLVE_MARK; | |
223 } | |
224 } | |
225 } | |
226 | |
227 | |
228 | |
229 void MainWindow::hgResolveList() | |
230 { | |
231 if (runningAction == ACT_NONE) | |
232 { | |
233 QStringList params; | |
234 | |
235 params << "resolve" << "--list"; | |
236 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
237 runningAction = ACT_RESOLVE_LIST; | |
238 } | |
239 } | |
240 | |
241 | |
242 | |
243 void MainWindow::hgAdd() | |
244 { | |
245 if (runningAction == ACT_NONE) | |
246 { | |
247 QStringList params; | |
248 | |
249 params << "add"; | |
250 | |
251 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
252 runningAction = ACT_ADD; | |
253 } | |
254 } | |
255 | |
256 int MainWindow::getCommitComment(QString& comment) | |
257 { | |
258 int ret; | |
259 | |
260 QDialog dlg(this); | |
261 | |
262 QLabel *commentLabel = new QLabel(tr("Comment:")); | |
263 QLineEdit *commentEdit = new QLineEdit; | |
264 commentEdit -> setFixedWidth(400); | |
265 QHBoxLayout *commentLayout = new QHBoxLayout; | |
266 commentLayout -> addWidget(commentLabel); | |
267 commentLayout -> addWidget(commentEdit); | |
268 | |
269 QPushButton *btnOk = new QPushButton(tr("Ok")); | |
270 QPushButton *btnCancel = new QPushButton(tr("Cancel")); | |
271 QHBoxLayout *btnLayout = new QHBoxLayout; | |
272 btnLayout -> addWidget(btnOk); | |
273 btnLayout -> addWidget(btnCancel); | |
274 | |
275 QVBoxLayout *mainLayout = new QVBoxLayout; | |
276 mainLayout -> addLayout(commentLayout); | |
277 mainLayout -> addLayout(btnLayout); | |
278 | |
279 dlg.setLayout(mainLayout); | |
280 | |
281 dlg.setWindowTitle(tr("Save (commit)")); | |
282 | |
283 connect(btnOk, SIGNAL(clicked()), &dlg, SLOT(accept())); | |
284 connect(btnCancel, SIGNAL(clicked()), &dlg, SLOT(reject())); | |
285 | |
286 ret = dlg.exec(); | |
287 comment = commentEdit -> text(); | |
288 return ret; | |
289 } | |
290 | |
291 void MainWindow::hgCommit() | |
292 { | |
293 if (runningAction == ACT_NONE) | |
294 { | |
295 QStringList params; | |
296 QString comment; | |
297 | |
298 if (QDialog::Accepted == getCommitComment(comment)) | |
299 { | |
300 if (!comment.isEmpty()) | |
301 { | |
302 params << "commit" << "--message" << comment << "--user" << userInfo; | |
303 | |
304 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
305 runningAction = ACT_COMMIT; | |
306 } | |
307 } | |
308 } | |
309 } | |
310 | |
311 void MainWindow::hgFileDiff() | |
312 { | |
313 if (runningAction == ACT_NONE) | |
314 { | |
315 QStringList params; | |
316 | |
317 QString currentFile = hgExp -> getCurrentFileListLine(); | |
318 | |
319 if (!currentFile.isEmpty()) | |
320 { | |
321 //Diff parent file against working folder file | |
322 params << "kdiff3" << currentFile.mid(2); | |
323 runner -> startProc(getHgBinaryName(), workFolderPath, params, false); | |
324 runningAction = ACT_FILEDIFF; | |
325 } | |
326 } | |
327 } | |
328 | |
329 | |
330 void MainWindow::hgFolderDiff() | |
331 { | |
332 if (runningAction == ACT_NONE) | |
333 { | |
334 QStringList params; | |
335 | |
336 //Diff parent against working folder (folder diff) | |
337 params << "kdiff3"; | |
338 runner -> startProc(getHgBinaryName(), workFolderPath, params, false); | |
339 runningAction = ACT_FOLDERDIFF; | |
340 } | |
341 } | |
342 | |
343 | |
344 void MainWindow::hgChgSetDiff() | |
345 { | |
346 if (runningAction == ACT_NONE) | |
347 { | |
348 QStringList params; | |
349 | |
350 //Diff 2 history log versions against each other | |
351 QString revA; | |
352 QString revB; | |
353 | |
354 hgExp -> getHistoryDiffRevisions(revA, revB); | |
355 | |
356 if ((!revA.isEmpty()) && (!revB.isEmpty())) | |
357 { | |
358 params << "kdiff3" << "--rev" << revA << "--rev" << revB; | |
359 runner -> startProc(getHgBinaryName(), workFolderPath, params, false); | |
360 runningAction = ACT_CHGSETDIFF; | |
361 } | |
362 else | |
363 { | |
364 QMessageBox::information(this, tr("Changeset diff"), tr("Please select two changesets from history list or heads list first.")); | |
365 } | |
366 } | |
367 } | |
368 | |
369 | |
370 | |
371 void MainWindow::hgUpdate() | |
372 { | |
373 if (runningAction == ACT_NONE) | |
374 { | |
375 QStringList params; | |
376 | |
377 | |
378 params << "update"; | |
379 | |
380 | |
381 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
382 runningAction = ACT_UPDATE; | |
383 } | |
384 } | |
385 | |
386 | |
387 void MainWindow::hgUpdateToRev() | |
388 { | |
389 if (runningAction == ACT_NONE) | |
390 { | |
391 QStringList params; | |
392 QString rev; | |
393 | |
394 hgExp -> getUpdateToRevRevision(rev); | |
395 | |
396 hgExp -> setCurrentIndex(WORKTAB); | |
397 enableDisableActions(); | |
398 | |
399 params << "update" << "--rev" << rev << "--clean"; | |
400 | |
401 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
402 | |
403 runningAction = ACT_UPDATE; | |
404 } | |
405 } | |
406 | |
407 | |
408 void MainWindow::hgRevert() | |
409 { | |
410 if (runningAction == ACT_NONE) | |
411 { | |
412 QStringList params; | |
413 QString currentFile = hgExp -> getCurrentFileListLine(); | |
414 | |
415 params << "revert" << currentFile.mid(2); | |
416 | |
417 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
418 runningAction = ACT_REVERT; | |
419 } | |
420 } | |
421 | |
422 void MainWindow::hgMerge() | |
423 { | |
424 if (runningAction == ACT_NONE) | |
425 { | |
426 QStringList params; | |
427 | |
428 params << "merge"; | |
429 | |
430 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
431 runningAction = ACT_MERGE; | |
432 } | |
433 } | |
434 | |
435 | |
436 void MainWindow::hgCloneFromRemote() | |
437 { | |
438 if (runningAction == ACT_NONE) | |
439 { | |
440 QStringList params; | |
441 | |
442 params << "clone" << remoteRepoPath << workFolderPath; | |
443 | |
444 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
445 runningAction = ACT_CLONEFROMREMOTE; | |
446 } | |
447 } | |
448 | |
449 | |
450 void MainWindow::hgInit() | |
451 { | |
452 if (runningAction == ACT_NONE) | |
453 { | |
454 QStringList params; | |
455 | |
456 params << "init"; | |
457 | |
458 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
459 runningAction = ACT_INIT; | |
460 } | |
461 } | |
462 | |
463 | |
464 void MainWindow::hgIncoming() | |
465 { | |
466 if (runningAction == ACT_NONE) | |
467 { | |
468 QStringList params; | |
469 | |
470 params << "incoming" << "--newest-first" << remoteRepoPath; | |
471 | |
472 runner -> startProc(getHgBinaryName(), workFolderPath, params, false); | |
473 runningAction = ACT_INCOMING; | |
474 } | |
475 } | |
476 | |
477 | |
478 void MainWindow::hgPull() | |
479 { | |
480 if (runningAction == ACT_NONE) | |
481 { | |
482 QStringList params; | |
483 | |
484 params << "pull" << remoteRepoPath; | |
485 | |
486 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
487 runningAction = ACT_PULL; | |
488 } | |
489 } | |
490 | |
491 | |
492 void MainWindow::hgPush() | |
493 { | |
494 if (runningAction == ACT_NONE) | |
495 { | |
496 QStringList params; | |
497 | |
498 params << "push" << remoteRepoPath; | |
499 | |
500 runner -> startProc(getHgBinaryName(), workFolderPath, params); | |
501 runningAction = ACT_PUSH; | |
502 } | |
503 } | |
504 | |
505 | |
506 void MainWindow::settings() | |
507 { | |
508 SettingsDialog *settingsDlg = new SettingsDialog(this); | |
509 settingsDlg->setModal(true); | |
510 settingsDlg->exec(); | |
511 hgExp -> clearLists(); | |
512 enableDisableActions(); | |
513 hgStat(); | |
514 } | |
515 | |
516 void MainWindow::presentLongStdoutToUser(QString stdo, int w, int h) | |
517 { | |
518 QDialog dlg; | |
519 dlg.setMinimumWidth(w); | |
520 dlg.setMinimumHeight(h); | |
521 | |
522 QVBoxLayout *box = new QVBoxLayout; | |
523 QListWidget *list = new QListWidget; | |
524 list-> addItems(stdo.split("\n")); | |
525 QPushButton *btn = new QPushButton(tr("Ok")); | |
526 connect(btn, SIGNAL(clicked()), &dlg, SLOT(accept())); | |
527 | |
528 box -> addWidget(list); | |
529 box -> addWidget(btn); | |
530 dlg.setLayout(box); | |
531 | |
532 dlg.exec(); | |
533 } | |
534 | |
535 | |
536 bool MainWindow::isSelectedLocallyDeleted(QListWidget *workList) | |
537 { | |
538 QList<QListWidgetItem *> selList = workList -> selectedItems(); | |
539 if (selList.count() == 1) | |
540 { | |
541 if (selList.at(0)->text().mid(0, 1) == "!") | |
542 { | |
543 return true; | |
544 } | |
545 } | |
546 return false; | |
547 } | |
548 | |
549 | |
550 bool MainWindow::isSelectedUntracked(QListWidget *workList) | |
551 { | |
552 QList<QListWidgetItem *> selList = workList -> selectedItems(); | |
553 if (selList.count() == 1) | |
554 { | |
555 if (selList.at(0)->text().mid(0, 1) == "?") | |
556 { | |
557 return true; | |
558 } | |
559 } | |
560 return false; | |
561 } | |
562 | |
563 | |
564 bool MainWindow::isSelectedModified(QListWidget *workList) | |
565 { | |
566 QList<QListWidgetItem *> selList = workList -> selectedItems(); | |
567 if (selList.count() == 1) | |
568 { | |
569 if (selList.at(0)->text().mid(0, 1) == "M") | |
570 { | |
571 return true; | |
572 } | |
573 } | |
574 return false; | |
575 } | |
576 | |
577 void MainWindow::countAMRModifications(QListWidget *workList, int& a, int& m, int& r) | |
578 { | |
579 int itemCount = workList -> count(); | |
580 if (itemCount > 0) | |
581 { | |
582 int A= 0; | |
583 int M=0; | |
584 int R=0; | |
585 for (int i = 0; i < workList -> count(); i++) | |
586 { | |
587 QListWidgetItem *currItem = workList -> item(i); | |
588 | |
589 QString tmp = currItem->text().mid(0, 1); | |
590 if (tmp == "M") | |
591 { | |
592 M++; | |
593 } | |
594 else if (tmp == "R") | |
595 { | |
596 R++; | |
597 } | |
598 else if (tmp == "A") | |
599 { | |
600 A++; | |
601 } | |
602 } | |
603 | |
604 a = A; | |
605 m = M; | |
606 r = R; | |
607 } | |
608 else | |
609 { | |
610 a = 0; | |
611 m = 0; | |
612 r = 0; | |
613 } | |
614 } | |
615 | |
616 | |
617 void MainWindow::timerEvent(QTimerEvent *) | |
618 { | |
619 bool shouldHgStat = false; | |
620 | |
621 if (runningAction != ACT_NONE) | |
622 { | |
623 //We are running some hg command... | |
624 if (runner -> isProcRunning() == false) | |
625 { | |
626 //Running has just ended. | |
627 int exitCode = runner -> getExitCode(); | |
628 | |
629 runner -> hideProgBar(); | |
630 | |
631 //Clumsy... | |
632 if ((EXITOK(exitCode)) || ((exitCode == 1) && (runningAction == ACT_INCOMING))) | |
633 { | |
634 //Successful running. | |
635 switch(runningAction) | |
636 { | |
637 case ACT_STAT: | |
638 { | |
639 hgExp -> updateWorkFolderFileList(runner -> getStdOut()); | |
640 } | |
641 break; | |
642 | |
643 case ACT_INCOMING: | |
644 case ACT_ANNOTATE: | |
645 case ACT_RESOLVE_LIST: | |
646 case ACT_RESOLVE_MARK: | |
647 presentLongStdoutToUser(runner -> getStdOut(), 1024, 768); | |
648 shouldHgStat = true; | |
649 break; | |
650 | |
651 case ACT_PULL: | |
652 QMessageBox::information(this, "pull", runner -> getStdOut()); | |
653 shouldHgStat = true; | |
654 break; | |
655 | |
656 case ACT_PUSH: | |
657 QMessageBox::information(this, "push", runner -> getStdOut()); | |
658 shouldHgStat = true; | |
659 break; | |
660 | |
661 case ACT_INIT: | |
662 enableDisableActions(); | |
663 shouldHgStat = true; | |
664 break; | |
665 | |
666 case ACT_CLONEFROMREMOTE: | |
667 QMessageBox::information(this, "clone", runner -> getStdOut()); | |
668 enableDisableActions(); | |
669 shouldHgStat = true; | |
670 break; | |
671 | |
672 case ACT_LOG: | |
673 { | |
674 hgExp -> updateLocalRepoHgLogList(runner -> getStdOut()); | |
675 } | |
676 break; | |
677 | |
678 case ACT_PARENTS: | |
679 { | |
680 hgExp -> updateLocalRepoParentsList(runner -> getStdOut()); | |
681 } | |
682 break; | |
683 | |
684 case ACT_HEADS: | |
685 { | |
686 QString stdOut = runner -> getStdOut(); | |
687 hgExp -> updateLocalRepoHeadsList(stdOut); | |
688 } | |
689 break; | |
690 | |
691 case ACT_REMOVE: | |
692 case ACT_ADD: | |
693 case ACT_COMMIT: | |
694 case ACT_FILEDIFF: | |
695 case ACT_FOLDERDIFF: | |
696 case ACT_CHGSETDIFF: | |
697 case ACT_REVERT: | |
698 shouldHgStat = true; | |
699 break; | |
700 | |
701 case ACT_UPDATE: | |
702 QMessageBox::information(this, "update", runner -> getStdOut()); | |
703 shouldHgStat = true; | |
704 break; | |
705 | |
706 case ACT_MERGE: | |
707 QMessageBox::information(this, "merge", runner -> getStdOut()); | |
708 shouldHgStat = true; | |
709 break; | |
710 | |
711 default: | |
712 break; | |
713 } | |
714 } | |
715 | |
716 //Typical sequence goes stat -> heads -> parents -> log | |
717 if (runningAction == ACT_STAT) | |
718 { | |
719 runningAction = ACT_NONE; | |
720 hgHeads(); | |
721 } | |
722 else if (runningAction == ACT_HEADS) | |
723 { | |
724 runningAction = ACT_NONE; | |
725 hgParents(); | |
726 } | |
727 else if (runningAction == ACT_PARENTS) | |
728 { | |
729 runningAction = ACT_NONE; | |
730 hgLog(); | |
731 } | |
732 else | |
733 { | |
734 runningAction = ACT_NONE; | |
735 if (shouldHgStat) | |
736 { | |
737 hgStat(); | |
738 } | |
739 } | |
740 } | |
741 } | |
742 else | |
743 { | |
744 enableDisableActions(); | |
745 } | |
746 } | |
747 | |
748 void MainWindow::connectActions() | |
749 { | |
750 connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); | |
751 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); | |
752 connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); | |
753 | |
754 connect(hgStatAct, SIGNAL(triggered()), this, SLOT(hgStat())); | |
755 connect(hgExp, SIGNAL(workFolderViewTypesChanged()), this, SLOT(hgStat())); | |
756 connect(hgRemoveAct, SIGNAL(triggered()), this, SLOT(hgRemove())); | |
757 connect(hgAddAct, SIGNAL(triggered()), this, SLOT(hgAdd())); | |
758 connect(hgCommitAct, SIGNAL(triggered()), this, SLOT(hgCommit())); | |
759 connect(hgFileDiffAct, SIGNAL(triggered()), this, SLOT(hgFileDiff())); | |
760 connect(hgFolderDiffAct, SIGNAL(triggered()), this, SLOT(hgFolderDiff())); | |
761 connect(hgChgSetDiffAct, SIGNAL(triggered()), this, SLOT(hgChgSetDiff())); | |
762 connect(hgUpdateAct, SIGNAL(triggered()), this, SLOT(hgUpdate())); | |
763 connect(hgRevertAct, SIGNAL(triggered()), this, SLOT(hgRevert())); | |
764 connect(hgMergeAct, SIGNAL(triggered()), this, SLOT(hgMerge())); | |
765 | |
766 connect(settingsAct, SIGNAL(triggered()), this, SLOT(settings())); | |
767 | |
768 connect(hgInitAct, SIGNAL(triggered()), this, SLOT(hgInit())); | |
769 connect(hgCloneFromRemoteAct, SIGNAL(triggered()), this, SLOT(hgCloneFromRemote())); | |
770 connect(hgIncomingAct, SIGNAL(triggered()), this, SLOT(hgIncoming())); | |
771 connect(hgPullAct, SIGNAL(triggered()), this, SLOT(hgPull())); | |
772 connect(hgPushAct, SIGNAL(triggered()), this, SLOT(hgPush())); | |
773 | |
774 connect(hgExp, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int))); | |
775 | |
776 connect(hgUpdateToRevAct, SIGNAL(triggered()), this, SLOT(hgUpdateToRev())); | |
777 connect(hgAnnotateAct, SIGNAL(triggered()), this, SLOT(hgAnnotate())); | |
778 connect(hgResolveListAct, SIGNAL(triggered()), this, SLOT(hgResolveList())); | |
779 connect(hgResolveMarkAct, SIGNAL(triggered()), this, SLOT(hgResolveMark())); | |
780 } | |
781 | |
782 void MainWindow::tabChanged(int currTab) | |
783 { | |
784 tabPage = currTab; | |
785 } | |
786 | |
787 void MainWindow::enableDisableActions() | |
788 { | |
789 QDir localRepoDir; | |
790 QDir workFolderDir; | |
791 bool workFolderExist; | |
792 bool localRepoExist; | |
793 | |
794 remoteRepoActionsEnabled = true; | |
795 if (remoteRepoPath.isEmpty()) | |
796 { | |
797 remoteRepoActionsEnabled = false; | |
798 } | |
799 | |
800 localRepoActionsEnabled = true; | |
801 if (workFolderPath.isEmpty()) | |
802 { | |
803 localRepoActionsEnabled = false; | |
804 workFolderExist = false; | |
805 } | |
806 | |
807 if (!workFolderDir.exists(workFolderPath)) | |
808 { | |
809 localRepoActionsEnabled = false; | |
810 workFolderExist = false; | |
811 } | |
812 else | |
813 { | |
814 workFolderExist = true; | |
815 } | |
816 | |
817 if (!localRepoDir.exists(workFolderPath + getHgDirName())) | |
818 { | |
819 localRepoActionsEnabled = false; | |
820 localRepoExist = false; | |
821 } | |
822 | |
823 hgCloneFromRemoteAct -> setEnabled(remoteRepoActionsEnabled); | |
824 hgIncomingAct -> setEnabled(remoteRepoActionsEnabled && remoteRepoActionsEnabled); | |
825 hgPullAct -> setEnabled(remoteRepoActionsEnabled && remoteRepoActionsEnabled); | |
826 hgPushAct -> setEnabled(remoteRepoActionsEnabled && remoteRepoActionsEnabled); | |
827 | |
828 if (tabPage != WORKTAB) | |
829 { | |
830 localRepoActionsEnabled = false; | |
831 } | |
832 | |
833 hgInitAct -> setEnabled((localRepoExist == false) && (workFolderExist==true)); | |
834 hgStatAct -> setEnabled(localRepoActionsEnabled); | |
835 hgFileDiffAct -> setEnabled(localRepoActionsEnabled); | |
836 hgFolderDiffAct -> setEnabled(localRepoActionsEnabled); | |
837 hgRevertAct -> setEnabled(localRepoActionsEnabled); | |
838 hgAddAct -> setEnabled(localRepoActionsEnabled); | |
839 hgRemoveAct -> setEnabled(localRepoActionsEnabled); | |
840 hgUpdateAct -> setEnabled(localRepoActionsEnabled); | |
841 hgCommitAct -> setEnabled(localRepoActionsEnabled); | |
842 hgMergeAct -> setEnabled(localRepoActionsEnabled); | |
843 | |
844 hgExp -> enableDisableOtherTabs(); | |
845 | |
846 int a, m, r; | |
847 countAMRModifications(hgExp -> workFolderFileList, a, m, r); | |
848 | |
849 if (tabPage == WORKTAB) | |
850 { | |
851 //Enable / disable actions according to workFolderFileList selections / currentSelection / count | |
852 hgChgSetDiffAct -> setEnabled(false); | |
853 hgUpdateToRevAct -> setEnabled(false); | |
854 | |
855 if (localRepoActionsEnabled) | |
856 { | |
857 if ((a == 0) && (m == 0) && (r == 0)) | |
858 { | |
859 hgCommitAct -> setEnabled(false); | |
860 hgRevertAct -> setEnabled(false); | |
861 } | |
862 | |
863 if (m == 0) | |
864 { | |
865 hgFolderDiffAct -> setEnabled(false); | |
866 } | |
867 | |
868 if (!isSelectedModified(hgExp -> workFolderFileList)) | |
869 { | |
870 hgFileDiffAct -> setEnabled(false); | |
871 hgRevertAct -> setEnabled(false); | |
872 } | |
873 | |
874 if (!isSelectedUntracked(hgExp -> workFolderFileList)) | |
875 { | |
876 hgAddAct -> setEnabled(false); | |
877 } | |
878 | |
879 if (!isSelectedLocallyDeleted(hgExp -> workFolderFileList)) | |
880 { | |
881 hgRemoveAct -> setEnabled(false); | |
882 } | |
883 | |
884 if (hgExp -> localRepoHeadsList->count() == 1) | |
885 { | |
886 hgMergeAct -> setEnabled(false); | |
887 } | |
888 | |
889 } | |
890 } | |
891 else | |
892 { | |
893 QList <QListWidgetItem *> headSelList = hgExp -> localRepoHeadsList->selectedItems(); | |
894 QList <QListWidgetItem *> historySelList = hgExp -> localRepoHgLogList->selectedItems(); | |
895 | |
896 if ((historySelList.count() == 2) || (headSelList.count() == 2)) | |
897 { | |
898 hgChgSetDiffAct -> setEnabled(true); | |
899 } | |
900 else | |
901 { | |
902 hgChgSetDiffAct -> setEnabled(false); | |
903 } | |
904 | |
905 if ((a == 0) && (m == 0) && (r == 0)) | |
906 { | |
907 if (historySelList.count() == 1) | |
908 { | |
909 hgUpdateToRevAct -> setEnabled(true); | |
910 } | |
911 else | |
912 { | |
913 hgUpdateToRevAct -> setEnabled(false); | |
914 } | |
915 } | |
916 else | |
917 { | |
918 hgUpdateToRevAct -> setEnabled(false); | |
919 } | |
920 } | |
921 } | |
922 | |
923 void MainWindow::createActions() | |
924 { | |
925 //File actions | |
926 hgInitAct = new QAction(tr("Init local repository"), this); | |
927 hgInitAct->setStatusTip(tr("Create an empty local repository in selected folder")); | |
928 | |
929 hgCloneFromRemoteAct = new QAction(tr("Clone from remote"), this); | |
930 hgCloneFromRemoteAct->setStatusTip(tr("Clone from remote repository into local repository in selected folder")); | |
931 | |
932 settingsAct = new QAction(QIcon(":/images/settings.png"), tr("Settings..."), this); | |
933 settingsAct -> setStatusTip(tr("View and change application settings")); | |
934 settingsAct -> setIconVisibleInMenu(true); | |
935 | |
936 exitAct = new QAction(QIcon(":/images/exit.png"), tr("Exit"), this); | |
937 exitAct->setShortcuts(QKeySequence::Quit); | |
938 exitAct->setStatusTip(tr("Exit application")); | |
939 exitAct -> setIconVisibleInMenu(true); | |
940 | |
941 //Repository actions | |
942 hgIncomingAct = new QAction(QIcon(":/images/incoming.png"), tr("View incoming changesets"), this); | |
943 hgIncomingAct -> setStatusTip(tr("View info of changesets incoming to us from remote repository (on pull operation)")); | |
944 | |
945 hgPullAct = new QAction(QIcon(":/images/pull.png"), tr("Pull from remote"), this); | |
946 hgPullAct -> setStatusTip(tr("Pull changesets from remote repository to local repository")); | |
947 | |
948 hgPushAct = new QAction(QIcon(":/images/push.png"), tr("Push to remote"), this); | |
949 hgPushAct->setStatusTip(tr("Push local changesets to remote repository")); | |
950 | |
951 //Workfolder actions | |
952 hgStatAct = new QAction(QIcon(":/images/status.png"), tr("Refresh status"), this); | |
953 hgStatAct->setStatusTip(tr("Refresh (info of) status of workfolder files (A=Added, M=Mofified, R=Removed, C=Clean, !=Locally deleted, ?=Not tracked, I=Ignored)")); | |
954 | |
955 hgFileDiffAct = new QAction(QIcon(":/images/diff.png"), tr("View filediff"), this); | |
956 hgFileDiffAct->setStatusTip(tr("Filediff: View differences between selected working folder file and local repository file")); | |
957 | |
958 hgFolderDiffAct = new QAction(QIcon(":/images/folderdiff.png"), tr("View folderdiff"), this); | |
959 hgFolderDiffAct->setStatusTip(tr("Folderdiff: View all differences between working folder files and local repository files")); | |
960 | |
961 hgChgSetDiffAct = new QAction(QIcon(":/images/chgsetdiff.png"), tr("View changesetdiff"), this); | |
962 hgChgSetDiffAct->setStatusTip(tr("Change set diff: View differences between all files of 2 repository changesets")); | |
963 | |
964 hgRevertAct = new QAction(QIcon(":/images/undo.png"), tr("Undo changes"), this); | |
965 hgRevertAct->setStatusTip(tr("Undo selected working folder file changes (return to local repository version)")); | |
966 | |
967 hgAddAct = new QAction(QIcon(":/images/add.png"), tr("Add files"), this); | |
968 hgAddAct -> setStatusTip(tr("Add working folder files to local repository (on next commit)")); | |
969 | |
970 hgRemoveAct = new QAction(QIcon(":/images/remove.png"), tr("Remove file"), this); | |
971 hgRemoveAct -> setStatusTip(tr("Remove selected working folder file from local repository (on next commit)")); | |
972 | |
973 hgUpdateAct = new QAction(QIcon(":/images/update.png"), tr("Update working folder"), this); | |
974 hgUpdateAct->setStatusTip(tr("Update working folder from local repository")); | |
975 | |
976 hgCommitAct = new QAction(QIcon(":/images/commit.png"), tr("Commit / Save changes"), this); | |
977 hgCommitAct->setStatusTip(tr("Save all changes in working folder (and all subfolders) to local repository")); | |
978 | |
979 hgMergeAct = new QAction(QIcon(":/images/merge.png"), tr("Merge"), this); | |
980 hgMergeAct->setStatusTip(tr("Merge two local repository changesets to working folder")); | |
981 | |
982 //Advanced actions | |
983 hgUpdateToRevAct = new QAction(tr("Update to revision"), this); | |
984 hgUpdateToRevAct -> setStatusTip(tr("Update working folder to version selected from history list")); | |
985 | |
986 hgAnnotateAct = new QAction(tr("Annotate"), this); | |
987 hgAnnotateAct -> setStatusTip(tr("Show line-by-line version information for selected file")); | |
988 | |
989 hgResolveListAct = new QAction(tr("Resolve (list)"), this); | |
990 hgResolveListAct -> setStatusTip(tr("Resolve (list): Show list of files needing merge")); | |
991 | |
992 hgResolveMarkAct = new QAction(tr("Resolve (mark)"), this); | |
993 hgResolveMarkAct -> setStatusTip(tr("Resolve (mark): Mark selected file status as resolved")); | |
994 | |
995 //Help actions | |
996 aboutAct = new QAction(tr("About"), this); | |
997 aboutAct->setStatusTip(tr("Show the application's About box")); | |
998 | |
999 aboutQtAct = new QAction(tr("About Qt"), this); | |
1000 aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); | |
1001 } | |
1002 | |
1003 void MainWindow::createMenus() | |
1004 { | |
1005 fileMenu = menuBar()->addMenu(tr("File")); | |
1006 fileMenu -> addAction(hgInitAct); | |
1007 fileMenu -> addAction(hgCloneFromRemoteAct); | |
1008 fileMenu -> addSeparator(); | |
1009 fileMenu -> addAction(settingsAct); | |
1010 fileMenu -> addSeparator(); | |
1011 fileMenu -> addAction(exitAct); | |
1012 | |
1013 advancedMenu = menuBar()->addMenu(tr("Advanced")); | |
1014 advancedMenu -> addAction(hgUpdateToRevAct); | |
1015 advancedMenu -> addSeparator(); | |
1016 advancedMenu -> addAction(hgAnnotateAct); | |
1017 advancedMenu -> addSeparator(); | |
1018 advancedMenu -> addAction(hgResolveListAct); | |
1019 advancedMenu -> addAction(hgResolveMarkAct); | |
1020 | |
1021 helpMenu = menuBar()->addMenu(tr("Help")); | |
1022 helpMenu->addAction(aboutAct); | |
1023 helpMenu->addAction(aboutQtAct); | |
1024 } | |
1025 | |
1026 void MainWindow::createToolBars() | |
1027 { | |
1028 fileToolBar = addToolBar(tr("File")); | |
1029 fileToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); | |
1030 fileToolBar -> addAction(settingsAct); | |
1031 fileToolBar -> addAction(exitAct); | |
1032 fileToolBar -> addSeparator(); | |
1033 fileToolBar -> addAction(hgChgSetDiffAct); | |
1034 fileToolBar -> setMovable(false); | |
1035 | |
1036 repoToolBar = addToolBar(tr(REPOMENU_TITLE)); | |
1037 repoToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); | |
1038 repoToolBar->addAction(hgIncomingAct); | |
1039 repoToolBar->addAction(hgPullAct); | |
1040 repoToolBar->addAction(hgPushAct); | |
1041 repoToolBar -> setMovable(false); | |
1042 | |
1043 workFolderToolBar = addToolBar(tr(WORKFOLDERMENU_TITLE)); | |
1044 addToolBar(Qt::LeftToolBarArea, workFolderToolBar); | |
1045 workFolderToolBar -> setIconSize(QSize(MY_ICON_SIZE, MY_ICON_SIZE)); | |
1046 workFolderToolBar->addAction(hgStatAct); | |
1047 workFolderToolBar->addSeparator(); | |
1048 workFolderToolBar->addAction(hgFileDiffAct); | |
1049 workFolderToolBar->addAction(hgFolderDiffAct); | |
1050 workFolderToolBar->addSeparator(); | |
1051 workFolderToolBar->addAction(hgRevertAct); | |
1052 workFolderToolBar->addAction(hgUpdateAct); | |
1053 workFolderToolBar->addAction(hgCommitAct); | |
1054 workFolderToolBar->addAction(hgMergeAct); | |
1055 workFolderToolBar->addSeparator(); | |
1056 workFolderToolBar->addAction(hgAddAct); | |
1057 workFolderToolBar->addAction(hgRemoveAct); | |
1058 workFolderToolBar -> setMovable(false); | |
1059 | |
1060 } | |
1061 | |
1062 | |
1063 void MainWindow::createStatusBar() | |
1064 { | |
1065 statusBar()->showMessage(tr("Ready")); | |
1066 } | |
1067 | |
1068 void MainWindow::readSettings() | |
1069 { | |
1070 QDir workFolder; | |
1071 | |
1072 QSettings settings("hgexplorer", "hgexplorer"); | |
1073 | |
1074 remoteRepoPath = settings.value("remoterepopath", "").toString() ; | |
1075 workFolderPath = settings.value("workfolderpath", "").toString(); | |
1076 if (!workFolder.exists(workFolderPath)) | |
1077 { | |
1078 workFolderPath = ""; | |
1079 } | |
1080 | |
1081 userInfo = settings.value("userinfo", "").toString(); | |
1082 | |
1083 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); | |
1084 QSize size = settings.value("size", QSize(400, 400)).toSize(); | |
1085 firstStart = settings.value("firststart", QVariant(true)).toBool(); | |
1086 | |
1087 initialFileTypesBits = (unsigned char) settings.value("viewFileTypes", QVariant(DEFAULT_HG_STAT_BITS)).toInt(); | |
1088 resize(size); | |
1089 move(pos); | |
1090 } | |
1091 | |
1092 void MainWindow::writeSettings() | |
1093 { | |
1094 QSettings settings("hgexplorer", "hgexplorer"); | |
1095 settings.setValue("pos", pos()); | |
1096 settings.setValue("size", size()); | |
1097 settings.setValue("remoterepopath", remoteRepoPath); | |
1098 settings.setValue("workfolderpath", workFolderPath); | |
1099 settings.setValue("userinfo", userInfo); | |
1100 settings.setValue("firststart", firstStart); | |
1101 settings.setValue("viewFileTypes", hgExp -> getFileTypesBits()); | |
1102 } | |
1103 | |
1104 | |
1105 | |
1106 |