diff --git a/CommitDialog.cpp b/CommitDialog.cpp new file mode 100644 index 0000000..dc06b0b --- /dev/null +++ b/CommitDialog.cpp @@ -0,0 +1,40 @@ +#include "CommitDialog.h" +#include "ui_CommitDialog.h" + +CommitDialog::CommitDialog(const QStringList &commitMsgHistory, const QStringList &files, QWidget *parent) : + QDialog(parent), + ui(new Ui::CommitDialog) +{ + ui->setupUi(this); + ui->comboBox->clear(); + ui->comboBox->insertItems(0, commitMsgHistory); + ui->plainTextEdit->clear(); + ui->listView->setModel(&itemModel); + + for(QStringList::const_iterator it=files.begin(); it!=files.end(); ++it) + itemModel.appendRow(new QStandardItem(*it)); + +} + +CommitDialog::~CommitDialog() +{ + delete ui; +} + +bool CommitDialog::run(QString &commitMsg, const QStringList &commitMsgHistory, const QStringList &files, QWidget *parent) +{ + CommitDialog dlg(commitMsgHistory, files, parent); + int res = dlg.exec(); + if(res==QDialog::Accepted) + { + commitMsg = dlg.ui->plainTextEdit->toPlainText(); + return true; + } + + return false; +} + +void CommitDialog::on_comboBox_activated(const QString &arg1) +{ + ui->plainTextEdit->setPlainText(arg1); +} diff --git a/CommitDialog.h b/CommitDialog.h new file mode 100644 index 0000000..2d6d864 --- /dev/null +++ b/CommitDialog.h @@ -0,0 +1,29 @@ +#ifndef COMMITDIALOG_H +#define COMMITDIALOG_H + +#include +#include + +namespace Ui { + class CommitDialog; +} + +class CommitDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CommitDialog(const QStringList &commitMsgHistory, const QStringList &files, QWidget *parent = 0); + ~CommitDialog(); + + static bool run(QString &commitMsg, const QStringList &commitMsgHistory, const QStringList &files, QWidget *parent); + +private slots: + void on_comboBox_activated(const QString &arg1); + +private: + Ui::CommitDialog *ui; + QStandardItemModel itemModel; +}; + +#endif // COMMITDIALOG_H diff --git a/CommitDialog.ui b/CommitDialog.ui new file mode 100644 index 0000000..1af10e6 --- /dev/null +++ b/CommitDialog.ui @@ -0,0 +1,102 @@ + + + CommitDialog + + + + 0 + 0 + 400 + 300 + + + + Commit + + + + + + + + + Qt::Vertical + + + + + 0 + 100 + + + + + + + 0 + 5 + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectRows + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + CommitDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CommitDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/FileActionDialog.cpp b/FileActionDialog.cpp new file mode 100644 index 0000000..acbef5f --- /dev/null +++ b/FileActionDialog.cpp @@ -0,0 +1,28 @@ +#include "FileActionDialog.h" +#include "ui_FileActionDialog.h" + +FileActionDialog::FileActionDialog(const QString &title, const QString &message, const QStringList &files, QWidget *parent) : + QDialog(parent), + ui(new Ui::FileActionDialog) +{ + ui->setupUi(this); + setWindowTitle(title); + ui->label->setText(message); + ui->listView->setModel(&itemModel); + + for(QStringList::const_iterator it=files.begin(); it!=files.end(); ++it) + itemModel.appendRow(new QStandardItem(*it)); +} + +FileActionDialog::~FileActionDialog() +{ + delete ui; +} + +bool FileActionDialog::run(const QString &title, const QString &message, const QStringList &files, QWidget *parent) +{ + FileActionDialog dlg(title, message, files, parent); + int res = dlg.exec(); + + return res == QDialog::Accepted; +} diff --git a/FileActionDialog.h b/FileActionDialog.h new file mode 100644 index 0000000..c2d07fb --- /dev/null +++ b/FileActionDialog.h @@ -0,0 +1,26 @@ +#ifndef FILEACTIONDIALOG_H +#define FILEACTIONDIALOG_H + +#include +#include + +namespace Ui { + class FileActionDialog; +} + +class FileActionDialog : public QDialog +{ + Q_OBJECT + +public: + explicit FileActionDialog(const QString &title, const QString &message, const QStringList &files, QWidget *parent = 0); + ~FileActionDialog(); + + static bool run(const QString &title, const QString &message, const QStringList &files, QWidget *parent); + +private: + Ui::FileActionDialog *ui; + QStandardItemModel itemModel; +}; + +#endif // FILEACTIONDIALOG_H diff --git a/FileActionDialog.ui b/FileActionDialog.ui new file mode 100644 index 0000000..2b97047 --- /dev/null +++ b/FileActionDialog.ui @@ -0,0 +1,90 @@ + + + FileActionDialog + + + + 0 + 0 + 400 + 200 + + + + File Action + + + + + + QFrame::NoFrame + + + TextLabel + + + true + + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + FileActionDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + FileActionDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/MainWindow.cpp b/MainWindow.cpp index 7cd62a8..5bf2ce3 100644 --- a/MainWindow.cpp +++ b/MainWindow.cpp @@ -6,6 +6,8 @@ #include #include #include +#include "CommitDialog.h" +#include "FileActionDialog.h" enum { @@ -95,6 +97,9 @@ static void RecurseDirectory(QFileInfoList &entries, const QString& dirPath, con //------------------------------------------------------------------------------ void MainWindow::refresh() { + // Load repository info + updateStatus(); + // Scan all workspace files QFileInfoList all_files; QString wkdir = getCurrentWorkspace(); @@ -103,14 +108,16 @@ void MainWindow::refresh() workspaceFiles.clear(); for(QFileInfoList::iterator it=all_files.begin(); it!=all_files.end(); ++it) { - if(it->fileName()== "_FOSSIL_") + QString filename = it->fileName(); + QString qqq = it->absoluteFilePath(); + + // Skip fossil files + if(filename == "_FOSSIL_" || (!repositoryFile.isEmpty() && it->absoluteFilePath()==repositoryFile)) continue; FileEntry e; - e.status = FileEntry::STATUS_UNKNOWN; - e.fileinfo = *it; - e.filename = e.getRelativeFilename(wkdir); - workspaceFiles.insert(e.filename, e); + e.set(*it, FileEntry::TYPE_UNKNOWN, wkdir); + workspaceFiles.insert(e.getFilename(), e); } // Retrieve the status of files tracked by fossil @@ -125,19 +132,19 @@ void MainWindow::refresh() continue; QString status_text = line.left(10).trimmed(); - FileEntry::Status status = FileEntry::STATUS_UNKNOWN; + FileEntry::EntryType type = FileEntry::TYPE_UNKNOWN; if(status_text=="EDITED") - status = FileEntry::STATUS_EDITTED; + type = FileEntry::TYPE_EDITTED; else if(status_text=="UNCHANGED") - status = FileEntry::STATUS_UNCHANGED; + type = FileEntry::TYPE_UNCHANGED; QString fname = line.right(line.length() - 10).trimmed(); filemap_t::iterator it = workspaceFiles.find(fname); Q_ASSERT(it!=workspaceFiles.end()); - it.value().status = status; + it.value().setType(type); } // Update the model @@ -148,15 +155,15 @@ void MainWindow::refresh() for(filemap_t::iterator it = workspaceFiles.begin(); it!=workspaceFiles.end(); ++it, ++i) { const FileEntry &e = it.value(); - switch(e.status) + switch(e.getType()) { - case FileEntry::STATUS_EDITTED: + case FileEntry::TYPE_EDITTED: { QIcon modicon(":icons/icons/Button Blank Yellow-01.png"); itemModel.setItem(i, COLUMN_STATUS, new QStandardItem(modicon, "E")); break; } - case FileEntry::STATUS_UNCHANGED: + case FileEntry::TYPE_UNCHANGED: { QIcon modicon(":icons/icons/Button Blank Green-01.png"); itemModel.setItem(i, COLUMN_STATUS, new QStandardItem(modicon, "U")); @@ -170,17 +177,25 @@ void MainWindow::refresh() } - QString path = e.filename; - path = path.left(path.indexOf(e.fileinfo.fileName())); + QString path = e.getFilename(); + path = path.left(path.indexOf(e.getFileInfo().fileName())); + QFileInfo finfo = e.getFileInfo(); itemModel.setItem(i, COLUMN_PATH, new QStandardItem(path)); - itemModel.setItem(i, COLUMN_FILENAME, new QStandardItem(e.filename)); - itemModel.setItem(i, COLUMN_EXTENSION, new QStandardItem(e.fileinfo.completeSuffix())); - itemModel.setItem(i, COLUMN_MODIFIED, new QStandardItem(e.fileinfo.lastModified().toString(Qt::SystemLocaleShortDate))); + itemModel.setItem(i, COLUMN_FILENAME, new QStandardItem(e.getFilename())); + itemModel.setItem(i, COLUMN_EXTENSION, new QStandardItem(finfo .completeSuffix())); + itemModel.setItem(i, COLUMN_MODIFIED, new QStandardItem(finfo .lastModified().toString(Qt::SystemLocaleShortDate))); } - ui->tableView->resizeColumnsToContents(); - ui->tableView->resizeRowsToContents(); + + ui->tableView->resizeColumnsToContents(); + ui->tableView->resizeRowsToContents(); + + QString title = "Fuel"; + if(!projectName.isEmpty()) + title += " - "+projectName; + + setWindowTitle(title); } //------------------------------------------------------------------------------ @@ -215,7 +230,6 @@ bool MainWindow::runFossil(QStringList &result, const QStringList &args) } process.waitForFinished(); - QString output = process.readAllStandardOutput(); QStringList lines = output.split('\n'); @@ -227,25 +241,10 @@ bool MainWindow::runFossil(QStringList &result, const QStringList &args) Log(line); } - return true; -} + if(process.exitStatus()!=QProcess::NormalExit) + return false; -//------------------------------------------------------------------------------ -void MainWindow::on_tableView_customContextMenuRequested(const QPoint &/*pos*/) -{ -/* - QModelIndex idx = ui->tableView->indexAt(pos); - if(!idx.isValid()) - return; - - QMenu *menu = new QMenu; - menu->addAction("Diff"); - menu->addSeparator(); - menu->addAction("Add"); - menu->addAction("Delete"); - menu->addSeparator(); - menu->addAction("Commit"); - menu->exec(pos);*/ + return process.exitCode() == EXIT_SUCCESS; } //------------------------------------------------------------------------------ @@ -315,7 +314,7 @@ void MainWindow::saveSettings() } //------------------------------------------------------------------------------ -void MainWindow::getSelectionFilenames(QStringList &filenames) +void MainWindow::getSelectionFilenames(QStringList &filenames, int includeMask) { QModelIndexList selection = ui->tableView->selectionModel()->selectedIndexes(); for(QModelIndexList::iterator mi_it = selection.begin(); mi_it!=selection.end(); ++mi_it) @@ -328,7 +327,16 @@ void MainWindow::getSelectionFilenames(QStringList &filenames) continue; QVariant data = itemModel.data(mi); - filenames.append(data.toString()); + QString filename = data.toString(); + filemap_t::iterator e_it = workspaceFiles.find(filename); + Q_ASSERT(e_it!=workspaceFiles.end()); + const FileEntry &e = e_it.value(); + + // Skip unwanted files + if(!(includeMask & e.getType())) + continue; + + filenames.append(filename); } } //------------------------------------------------------------------------------ @@ -448,3 +456,91 @@ void MainWindow::on_actionPull_triggered() QStringList res; runFossil(res, QStringList() << "pull"); } + +//------------------------------------------------------------------------------ +void MainWindow::updateStatus() +{ + QStringList res; + if(!runFossil(res, QStringList() << "info")) + return; + + for(QStringList::iterator it=res.begin(); it!=res.end(); ++it) + { + QStringList tokens = it->split(":"); + if(tokens.length()!=2) + continue; + QString key = tokens[0].trimmed(); + QString value = tokens[1].trimmed(); + if(key=="project-name") + projectName = value; + else if(key=="repository") + repositoryFile = value; + } +} + +//------------------------------------------------------------------------------ +void MainWindow::on_actionCommit_triggered() +{ + QStringList modified_files; + getSelectionFilenames(modified_files, FileEntry::TYPE_EDITTED); + + if(modified_files.empty()) + return; + + QString msg; + if(!CommitDialog::run(msg, commitMessages, modified_files, this)) + return; + + // Do commit + commitMessages.push_front(msg); +} + +//------------------------------------------------------------------------------ +void MainWindow::on_actionAdd_triggered() +{ + // Get unknown files only + QStringList selection; + getSelectionFilenames(selection, FileEntry::TYPE_UNKNOWN); + + if(selection.empty()) + return; + + if(!FileActionDialog::run("Add files", "The following files will be added. Are you sure?", selection, this)) + return; + + // Do Add +} + +//------------------------------------------------------------------------------ +void MainWindow::on_actionDelete_triggered() +{ + QStringList repo_files; + getSelectionFilenames(repo_files, FileEntry::TYPE_EDITTED|FileEntry::TYPE_UNCHANGED); + + QStringList unknown_files; + getSelectionFilenames(unknown_files, FileEntry::TYPE_UNKNOWN); + + if(repo_files.empty() && unknown_files.empty()) + return; + + if(!FileActionDialog::run("Delete files", "The following files will be deleted. Are you sure?", repo_files+unknown_files, this)) + return; + + // Do Delete + +} + +//------------------------------------------------------------------------------ +void MainWindow::on_actionRevert_triggered() +{ + QStringList modified_files; + getSelectionFilenames(modified_files, FileEntry::TYPE_EDITTED); + + if(modified_files.empty()) + return; + + if(!FileActionDialog::run("Revert files", "The following files will be reverted. Are you sure?", modified_files, this)) + return; + + // Do Revert +} diff --git a/MainWindow.h b/MainWindow.h index a22a877..2c082c0 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -17,28 +17,67 @@ class QStringList; struct FileEntry { - enum Status + enum EntryType { - STATUS_UNKNOWN, - STATUS_UNCHANGED, - STATUS_EDITTED + TYPE_UNKNOWN = 1<<0, + TYPE_UNCHANGED = 1<<1, + TYPE_EDITTED = 1<<2, + TYPE_ALL = TYPE_UNKNOWN|TYPE_UNCHANGED|TYPE_EDITTED }; - QFileInfo fileinfo; - Status status; - QString filename; + void set(QFileInfo &info, EntryType type, const QString &repoPath) + { + FileInfo = info; + Type = type; + Filename = getRelativeFilename(repoPath); + } + + bool isType(EntryType t) const + { + return Type == t; + } + + void setType(EntryType t) + { + Type = t; + } + + EntryType getType() const + { + return Type; + } + + QFileInfo getFileInfo() const + { + return FileInfo; + } + + bool isRepo() const + { + return Type == TYPE_UNCHANGED || Type == TYPE_EDITTED; + } + + const QString &getFilename() const + { + return Filename; + } QString getRelativeFilename(const QString &path) { QString abs_base_dir = QDir(path).absolutePath(); - QString relative = fileinfo.absoluteFilePath(); + QString relative = FileInfo.absoluteFilePath(); int index = relative.indexOf(abs_base_dir); if(index<0) return QString(""); return relative.right(relative.length() - abs_base_dir.length()-1); } + +private: + QFileInfo FileInfo; + EntryType Type; + QString Filename; }; @@ -58,9 +97,10 @@ private: const QString &getCurrentWorkspace() { Q_ASSERT(currentWorkspace filemap_t; - filemap_t workspaceFiles; - int currentWorkspace; - - QProcess fossilUI; + filemap_t workspaceFiles; + int currentWorkspace; + QStringList commitMessages; }; #endif // MAINWINDOW_H diff --git a/manifest b/manifest index 683cde9..e760dec 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,13 @@ -C Added\sPush/Pull\sactions -D 2011-08-02T15:42:48.504 -F MainWindow.cpp 7eb2ce3b3bb54d824abd77d648f28816b804172d -F MainWindow.h ea40c2f2cf6fe116bdb90f344bc3bade15b040b2 +C Added\sCommit\sand\sFileAction\sdialogs\nSkeleton\scode\sfor\sCommit,\sAdd,\sDelete,\sRevert\sactions +D 2011-08-03T15:30:09.277 +F CommitDialog.cpp f4065a49dfaa6904ffb1ad4ebe5efd01506cf550 +F CommitDialog.h c18c73998f8a925723ec1407ce75dc17a27a5ff7 +F CommitDialog.ui 482961858d1e7c31745966c347b21b6318e2e7b5 +F FileActionDialog.cpp 02dc244b0bcaad2021327186d5870bc408210a41 +F FileActionDialog.h 6082f84f6b5d48be6104034d6dc896a9d343b613 +F FileActionDialog.ui 2d7a0fa47f9555f4a4a7485feacd5bce504415a0 +F MainWindow.cpp b2fb908aefa74484a4b7f751f8ad9570b79454bb +F MainWindow.h a3fda2c06f47a831e799a441f183810e6585b9bb F MainWindow.ui 71a58630d7a3b6af128d427a9390eadfc4fc83e3 F icons/Address\sBook-01.png ef2cec80ea5a559b72e8be4a344a1869fe69cbd8 F icons/Adobe\sIllustrator\sCS3\sDocument-01.png 2e44e933d58eefee7ccfa1650fed4ceadcf3c2be @@ -156,10 +162,10 @@ F icons/Zoom\sIn-01.png bdd24558fd23a1003f1a569f092f22022736f236 F icons/Zoom\sOut-01.png 8eda092100d9e00c9097f43a80d1e26695947448 F icons/Zoom-01.png 67ca532922e9166325c5c75fce1ca3fbb0d2b6a6 F main.cpp f53e9e1e34f65565f06b2d37d7be5c38e2113a03 -F qtfossil.pro 80268b3b1ec8f73cbc24896a0f2ae3fbcca286cb -F qtfossil.pro.user ea741584bcfd60b32ce9033f85af877d353a7b53 +F qtfossil.pro 728f1eec3adbcfc0e030cad1ea0867f765d9f179 +F qtfossil.pro.user 3aa11e8cc637ac9de0e6396307370f20bee7f62f F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53 -P 22658a331a132d4adb2643d8d51f379e35b95f63 -R d999d8ba09737ca61b3d491cc01b1e51 +P aea0b01c82bcd9caa71a5049c60e07ad6b3aed41 +R c84ec25e7c6ecb8c98cb5544d5a2d147 U kostas -Z 00972b3f796d2e2d29df1e5b26d27b87 +Z c73d16be1ed5c7fe4f1970c96b7dab6a diff --git a/manifest.uuid b/manifest.uuid index ef61d8d..9f43ba2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aea0b01c82bcd9caa71a5049c60e07ad6b3aed41 \ No newline at end of file +9e35495cc3f4e18f458cf02f83d1d8075c0a85b9 \ No newline at end of file diff --git a/qtfossil.pro b/qtfossil.pro index b26b745..f91daa8 100644 --- a/qtfossil.pro +++ b/qtfossil.pro @@ -11,12 +11,24 @@ TEMPLATE = app SOURCES += main.cpp\ - MainWindow.cpp + MainWindow.cpp \ + CommitDialog.cpp \ + FileActionDialog.cpp -HEADERS += MainWindow.h +HEADERS += MainWindow.h \ + CommitDialog.h \ + FileActionDialog.h -FORMS += MainWindow.ui +FORMS += MainWindow.ui \ + CommitDialog.ui \ + FileActionDialog.ui RESOURCES += \ resources.qrc + + + + + + diff --git a/qtfossil.pro.user b/qtfossil.pro.user index 1c75247..eca131d 100644 --- a/qtfossil.pro.user +++ b/qtfossil.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget