Added Workspace Tree view
Added Rename Folder action Minor GUI cleanups FossilOrigin-Name: 5fc925ac68148c69db66e88e23be196807ffec22
This commit is contained in:
		
							
								
								
									
										544
									
								
								MainWindow.cpp
									
									
									
									
									
								
							
							
						
						
									
										544
									
								
								MainWindow.cpp
									
									
									
									
									
								
							| @@ -24,14 +24,21 @@ | |||||||
| 	QString EOL_MARK("\n"); | 	QString EOL_MARK("\n"); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #define PATH_SEP "/" | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| enum | enum | ||||||
| { | { | ||||||
| 	COLUMN_STATUS, | 	COLUMN_STATUS, | ||||||
| 	COLUMN_PATH, |  | ||||||
| 	COLUMN_FILENAME, | 	COLUMN_FILENAME, | ||||||
| 	COLUMN_EXTENSION, | 	COLUMN_EXTENSION, | ||||||
| 	COLUMN_MODIFIED | 	COLUMN_MODIFIED, | ||||||
|  | 	COLUMN_PATH | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | enum | ||||||
|  | { | ||||||
|  | 	REPODIRMODEL_ROLE_PATH = Qt::UserRole+1 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| @@ -128,17 +135,40 @@ MainWindow::MainWindow(QWidget *parent) : | |||||||
|     ui(new Ui::MainWindow) |     ui(new Ui::MainWindow) | ||||||
| { | { | ||||||
|     ui->setupUi(this); |     ui->setupUi(this); | ||||||
| 	ui->tableView->setModel(&itemModel); |  | ||||||
| 	itemModel.setHorizontalHeaderLabels(QStringList() << tr("S") << tr("Path") << tr("File") << tr("Ext") << tr("Modified") ); | 	QAction *separator = new QAction(this); | ||||||
|  | 	separator->setSeparator(true); | ||||||
|  |  | ||||||
|  | 	// TableView | ||||||
|  | 	ui->tableView->setModel(&repoFileModel); | ||||||
|  |  | ||||||
| 	ui->tableView->addAction(ui->actionDiff); | 	ui->tableView->addAction(ui->actionDiff); | ||||||
| 	ui->tableView->addAction(ui->actionHistory); | 	ui->tableView->addAction(ui->actionHistory); | ||||||
| 	ui->tableView->addAction(ui->actionOpenFile); | 	ui->tableView->addAction(ui->actionOpenFile); | ||||||
| 	ui->tableView->addAction(ui->actionOpenContaining); | 	ui->tableView->addAction(ui->actionOpenContaining); | ||||||
|  | 	ui->tableView->addAction(separator); | ||||||
| 	ui->tableView->addAction(ui->actionAdd); | 	ui->tableView->addAction(ui->actionAdd); | ||||||
| 	ui->tableView->addAction(ui->actionDelete); | 	ui->tableView->addAction(ui->actionRevert); | ||||||
| 	ui->tableView->addAction(ui->actionRename); | 	ui->tableView->addAction(ui->actionRename); | ||||||
|  | 	ui->tableView->addAction(ui->actionDelete); | ||||||
|  |  | ||||||
|  | 	// TreeView | ||||||
|  | 	ui->treeView->setModel(&repoDirModel); | ||||||
|  | 	connect( ui->treeView->selectionModel(), | ||||||
|  | 		SIGNAL( selectionChanged(const QItemSelection &, const QItemSelection &) ), | ||||||
|  | 		SLOT( on_treeView_selectionChanged(const QItemSelection &, const QItemSelection &) ), | ||||||
|  | 		Qt::DirectConnection ); | ||||||
|  |  | ||||||
|  | 	ui->treeView->addAction(ui->actionCommit); | ||||||
|  | 	ui->treeView->addAction(ui->actionOpenFolder); | ||||||
|  | 	ui->treeView->addAction(ui->actionAdd); | ||||||
|  | 	ui->treeView->addAction(ui->actionRevert); | ||||||
|  | 	ui->treeView->addAction(ui->actionDelete); | ||||||
|  | 	ui->treeView->addAction(separator); | ||||||
|  | 	ui->treeView->addAction(ui->actionRenameFolder); | ||||||
|  | 	ui->treeView->addAction(ui->actionOpenFolder); | ||||||
|  |  | ||||||
|  | 	// Recent Workspaces | ||||||
| 	// Locate a sequence of two separator actions in file menu | 	// Locate a sequence of two separator actions in file menu | ||||||
| 	QList<QAction*> file_actions = ui->menuFile->actions(); | 	QList<QAction*> file_actions = ui->menuFile->actions(); | ||||||
| 	QAction *recent_sep=0; | 	QAction *recent_sep=0; | ||||||
| @@ -156,7 +186,7 @@ MainWindow::MainWindow(QWidget *parent) : | |||||||
| 	{ | 	{ | ||||||
| 		recentWorkspaceActs[i] = new QAction(this); | 		recentWorkspaceActs[i] = new QAction(this); | ||||||
| 		recentWorkspaceActs[i]->setVisible(false); | 		recentWorkspaceActs[i]->setVisible(false); | ||||||
| 		connect(recentWorkspaceActs[i], SIGNAL(triggered()), this, SLOT(onOpenRecent())); | 		connect(recentWorkspaceActs[i], SIGNAL(triggered()), this, SLOT(on_openRecent())); | ||||||
| 		ui->menuFile->insertAction(recent_sep, recentWorkspaceActs[i]); | 		ui->menuFile->insertAction(recent_sep, recentWorkspaceActs[i]); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -172,6 +202,8 @@ MainWindow::MainWindow(QWidget *parent) : | |||||||
| 		a->setIconVisibleInMenu(false); | 		a->setIconVisibleInMenu(false); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | 	viewMode = VIEWMODE_TREE; | ||||||
|  |  | ||||||
| 	loadSettings(); | 	loadSettings(); | ||||||
| 	refresh(); | 	refresh(); | ||||||
| 	rebuildRecent(); | 	rebuildRecent(); | ||||||
| @@ -183,6 +215,11 @@ MainWindow::~MainWindow() | |||||||
| { | { | ||||||
| 	stopUI(); | 	stopUI(); | ||||||
| 	saveSettings(); | 	saveSettings(); | ||||||
|  |  | ||||||
|  | 	// Dispose RepoFiles | ||||||
|  | 	for(filemap_t::iterator it = workspaceFiles.begin(); it!=workspaceFiles.end(); ++it) | ||||||
|  | 		delete *it; | ||||||
|  |  | ||||||
| 	delete ui; | 	delete ui; | ||||||
| } | } | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| @@ -254,11 +291,12 @@ bool MainWindow::openWorkspace(const QString &dir) | |||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| void MainWindow::on_actionOpen_triggered() | void MainWindow::on_actionOpen_triggered() | ||||||
| { | { | ||||||
| 	QString path = QFileDialog::getExistingDirectory(this, tr("Fossil Checkout"), QDir::currentPath()); | 	QString path = QFileDialog::getExistingDirectory(this, tr("Fossil Workspace"), QDir::currentPath()); | ||||||
| 	if(!path.isNull()) | 	if(!path.isNull()) | ||||||
| 		openWorkspace(path); | 		openWorkspace(path); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| void MainWindow::rebuildRecent() | void MainWindow::rebuildRecent() | ||||||
| { | { | ||||||
| @@ -279,7 +317,7 @@ void MainWindow::rebuildRecent() | |||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| void MainWindow::onOpenRecent() | void MainWindow::on_openRecent() | ||||||
| { | { | ||||||
| 	QAction *action = qobject_cast<QAction *>(sender()); | 	QAction *action = qobject_cast<QAction *>(sender()); | ||||||
| 	if(!action) | 	if(!action) | ||||||
| @@ -305,7 +343,7 @@ bool MainWindow::scanDirectory(QFileInfoList &entries, const QString& dirPath, c | |||||||
| 		QString filename = info.fileName(); | 		QString filename = info.fileName(); | ||||||
| 		QString filepath = info.filePath(); | 		QString filepath = info.filePath(); | ||||||
| 		QString rel_path = filepath; | 		QString rel_path = filepath; | ||||||
| 		rel_path.remove(baseDir+"/"); | 		rel_path.remove(baseDir+PATH_SEP); | ||||||
|  |  | ||||||
| 		// Skip ignored files | 		// Skip ignored files | ||||||
| 		if(!ignoreSpec.isEmpty() && QDir::match(ignoreSpec, rel_path)) | 		if(!ignoreSpec.isEmpty() && QDir::match(ignoreSpec, rel_path)) | ||||||
| @@ -351,14 +389,14 @@ bool MainWindow::refresh() | |||||||
| 	{ | 	{ | ||||||
| 		setStatus(tr("No checkout detected.")); | 		setStatus(tr("No checkout detected.")); | ||||||
| 		enableActions(false); | 		enableActions(false); | ||||||
| 		itemModel.removeRows(0, itemModel.rowCount()); | 		repoFileModel.removeRows(0, repoFileModel.rowCount()); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| 	else if(st==REPO_OLD_SCHEMA) | 	else if(st==REPO_OLD_SCHEMA) | ||||||
| 	{ | 	{ | ||||||
| 		setStatus(tr("Old fossil schema detected. Consider running rebuild.")); | 		setStatus(tr("Old fossil schema detected. Consider running rebuild.")); | ||||||
| 		enableActions(false); | 		enableActions(false); | ||||||
| 		itemModel.removeRows(0, itemModel.rowCount()); | 		repoFileModel.removeRows(0, repoFileModel.rowCount()); | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -393,7 +431,13 @@ void MainWindow::scanWorkspace() | |||||||
| 	setEnabled(false); | 	setEnabled(false); | ||||||
| 	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); | 	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); | ||||||
|  |  | ||||||
|  | 	// Dispose RepoFiles | ||||||
|  | 	for(filemap_t::iterator it = workspaceFiles.begin(); it!=workspaceFiles.end(); ++it) | ||||||
|  | 		delete *it; | ||||||
|  |  | ||||||
| 	workspaceFiles.clear(); | 	workspaceFiles.clear(); | ||||||
|  | 	pathSet.clear(); | ||||||
|  |  | ||||||
| 	if(scan_files) | 	if(scan_files) | ||||||
| 	{ | 	{ | ||||||
| 		QCoreApplication::processEvents(); | 		QCoreApplication::processEvents(); | ||||||
| @@ -416,17 +460,20 @@ void MainWindow::scanWorkspace() | |||||||
| 			if(filename == "_FOSSIL_" || (!repositoryFile.isEmpty() && it->absoluteFilePath()==repositoryFile)) | 			if(filename == "_FOSSIL_" || (!repositoryFile.isEmpty() && it->absoluteFilePath()==repositoryFile)) | ||||||
| 				continue; | 				continue; | ||||||
|  |  | ||||||
| 			RepoFile e; | 			RepoFile *rf = new RepoFile(*it, RepoFile::TYPE_UNKNOWN, wkdir); | ||||||
| 			e.set(*it, RepoFile::TYPE_UNKNOWN, wkdir); | 			workspaceFiles.insert(rf->getFilePath(), rf); | ||||||
| 			workspaceFiles.insert(e.getFilename(), e); | 			pathSet.insert(rf->getPath()); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	setStatus(tr("Updating...")); | 	setStatus(tr("Updating...")); | ||||||
| 	QCoreApplication::processEvents(); | 	QCoreApplication::processEvents(); | ||||||
|  |  | ||||||
| 	for(QStringList::iterator it=res.begin(); it!=res.end(); ++it) | 	// Update Files and Directories | ||||||
|  |  | ||||||
|  | 	for(QStringList::iterator line_it=res.begin(); line_it!=res.end(); ++line_it) | ||||||
| 	{ | 	{ | ||||||
| 		QString line = (*it).trimmed(); | 		QString line = (*line_it).trimmed(); | ||||||
| 		if(line.length()==0) | 		if(line.length()==0) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| @@ -467,26 +514,114 @@ void MainWindow::scanWorkspace() | |||||||
|  |  | ||||||
| 		filemap_t::iterator it = workspaceFiles.find(fname); | 		filemap_t::iterator it = workspaceFiles.find(fname); | ||||||
|  |  | ||||||
|  | 		RepoFile *rf = 0; | ||||||
| 		if(add_missing && it==workspaceFiles.end()) | 		if(add_missing && it==workspaceFiles.end()) | ||||||
| 		{ | 		{ | ||||||
| 			RepoFile e; |  | ||||||
| 			QFileInfo info(wkdir+QDir::separator()+fname); | 			QFileInfo info(wkdir+QDir::separator()+fname); | ||||||
| 			e.set(info, type, wkdir); | 			rf = new RepoFile(info, type, wkdir); | ||||||
| 			workspaceFiles.insert(e.getFilename(), e); | 			workspaceFiles.insert(rf->getFilePath(), rf); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		it = workspaceFiles.find(fname); | 		if(!rf) | ||||||
| 		Q_ASSERT(it!=workspaceFiles.end()); | 		{ | ||||||
|  | 			it = workspaceFiles.find(fname); | ||||||
|  | 			Q_ASSERT(it!=workspaceFiles.end()); | ||||||
|  | 			rf = *it; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		it.value().setType(type); | 		rf->setType(type); | ||||||
|  |  | ||||||
|  | 		QString path = rf->getPath(); | ||||||
|  | 		pathSet.insert(path); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Update the model | 	// Update the file item model | ||||||
|  | 	updateDirView(); | ||||||
|  | 	updateFileView(); | ||||||
|  |  | ||||||
|  | 	setEnabled(true); | ||||||
|  | 	setStatus(""); | ||||||
|  | 	QApplication::restoreOverrideCursor(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | static void addPathToTree(QStandardItem &root, const QString &path) | ||||||
|  | { | ||||||
|  | 	QStringList dirs = path.split('/'); | ||||||
|  | 	QStandardItem *parent = &root; | ||||||
|  |  | ||||||
|  | 	QString fullpath; | ||||||
|  | 	for(QStringList::iterator it = dirs.begin(); it!=dirs.end(); ++it) | ||||||
|  | 	{ | ||||||
|  | 		const QString &dir = *it; | ||||||
|  | 		fullpath += dir; | ||||||
|  |  | ||||||
|  | 		// Find the child that matches this subdir | ||||||
|  | 		bool found = false; | ||||||
|  | 		for(int r=0; r<parent->rowCount(); ++r) | ||||||
|  | 		{ | ||||||
|  | 			QStandardItem *child = parent->child(r, 0); | ||||||
|  | 			Q_ASSERT(child); | ||||||
|  | 			if(child->text() == dir) | ||||||
|  | 			{ | ||||||
|  | 				parent = child; | ||||||
|  | 				found = true; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if(!found) // Generate it | ||||||
|  | 		{ | ||||||
|  | 			QStandardItem *child = new QStandardItem(QIcon(":icons/icons/Folder-01.png"), dir); | ||||||
|  | 			child->setData(fullpath); // keep the full path to simplify selection | ||||||
|  | 			parent->appendRow(child); | ||||||
|  | 			parent = child; | ||||||
|  | 		} | ||||||
|  | 		fullpath += '/'; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::updateDirView() | ||||||
|  | { | ||||||
|  | 	if(viewMode == VIEWMODE_TREE) | ||||||
|  | 	{ | ||||||
|  | 		// Directory View | ||||||
|  | 		repoDirModel.clear(); | ||||||
|  | 		QStandardItem *root = new QStandardItem(QIcon(":icons/icons/My Documents-01.png"), projectName); | ||||||
|  | 		root->setData(""); // Empty Path | ||||||
|  | 		root->setEditable(false); | ||||||
|  | 		QString aa = root->data().toString(); | ||||||
|  | 		repoDirModel.appendRow(root); | ||||||
|  | 		for(pathset_t::iterator it = pathSet.begin(); it!=pathSet.end(); ++it) | ||||||
|  | 		{ | ||||||
|  | 			const QString &dir = *it; | ||||||
|  | 			if(dir.isEmpty()) | ||||||
|  | 				continue; | ||||||
|  |  | ||||||
|  | 			addPathToTree(*root, dir); | ||||||
|  | 		} | ||||||
|  | 		ui->treeView->expandToDepth(0); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::updateFileView() | ||||||
|  | { | ||||||
|  | 	// File View | ||||||
| 	// Clear all rows (except header) | 	// Clear all rows (except header) | ||||||
| 	itemModel.removeRows(0, itemModel.rowCount()); | 	repoFileModel.clear(); | ||||||
|  |  | ||||||
|  | 	QStringList header; | ||||||
|  | 	header << tr("S") << tr("File") << tr("Ext") << tr("Modified"); | ||||||
|  |  | ||||||
|  | 	if(viewMode==VIEWMODE_LIST) | ||||||
|  | 		header << tr("Path"); | ||||||
|  |  | ||||||
|  | 	repoFileModel.setHorizontalHeaderLabels(header); | ||||||
|  |  | ||||||
| 	struct { RepoFile::EntryType type; const char *tag; const char *tooltip; const char *icon; } | 	struct { RepoFile::EntryType type; const char *tag; const char *tooltip; const char *icon; } | ||||||
| 	stats[] = { | 	stats[] = | ||||||
|  | 	{ | ||||||
| 		{	RepoFile::TYPE_EDITTED, "E", "Editted", ":icons/icons/Button Blank Yellow-01.png" }, | 		{	RepoFile::TYPE_EDITTED, "E", "Editted", ":icons/icons/Button Blank Yellow-01.png" }, | ||||||
| 		{	RepoFile::TYPE_UNCHANGED, "U", "Unchanged", ":icons/icons/Button Blank Green-01.png" }, | 		{	RepoFile::TYPE_UNCHANGED, "U", "Unchanged", ":icons/icons/Button Blank Green-01.png" }, | ||||||
| 		{	RepoFile::TYPE_ADDED, "A", "Added", ":icons/icons/Button Add-01.png" }, | 		{	RepoFile::TYPE_ADDED, "A", "Added", ":icons/icons/Button Add-01.png" }, | ||||||
| @@ -495,13 +630,18 @@ void MainWindow::scanWorkspace() | |||||||
| 		{	RepoFile::TYPE_MISSING, "M", "Missing", ":icons/icons/Button Help-01.png" }, | 		{	RepoFile::TYPE_MISSING, "M", "Missing", ":icons/icons/Button Help-01.png" }, | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	size_t num_files = workspaceFiles.size(); | 	//size_t num_files = workspaceFiles.size(); | ||||||
| 	itemModel.insertRows(0, num_files); | 	//repoFileModel.insertRows(0, num_files); | ||||||
|  |  | ||||||
| 	size_t i=0; | 	size_t item_id=0; | ||||||
| 	for(filemap_t::iterator it = workspaceFiles.begin(); it!=workspaceFiles.end(); ++it, ++i) | 	for(filemap_t::iterator it = workspaceFiles.begin(); it!=workspaceFiles.end(); ++it) | ||||||
| 	{ | 	{ | ||||||
| 		const RepoFile &e = it.value(); | 		const RepoFile &e = *it.value(); | ||||||
|  | 		QString path = e.getPath(); | ||||||
|  |  | ||||||
|  | 		// In Tree mode, filter all items not included in the current dir | ||||||
|  | 		if(viewMode==VIEWMODE_TREE && path != viewDir) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
| 		// Status Column | 		// Status Column | ||||||
| 		const char *tag = "?"; // Default Tag | 		const char *tag = "?"; // Default Tag | ||||||
| @@ -521,26 +661,35 @@ void MainWindow::scanWorkspace() | |||||||
|  |  | ||||||
| 		QStandardItem *status = new QStandardItem(QIcon(status_icon), tag); | 		QStandardItem *status = new QStandardItem(QIcon(status_icon), tag); | ||||||
| 		status->setToolTip(tooltip); | 		status->setToolTip(tooltip); | ||||||
| 		itemModel.setItem(i, COLUMN_STATUS, status); | 		repoFileModel.setItem(item_id, COLUMN_STATUS, status); | ||||||
|  |  | ||||||
| 		QString path = e.getFilename(); |  | ||||||
| 		path = path.left(path.indexOf(e.getFileInfo().fileName())); |  | ||||||
| 		QFileInfo finfo = e.getFileInfo(); | 		QFileInfo finfo = e.getFileInfo(); | ||||||
|  |  | ||||||
| 		itemModel.setItem(i, COLUMN_PATH, new QStandardItem(path)); | 		QStandardItem *filename_item = 0; | ||||||
| 		itemModel.setItem(i, COLUMN_FILENAME, new QStandardItem(e.getFilename())); | 		if(viewMode==VIEWMODE_LIST) | ||||||
| 		itemModel.setItem(i, COLUMN_EXTENSION, new QStandardItem(finfo .completeSuffix())); | 		{ | ||||||
| 		itemModel.setItem(i, COLUMN_MODIFIED, new QStandardItem(finfo .lastModified().toString(Qt::SystemLocaleShortDate))); | 			repoFileModel.setItem(item_id, COLUMN_PATH, new QStandardItem(path)); | ||||||
|  |  | ||||||
|  | 			filename_item = new QStandardItem(e.getFilePath()); | ||||||
|  | 		} | ||||||
|  | 		else // In Tree mode the path is implicit so the file name is enough | ||||||
|  | 			filename_item = new QStandardItem(e.getFilename()); | ||||||
|  |  | ||||||
|  | 		Q_ASSERT(filename_item); | ||||||
|  | 		// Keep the path in the user data | ||||||
|  | 		filename_item->setData(e.getFilePath()); | ||||||
|  | 		repoFileModel.setItem(item_id, COLUMN_FILENAME, filename_item); | ||||||
|  |  | ||||||
|  | 		repoFileModel.setItem(item_id, COLUMN_EXTENSION, new QStandardItem(finfo .completeSuffix())); | ||||||
|  | 		repoFileModel.setItem(item_id, COLUMN_MODIFIED, new QStandardItem(finfo .lastModified().toString(Qt::SystemLocaleShortDate))); | ||||||
|  |  | ||||||
|  | 		++item_id; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ui->tableView->resizeColumnsToContents(); | 	ui->tableView->resizeColumnsToContents(); | ||||||
| 	ui->tableView->resizeRowsToContents(); | 	ui->tableView->resizeRowsToContents(); | ||||||
|  |  | ||||||
| 	setEnabled(true); |  | ||||||
| 	setStatus(""); |  | ||||||
| 	QApplication::restoreOverrideCursor(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| MainWindow::RepoStatus MainWindow::getRepoStatus() | MainWindow::RepoStatus MainWindow::getRepoStatus() | ||||||
| { | { | ||||||
| @@ -653,7 +802,7 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int | |||||||
| 	process.start(fossil, args); | 	process.start(fossil, args); | ||||||
| 	if(!process.waitForStarted()) | 	if(!process.waitForStarted()) | ||||||
| 	{ | 	{ | ||||||
| 		log("Could not start fossil executable '" + fossil + "''\n"); | 		log(tr("Could not start fossil executable '") + fossil + "''\n"); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -668,7 +817,7 @@ bool MainWindow::runFossilRaw(const QStringList &args, QStringList *output, int | |||||||
| 	{ | 	{ | ||||||
| 		if(fossilAbort) | 		if(fossilAbort) | ||||||
| 		{ | 		{ | ||||||
| 			log("\n* Terminated *\n"); | 			log("\n* "+tr("Terminated")+" *\n"); | ||||||
| 			#ifdef Q_WS_WIN | 			#ifdef Q_WS_WIN | ||||||
| 				fossilUI.kill(); // QT on windows cannot terminate console processes with QProcess::terminate | 				fossilUI.kill(); // QT on windows cannot terminate console processes with QProcess::terminate | ||||||
| 			#else | 			#else | ||||||
| @@ -848,8 +997,9 @@ void MainWindow::loadSettings() | |||||||
| 	if(qsettings.contains("ViewUnchanged")) | 	if(qsettings.contains("ViewUnchanged")) | ||||||
| 		ui->actionViewUnchanged->setChecked(qsettings.value("ViewUnchanged").toBool()); | 		ui->actionViewUnchanged->setChecked(qsettings.value("ViewUnchanged").toBool()); | ||||||
| 	if(qsettings.contains("ViewIgnored")) | 	if(qsettings.contains("ViewIgnored")) | ||||||
| 		ui->actionViewUnchanged->setChecked(qsettings.value("ViewIgnored").toBool()); | 		ui->actionViewIgnored->setChecked(qsettings.value("ViewIgnored").toBool()); | ||||||
|  | 	if(qsettings.contains("ViewAsList")) | ||||||
|  | 		ui->actionViewAsList->setChecked(qsettings.value("ViewAsList").toBool()); | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| @@ -881,10 +1031,80 @@ void MainWindow::saveSettings() | |||||||
| 	qsettings.setValue("ViewModified", ui->actionViewModified->isChecked()); | 	qsettings.setValue("ViewModified", ui->actionViewModified->isChecked()); | ||||||
| 	qsettings.setValue("ViewUnchanged", ui->actionViewUnchanged->isChecked()); | 	qsettings.setValue("ViewUnchanged", ui->actionViewUnchanged->isChecked()); | ||||||
| 	qsettings.setValue("ViewIgnored", ui->actionViewIgnored->isChecked()); | 	qsettings.setValue("ViewIgnored", ui->actionViewIgnored->isChecked()); | ||||||
|  | 	qsettings.setValue("ViewAsList", ui->actionViewAsList->isChecked()); | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| void MainWindow::getSelectionFilenames(QStringList &filenames, int includeMask, bool allIfEmpty) | void MainWindow::getSelectionFilenames(QStringList &filenames, int includeMask, bool allIfEmpty) | ||||||
|  | { | ||||||
|  | 	if(QApplication::focusWidget() == ui->tableView) | ||||||
|  | 		getFileViewSelection(filenames, includeMask, allIfEmpty); | ||||||
|  | 	else if(QApplication::focusWidget() == ui->treeView) | ||||||
|  | 		getDirViewSelection(filenames, includeMask, allIfEmpty); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::getSelectionPaths(pathset_t &paths) | ||||||
|  | { | ||||||
|  | 	// Determine the directories selected | ||||||
|  | 	QModelIndexList selection = ui->treeView->selectionModel()->selectedIndexes(); | ||||||
|  | 	for(QModelIndexList::iterator mi_it = selection.begin(); mi_it!=selection.end(); ++mi_it) | ||||||
|  | 	{ | ||||||
|  | 		const QModelIndex &mi = *mi_it; | ||||||
|  | 		QVariant data = repoDirModel.data(mi, REPODIRMODEL_ROLE_PATH); | ||||||
|  | 		paths.insert(data.toString()); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::getDirViewSelection(QStringList &filenames, int includeMask, bool allIfEmpty) | ||||||
|  | { | ||||||
|  | 	// Determine the directories selected | ||||||
|  | 	pathset_t paths; | ||||||
|  |  | ||||||
|  | 	QModelIndexList selection = ui->treeView->selectionModel()->selectedIndexes(); | ||||||
|  | 	if(!(selection.empty() && allIfEmpty)) | ||||||
|  | 	{ | ||||||
|  | 		getSelectionPaths(paths); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Select the actual files form the selected directories | ||||||
|  | 	for(filemap_t::iterator it=workspaceFiles.begin(); it!=workspaceFiles.end(); ++it) | ||||||
|  | 	{ | ||||||
|  | 		const RepoFile &e = *(*it); | ||||||
|  |  | ||||||
|  | 		// Skip unwanted file types | ||||||
|  | 		if(!(includeMask & e.getType())) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		bool include = true; | ||||||
|  |  | ||||||
|  | 		// If we have a limited set of paths to filter, check them | ||||||
|  | 		if(!paths.empty()) | ||||||
|  | 			include = false; | ||||||
|  |  | ||||||
|  | 		for(pathset_t::iterator p_it=paths.begin(); p_it!=paths.end(); ++p_it) | ||||||
|  | 		{ | ||||||
|  | 			const QString &path = *p_it; | ||||||
|  | 			// An empty path is the root folder, so it includes all files | ||||||
|  | 			// If the file's path starts with this, we include id | ||||||
|  | 			if(path.isEmpty() || e.getPath().indexOf(path)==0) | ||||||
|  | 			{ | ||||||
|  | 				include = true; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if(!include) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		filenames.append(e.getFilePath()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	qDebug() << filenames; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::getFileViewSelection(QStringList &filenames, int includeMask, bool allIfEmpty) | ||||||
| { | { | ||||||
| 	QModelIndexList selection = ui->tableView->selectionModel()->selectedIndexes(); | 	QModelIndexList selection = ui->tableView->selectionModel()->selectedIndexes(); | ||||||
| 	if(selection.empty() && allIfEmpty) | 	if(selection.empty() && allIfEmpty) | ||||||
| @@ -903,11 +1123,11 @@ void MainWindow::getSelectionFilenames(QStringList &filenames, int includeMask, | |||||||
| 		if(mi.column()!=COLUMN_FILENAME) | 		if(mi.column()!=COLUMN_FILENAME) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		QVariant data = itemModel.data(mi); | 		QVariant data = repoFileModel.data(mi, Qt::UserRole+1); | ||||||
| 		QString filename = data.toString(); | 		QString filename = data.toString(); | ||||||
| 		filemap_t::iterator e_it = workspaceFiles.find(filename); | 		filemap_t::iterator e_it = workspaceFiles.find(filename); | ||||||
| 		Q_ASSERT(e_it!=workspaceFiles.end()); | 		Q_ASSERT(e_it!=workspaceFiles.end()); | ||||||
| 		const RepoFile &e = e_it.value(); | 		const RepoFile &e = *e_it.value(); | ||||||
|  |  | ||||||
| 		// Skip unwanted files | 		// Skip unwanted files | ||||||
| 		if(!(includeMask & e.getType())) | 		if(!(includeMask & e.getType())) | ||||||
| @@ -1036,7 +1256,7 @@ void MainWindow::on_actionHistory_triggered() | |||||||
|  |  | ||||||
| 	for(QStringList::iterator it = selection.begin(); it!=selection.end(); ++it) | 	for(QStringList::iterator it = selection.begin(); it!=selection.end(); ++it) | ||||||
| 	{ | 	{ | ||||||
| 				QDesktopServices::openUrl(QUrl(getFossilHttpAddress()+"/finfo?name="+*it)); | 		QDesktopServices::openUrl(QUrl(getFossilHttpAddress()+"/finfo?name="+*it)); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1229,7 +1449,7 @@ void MainWindow::on_actionRename_triggered() | |||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| void MainWindow::on_actionNew_triggered() | void MainWindow::on_actionNewRepository_triggered() | ||||||
| { | { | ||||||
| 	QString filter(tr("Fossil Repositories (*.fossil)")); | 	QString filter(tr("Fossil Repositories (*.fossil)")); | ||||||
|  |  | ||||||
| @@ -1281,6 +1501,32 @@ void MainWindow::on_actionNew_triggered() | |||||||
| 	refresh(); | 	refresh(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::on_actionOpenRepository_triggered() | ||||||
|  | { | ||||||
|  | #if 0 | ||||||
|  | 	QString filter(tr("Fossil Repositories (*.fossil)")); | ||||||
|  |  | ||||||
|  | 	QString path = QFileDialog::getOpenFileName( | ||||||
|  | 				this, | ||||||
|  | 				tr("Fossil Repository"), | ||||||
|  | 				QDir::currentPath(), | ||||||
|  | 				filter, | ||||||
|  | 				&filter); | ||||||
|  |  | ||||||
|  | 	if(path.isEmpty()) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	if(!QFile::exists(path)) | ||||||
|  | 	{ | ||||||
|  | 		QMessageBox::critical(this, tr("Error"), tr("Repository file does not exist."), QMessageBox::Ok ); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| void MainWindow::on_actionClone_triggered() | void MainWindow::on_actionClone_triggered() | ||||||
| { | { | ||||||
| @@ -1478,10 +1724,210 @@ void MainWindow::on_actionViewIgnored_triggered() | |||||||
| 	refresh(); | 	refresh(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::on_actionViewAsList_triggered() | ||||||
|  | { | ||||||
|  | 	viewMode =  ui->actionViewAsList->isChecked() ? VIEWMODE_LIST : VIEWMODE_TREE; | ||||||
|  | 	ui->treeView->setVisible(viewMode == VIEWMODE_TREE); | ||||||
|  | 	updateFileView(); | ||||||
|  | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| QString MainWindow::getFossilHttpAddress() | QString MainWindow::getFossilHttpAddress() | ||||||
| { | { | ||||||
| 	return "http://127.0.0.1:"+fossilUIPort; | 	return "http://127.0.0.1:"+fossilUIPort; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::on_treeView_selectionChanged(const QItemSelection &selected, const QItemSelection &/*deselected*/) | ||||||
|  | { | ||||||
|  | 	if(selected.indexes().count()!=1) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	QModelIndex index = selected.indexes().at(0); | ||||||
|  | 	viewDir = repoDirModel.data(index, REPODIRMODEL_ROLE_PATH).toString(); | ||||||
|  | 	setStatus(viewDir); | ||||||
|  | 	updateFileView(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::on_actionOpenFolder_triggered() | ||||||
|  | { | ||||||
|  | 	const QItemSelection &selection =  ui->treeView->selectionModel()->selection(); | ||||||
|  |  | ||||||
|  | 	if(selection.indexes().count()!=1) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	QModelIndex index = selection.indexes().at(0); | ||||||
|  | 	QString target = repoDirModel.data(index, REPODIRMODEL_ROLE_PATH).toString(); | ||||||
|  | 	target = getCurrentWorkspace() + PATH_SEP + target; | ||||||
|  |  | ||||||
|  | 	QUrl url = QUrl::fromLocalFile(target); | ||||||
|  | 	QDesktopServices::openUrl(url); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void MainWindow::on_actionRenameFolder_triggered() | ||||||
|  | { | ||||||
|  | 	pathset_t paths; | ||||||
|  | 	getSelectionPaths(paths); | ||||||
|  |  | ||||||
|  | 	if(paths.size()!=1) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	QString old_path = *paths.begin(); | ||||||
|  |  | ||||||
|  | 	// Root Node? | ||||||
|  | 	if(old_path.isEmpty()) | ||||||
|  | 	{ | ||||||
|  | 		// Cannot change the project name via command line | ||||||
|  | 		// so unsupported | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	int dir_start = old_path.lastIndexOf(PATH_SEP); | ||||||
|  | 	if(dir_start==-1) | ||||||
|  | 		dir_start = 0; | ||||||
|  | 	else | ||||||
|  | 		++dir_start; | ||||||
|  |  | ||||||
|  | 	QString old_name = old_path.mid(dir_start); | ||||||
|  |  | ||||||
|  | 	bool ok = false; | ||||||
|  | 	QString new_name = QInputDialog::getText(this, tr("Rename Folder"), tr("Enter new name"), QLineEdit::Normal, old_name, &ok, Qt::Sheet); | ||||||
|  | 	if(!ok || old_name==new_name) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	const char* invalid_tokens[] = { | ||||||
|  | 		"/", "\\", "\\\\", ":", ">", "<", "*", "?", "|", "\"", ".." | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	for(size_t i=0; i<COUNTOF(invalid_tokens); ++i) | ||||||
|  | 	{ | ||||||
|  | 		if(new_name.indexOf(invalid_tokens[i])!=-1) | ||||||
|  | 		{ | ||||||
|  | 			QMessageBox::critical(this, tr("Error"), tr("Cannot rename folder.\nFolder name contains invalid characters.")); | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	QString new_path = old_path.left(dir_start) + new_name; | ||||||
|  |  | ||||||
|  | 	if(pathSet.contains(new_path)) | ||||||
|  | 	{ | ||||||
|  | 		QMessageBox::critical(this, tr("Error"), tr("Cannot rename folder.\nThis folder exists already.")); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Collect the files to be moved | ||||||
|  | 	filelist_t files_to_move; | ||||||
|  | 	QStringList new_paths; | ||||||
|  | 	QStringList operations; | ||||||
|  | 	foreach(RepoFile *r, workspaceFiles) | ||||||
|  | 	{ | ||||||
|  | 		if(r->getPath().indexOf(old_path)!=0) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		files_to_move.append(r); | ||||||
|  | 		QString new_dir = new_path + r->getPath().mid(old_path.length()); | ||||||
|  | 		new_paths.append(new_dir); | ||||||
|  | 		QString new_file_path =  new_dir + PATH_SEP + r->getFilename(); | ||||||
|  | 		operations.append(r->getFilePath() + " -> " + new_file_path); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(files_to_move.empty()) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	bool move_local = false; | ||||||
|  | 	if(!FileActionDialog::run(this, tr("Rename Folder"), tr("Renaming folder '")+old_path+tr("' to '")+new_path | ||||||
|  | 							  +tr("'\nThe following files will be moved in the repository. Are you sure?"), | ||||||
|  | 							  operations, | ||||||
|  | 							  tr("Also move the workspace files"), &move_local)) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Rename files in fossil | ||||||
|  | 	Q_ASSERT(files_to_move.length() == new_paths.length()); | ||||||
|  | 	for(int i=0; i<files_to_move.length(); ++i) | ||||||
|  | 	{ | ||||||
|  | 		RepoFile *r = files_to_move[i]; | ||||||
|  | 		const QString &new_file_path = new_paths[i] + PATH_SEP + r->getFilename(); | ||||||
|  |  | ||||||
|  | 		if(!runFossil(QStringList() << "mv" <<  QuotePath(r->getFilePath()) << QuotePath(new_file_path))) | ||||||
|  | 		{ | ||||||
|  | 			log(tr("Move aborted due to errors\n")); | ||||||
|  | 			goto _exit; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if(!move_local) | ||||||
|  | 		goto _exit; | ||||||
|  |  | ||||||
|  | 	// First ensure that the target directories exist, and if not make them | ||||||
|  | 	for(int i=0; i<files_to_move.length(); ++i) | ||||||
|  | 	{ | ||||||
|  | 		QString target_path = QDir::cleanPath(getCurrentWorkspace() + PATH_SEP + new_paths[i] + PATH_SEP); | ||||||
|  | 		QDir target(target_path); | ||||||
|  |  | ||||||
|  | 		if(target.exists()) | ||||||
|  | 			continue; | ||||||
|  |  | ||||||
|  | 		QDir wkdir(getCurrentWorkspace()); | ||||||
|  | 		Q_ASSERT(wkdir.exists()); | ||||||
|  |  | ||||||
|  | 		log(tr("Creating folder '")+target_path+"'\n"); | ||||||
|  | 		if(!wkdir.mkpath(new_paths[i] + PATH_SEP + ".")) | ||||||
|  | 		{ | ||||||
|  | 			QMessageBox::critical(this, tr("Error"), tr("Cannot make target folder '")+target_path+"'\n"); | ||||||
|  | 			goto _exit; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Now that target directories exist copy files | ||||||
|  | 	for(int i=0; i<files_to_move.length(); ++i) | ||||||
|  | 	{ | ||||||
|  | 		RepoFile *r = files_to_move[i]; | ||||||
|  | 		QString new_file_path = new_paths[i] + PATH_SEP + r->getFilename(); | ||||||
|  |  | ||||||
|  | 		if(QFile::exists(new_file_path)) | ||||||
|  | 		{ | ||||||
|  | 			QMessageBox::critical(this, tr("Error"), tr("Target file '")+new_file_path+tr("' exists already")); | ||||||
|  | 			goto _exit; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		log(tr("Copying file '")+r->getFilePath()+tr("' to '")+new_file_path+"'\n"); | ||||||
|  |  | ||||||
|  | 		if(!QFile::copy(r->getFilePath(), new_file_path)) | ||||||
|  | 		{ | ||||||
|  | 			QMessageBox::critical(this, tr("Error"), tr("Cannot copy file '")+r->getFilePath()+tr("' to '")+new_file_path+"'"); | ||||||
|  | 			goto _exit; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Finally delete old files | ||||||
|  | 	for(int i=0; i<files_to_move.length(); ++i) | ||||||
|  | 	{ | ||||||
|  | 		RepoFile *r = files_to_move[i]; | ||||||
|  |  | ||||||
|  | 		log(tr("Removing old file '")+r->getFilePath()+"'\n"); | ||||||
|  |  | ||||||
|  | 		if(!QFile::exists(r->getFilePath())) | ||||||
|  | 		{ | ||||||
|  | 			QMessageBox::critical(this, tr("Error"), tr("Source file '")+r->getFilePath()+tr("' does not exist")); | ||||||
|  | 			goto _exit; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if(!QFile::remove(r->getFilePath())) | ||||||
|  | 		{ | ||||||
|  | 			QMessageBox::critical(this, tr("Error"), tr("Cannot remove file '")+r->getFilePath()+"'"); | ||||||
|  | 			goto _exit; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	log(tr("Folder renamed completed. Don't forget to commit!\n")); | ||||||
|  |  | ||||||
|  | _exit: | ||||||
|  | 	refresh(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										62
									
								
								MainWindow.h
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								MainWindow.h
									
									
									
									
									
								
							| @@ -8,6 +8,7 @@ | |||||||
| #include <QFileInfo> | #include <QFileInfo> | ||||||
| #include <QDir> | #include <QDir> | ||||||
| #include <QProcess> | #include <QProcess> | ||||||
|  | #include <QSet> | ||||||
| #include "SettingsDialog.h" | #include "SettingsDialog.h" | ||||||
|  |  | ||||||
| namespace Ui { | namespace Ui { | ||||||
| @@ -32,11 +33,17 @@ struct RepoFile | |||||||
| 		TYPE_ALL			= TYPE_UNKNOWN|TYPE_REPO | 		TYPE_ALL			= TYPE_UNKNOWN|TYPE_REPO | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	void set(QFileInfo &info, EntryType type, const QString &repoPath) | 	RepoFile(QFileInfo &info, EntryType type, const QString &repoPath) | ||||||
| 	{ | 	{ | ||||||
| 		FileInfo = info; | 		FileInfo = info; | ||||||
| 		Type = type; | 		Type = type; | ||||||
| 		Filename = getRelativeFilename(repoPath); | 		FilePath = getRelativeFilename(repoPath); | ||||||
|  |  | ||||||
|  | 		if(FilePath.indexOf('/')!=-1) | ||||||
|  | 		{ | ||||||
|  | 			Path = FilePath; | ||||||
|  | 			Path = Path.left(Path.indexOf(FileInfo.fileName())-1); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool isType(EntryType t) const | 	bool isType(EntryType t) const | ||||||
| @@ -64,9 +71,19 @@ struct RepoFile | |||||||
| 		return Type == TYPE_UNCHANGED || Type == TYPE_EDITTED; | 		return Type == TYPE_UNCHANGED || Type == TYPE_EDITTED; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	const QString &getFilename() const | 	const QString &getFilePath() const | ||||||
| 	{ | 	{ | ||||||
| 		return Filename; | 		return FilePath; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	QString getFilename() const | ||||||
|  | 	{ | ||||||
|  | 		return FileInfo.fileName(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	const QString &getPath() const | ||||||
|  | 	{ | ||||||
|  | 		return Path; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	QString getRelativeFilename(const QString &path) | 	QString getRelativeFilename(const QString &path) | ||||||
| @@ -84,7 +101,8 @@ struct RepoFile | |||||||
| private: | private: | ||||||
| 	QFileInfo	FileInfo; | 	QFileInfo	FileInfo; | ||||||
| 	EntryType	Type; | 	EntryType	Type; | ||||||
| 	QString		Filename; | 	QString		FilePath; | ||||||
|  | 	QString		Path; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -98,6 +116,9 @@ public: | |||||||
|     ~MainWindow(); |     ~MainWindow(); | ||||||
| 	bool diffFile(QString repoFile); | 	bool diffFile(QString repoFile); | ||||||
|  |  | ||||||
|  | private: | ||||||
|  | 	typedef QSet<QString> pathset_t; | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	bool refresh(); | 	bool refresh(); | ||||||
| 	void scanWorkspace(); | 	void scanWorkspace(); | ||||||
| @@ -111,6 +132,9 @@ private: | |||||||
| 	void setStatus(const QString &text); | 	void setStatus(const QString &text); | ||||||
| 	bool uiRunning() const { return fossilUI.state() == QProcess::Running; } | 	bool uiRunning() const { return fossilUI.state() == QProcess::Running; } | ||||||
| 	void getSelectionFilenames(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false); | 	void getSelectionFilenames(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false); | ||||||
|  | 	void getFileViewSelection(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false); | ||||||
|  | 	void getDirViewSelection(QStringList &filenames, int includeMask=RepoFile::TYPE_ALL, bool allIfEmpty=false); | ||||||
|  | 	void getSelectionPaths(pathset_t &paths); | ||||||
| 	bool startUI(); | 	bool startUI(); | ||||||
| 	void stopUI(); | 	void stopUI(); | ||||||
| 	void enableActions(bool on); | 	void enableActions(bool on); | ||||||
| @@ -121,6 +145,8 @@ private: | |||||||
| 	QString getFossilPath(); | 	QString getFossilPath(); | ||||||
| 	QString getFossilHttpAddress(); | 	QString getFossilHttpAddress(); | ||||||
| 	bool scanDirectory(QFileInfoList &entries, const QString& dirPath, const QString &baseDir, const QString ignoreSpec); | 	bool scanDirectory(QFileInfoList &entries, const QString& dirPath, const QString &baseDir, const QString ignoreSpec); | ||||||
|  | 	void updateDirView(); | ||||||
|  | 	void updateFileView(); | ||||||
|  |  | ||||||
| 	enum RepoStatus | 	enum RepoStatus | ||||||
| 	{ | 	{ | ||||||
| @@ -131,9 +157,16 @@ private: | |||||||
|  |  | ||||||
| 	RepoStatus getRepoStatus(); | 	RepoStatus getRepoStatus(); | ||||||
|  |  | ||||||
|  | 	enum ViewMode | ||||||
|  | 	{ | ||||||
|  | 		VIEWMODE_LIST, | ||||||
|  | 		VIEWMODE_TREE | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| private slots: | private slots: | ||||||
| 	// Manual slots | 	// Manual slots | ||||||
| 	void onOpenRecent(); | 	void on_openRecent(); | ||||||
|  | 	void on_treeView_selectionChanged(const class QItemSelection &selected, const class QItemSelection &deselected); | ||||||
|  |  | ||||||
| 	// Designer slots | 	// Designer slots | ||||||
| 	void on_actionRefresh_triggered(); | 	void on_actionRefresh_triggered(); | ||||||
| @@ -152,7 +185,6 @@ private slots: | |||||||
| 	void on_actionAdd_triggered(); | 	void on_actionAdd_triggered(); | ||||||
| 	void on_actionDelete_triggered(); | 	void on_actionDelete_triggered(); | ||||||
| 	void on_actionRevert_triggered(); | 	void on_actionRevert_triggered(); | ||||||
| 	void on_actionNew_triggered(); |  | ||||||
| 	void on_actionClone_triggered(); | 	void on_actionClone_triggered(); | ||||||
| 	void on_actionOpenContaining_triggered(); | 	void on_actionOpenContaining_triggered(); | ||||||
| 	void on_actionRename_triggered(); | 	void on_actionRename_triggered(); | ||||||
| @@ -164,8 +196,12 @@ private slots: | |||||||
| 	void on_actionViewUnchanged_triggered(); | 	void on_actionViewUnchanged_triggered(); | ||||||
| 	void on_actionViewModified_triggered(); | 	void on_actionViewModified_triggered(); | ||||||
| 	void on_actionViewUnknown_triggered(); | 	void on_actionViewUnknown_triggered(); | ||||||
|  |  | ||||||
| 	void on_actionViewIgnored_triggered(); | 	void on_actionViewIgnored_triggered(); | ||||||
|  | 	void on_actionViewAsList_triggered(); | ||||||
|  | 	void on_actionOpenFolder_triggered(); | ||||||
|  | 	void on_actionRenameFolder_triggered(); | ||||||
|  | 	void on_actionOpenRepository_triggered(); | ||||||
|  | 	void on_actionNewRepository_triggered(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
| 	enum | 	enum | ||||||
| @@ -174,7 +210,8 @@ private: | |||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Ui::MainWindow		*ui; | 	Ui::MainWindow		*ui; | ||||||
| 	QStandardItemModel	itemModel; | 	QStandardItemModel	repoFileModel; | ||||||
|  | 	QStandardItemModel	repoDirModel; | ||||||
| 	QProcess			fossilUI; | 	QProcess			fossilUI; | ||||||
| 	QString				fossilUIPort; | 	QString				fossilUIPort; | ||||||
| 	class QAction		*recentWorkspaceActs[MAX_RECENT]; | 	class QAction		*recentWorkspaceActs[MAX_RECENT]; | ||||||
| @@ -187,11 +224,14 @@ private: | |||||||
| 	QStringList			workspaceHistory; | 	QStringList			workspaceHistory; | ||||||
| 	QString				currentWorkspace; | 	QString				currentWorkspace; | ||||||
| 	QStringList			commitMessages; | 	QStringList			commitMessages; | ||||||
|  | 	ViewMode			viewMode; | ||||||
|  | 	QString				viewDir;	// The directory selected in the tree | ||||||
|  |  | ||||||
| 	// Repo State | 	// Repo State | ||||||
| 	typedef QMap<QString, RepoFile> filemap_t; | 	typedef QList<RepoFile*> filelist_t; | ||||||
|  | 	typedef QMap<QString, RepoFile*> filemap_t; | ||||||
| 	filemap_t			workspaceFiles; | 	filemap_t			workspaceFiles; | ||||||
|  | 	pathset_t			pathSet; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif // MAINWINDOW_H | #endif // MAINWINDOW_H | ||||||
|   | |||||||
							
								
								
									
										204
									
								
								MainWindow.ui
									
									
									
									
									
								
							
							
						
						
									
										204
									
								
								MainWindow.ui
									
									
									
									
									
								
							| @@ -26,47 +26,84 @@ | |||||||
|      <number>4</number> |      <number>4</number> | ||||||
|     </property> |     </property> | ||||||
|     <item> |     <item> | ||||||
|      <widget class="QSplitter" name="splitter"> |      <widget class="QSplitter" name="splitter_2"> | ||||||
|       <property name="orientation"> |       <property name="orientation"> | ||||||
|        <enum>Qt::Vertical</enum> |        <enum>Qt::Vertical</enum> | ||||||
|       </property> |       </property> | ||||||
|       <widget class="QTableView" name="tableView"> |       <widget class="QSplitter" name="splitter"> | ||||||
|        <property name="sizePolicy"> |        <property name="sizePolicy"> | ||||||
|         <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> |         <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> | ||||||
|          <horstretch>0</horstretch> |          <horstretch>0</horstretch> | ||||||
|          <verstretch>80</verstretch> |          <verstretch>80</verstretch> | ||||||
|         </sizepolicy> |         </sizepolicy> | ||||||
|        </property> |        </property> | ||||||
|        <property name="contextMenuPolicy"> |        <property name="orientation"> | ||||||
|         <enum>Qt::ActionsContextMenu</enum> |         <enum>Qt::Horizontal</enum> | ||||||
|        </property> |        </property> | ||||||
|        <property name="editTriggers"> |        <widget class="QTreeView" name="treeView"> | ||||||
|         <set>QAbstractItemView::NoEditTriggers</set> |         <property name="sizePolicy"> | ||||||
|        </property> |          <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> | ||||||
|        <property name="alternatingRowColors"> |           <horstretch>20</horstretch> | ||||||
|         <bool>true</bool> |           <verstretch>0</verstretch> | ||||||
|        </property> |          </sizepolicy> | ||||||
|        <property name="selectionBehavior"> |         </property> | ||||||
|         <enum>QAbstractItemView::SelectRows</enum> |         <property name="contextMenuPolicy"> | ||||||
|        </property> |          <enum>Qt::ActionsContextMenu</enum> | ||||||
|        <property name="showGrid"> |         </property> | ||||||
|         <bool>false</bool> |         <property name="editTriggers"> | ||||||
|        </property> |          <set>QAbstractItemView::NoEditTriggers</set> | ||||||
|        <property name="sortingEnabled"> |         </property> | ||||||
|         <bool>true</bool> |         <property name="selectionMode"> | ||||||
|        </property> |          <enum>QAbstractItemView::ExtendedSelection</enum> | ||||||
|        <property name="wordWrap"> |         </property> | ||||||
|         <bool>false</bool> |         <property name="selectionBehavior"> | ||||||
|        </property> |          <enum>QAbstractItemView::SelectItems</enum> | ||||||
|        <attribute name="horizontalHeaderMinimumSectionSize"> |         </property> | ||||||
|         <number>20</number> |         <property name="sortingEnabled"> | ||||||
|        </attribute> |          <bool>true</bool> | ||||||
|        <attribute name="verticalHeaderVisible"> |         </property> | ||||||
|         <bool>false</bool> |         <attribute name="headerVisible"> | ||||||
|        </attribute> |          <bool>false</bool> | ||||||
|        <attribute name="verticalHeaderDefaultSectionSize"> |         </attribute> | ||||||
|         <number>30</number> |        </widget> | ||||||
|        </attribute> |        <widget class="QTableView" name="tableView"> | ||||||
|  |         <property name="sizePolicy"> | ||||||
|  |          <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> | ||||||
|  |           <horstretch>80</horstretch> | ||||||
|  |           <verstretch>0</verstretch> | ||||||
|  |          </sizepolicy> | ||||||
|  |         </property> | ||||||
|  |         <property name="contextMenuPolicy"> | ||||||
|  |          <enum>Qt::ActionsContextMenu</enum> | ||||||
|  |         </property> | ||||||
|  |         <property name="editTriggers"> | ||||||
|  |          <set>QAbstractItemView::NoEditTriggers</set> | ||||||
|  |         </property> | ||||||
|  |         <property name="alternatingRowColors"> | ||||||
|  |          <bool>true</bool> | ||||||
|  |         </property> | ||||||
|  |         <property name="selectionBehavior"> | ||||||
|  |          <enum>QAbstractItemView::SelectRows</enum> | ||||||
|  |         </property> | ||||||
|  |         <property name="showGrid"> | ||||||
|  |          <bool>false</bool> | ||||||
|  |         </property> | ||||||
|  |         <property name="sortingEnabled"> | ||||||
|  |          <bool>true</bool> | ||||||
|  |         </property> | ||||||
|  |         <property name="wordWrap"> | ||||||
|  |          <bool>false</bool> | ||||||
|  |         </property> | ||||||
|  |         <attribute name="horizontalHeaderMinimumSectionSize"> | ||||||
|  |          <number>20</number> | ||||||
|  |         </attribute> | ||||||
|  |         <attribute name="verticalHeaderVisible"> | ||||||
|  |          <bool>false</bool> | ||||||
|  |         </attribute> | ||||||
|  |         <attribute name="verticalHeaderDefaultSectionSize"> | ||||||
|  |          <number>30</number> | ||||||
|  |         </attribute> | ||||||
|  |        </widget> | ||||||
|       </widget> |       </widget> | ||||||
|       <widget class="QTextBrowser" name="textBrowser"> |       <widget class="QTextBrowser" name="textBrowser"> | ||||||
|        <property name="sizePolicy"> |        <property name="sizePolicy"> | ||||||
| @@ -93,11 +130,12 @@ | |||||||
|     <property name="title"> |     <property name="title"> | ||||||
|      <string>Workspace</string> |      <string>Workspace</string> | ||||||
|     </property> |     </property> | ||||||
|     <addaction name="actionNew"/> |  | ||||||
|     <addaction name="actionOpen"/> |     <addaction name="actionOpen"/> | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
|     <addaction name="actionSyncSettings"/> |     <addaction name="actionNewRepository"/> | ||||||
|  |     <addaction name="actionOpenRepository"/> | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
|  |     <addaction name="actionSyncSettings"/> | ||||||
|     <addaction name="actionSettings"/> |     <addaction name="actionSettings"/> | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
| @@ -117,6 +155,8 @@ | |||||||
|     <addaction name="actionViewUnchanged"/> |     <addaction name="actionViewUnchanged"/> | ||||||
|     <addaction name="actionViewUnknown"/> |     <addaction name="actionViewUnknown"/> | ||||||
|     <addaction name="actionViewIgnored"/> |     <addaction name="actionViewIgnored"/> | ||||||
|  |     <addaction name="separator"/> | ||||||
|  |     <addaction name="actionViewAsList"/> | ||||||
|    </widget> |    </widget> | ||||||
|    <addaction name="menuFile"/> |    <addaction name="menuFile"/> | ||||||
|    <addaction name="menuView"/> |    <addaction name="menuView"/> | ||||||
| @@ -240,6 +280,9 @@ | |||||||
|    <property name="toolTip"> |    <property name="toolTip"> | ||||||
|     <string>Open a fossil checkout folder</string> |     <string>Open a fossil checkout folder</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Open a fossil checkout folder</string> | ||||||
|  |    </property> | ||||||
|    <property name="shortcut"> |    <property name="shortcut"> | ||||||
|     <string>Ctrl+O</string> |     <string>Ctrl+O</string> | ||||||
|    </property> |    </property> | ||||||
| @@ -294,6 +337,9 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Quit</string> |     <string>Quit</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Quit</string> | ||||||
|  |    </property> | ||||||
|    <property name="shortcut"> |    <property name="shortcut"> | ||||||
|     <string>Ctrl+Q</string> |     <string>Ctrl+Q</string> | ||||||
|    </property> |    </property> | ||||||
| @@ -379,7 +425,7 @@ | |||||||
|     <string>Ctrl+Return</string> |     <string>Ctrl+Return</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionNew"> |   <action name="actionNewRepository"> | ||||||
|    <property name="icon"> |    <property name="icon"> | ||||||
|     <iconset resource="resources.qrc"> |     <iconset resource="resources.qrc"> | ||||||
|      <normaloff>:/icons/icons/Book-01.png</normaloff>:/icons/icons/Book-01.png</iconset> |      <normaloff>:/icons/icons/Book-01.png</normaloff>:/icons/icons/Book-01.png</iconset> | ||||||
| @@ -387,11 +433,25 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>New Repository...</string> |     <string>New Repository...</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="toolTip"> | ||||||
|  |     <string>Make a new Fossil repository</string> | ||||||
|  |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Make a new Fossil repository</string> | ||||||
|  |    </property> | ||||||
|    <property name="shortcut"> |    <property name="shortcut"> | ||||||
|     <string>Ctrl+N</string> |     <string>Ctrl+N</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionClone"> |   <action name="actionOpenRepository"> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Open Repository...</string> | ||||||
|  |    </property> | ||||||
|  |    <property name="toolTip"> | ||||||
|  |     <string>Open Repository</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionCloneRepository"> | ||||||
|    <property name="icon"> |    <property name="icon"> | ||||||
|     <iconset resource="resources.qrc"> |     <iconset resource="resources.qrc"> | ||||||
|      <normaloff>:/icons/icons/Address Book-01.png</normaloff>:/icons/icons/Address Book-01.png</iconset> |      <normaloff>:/icons/icons/Address Book-01.png</normaloff>:/icons/icons/Address Book-01.png</iconset> | ||||||
| @@ -432,6 +492,9 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>About...</string> |     <string>About...</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>About Fuel</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionUpdate"> |   <action name="actionUpdate"> | ||||||
|    <property name="icon"> |    <property name="icon"> | ||||||
| @@ -456,6 +519,9 @@ | |||||||
|    <property name="toolTip"> |    <property name="toolTip"> | ||||||
|     <string>Application Preferences</string> |     <string>Application Preferences</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Set application preferences</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionSyncSettings"> |   <action name="actionSyncSettings"> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
| @@ -464,6 +530,9 @@ | |||||||
|    <property name="toolTip"> |    <property name="toolTip"> | ||||||
|     <string>Set remote synchronization settings</string> |     <string>Set remote synchronization settings</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Set remote synchronization settings</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionViewModified"> |   <action name="actionViewModified"> | ||||||
|    <property name="checkable"> |    <property name="checkable"> | ||||||
| @@ -475,6 +544,9 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Modified</string> |     <string>Modified</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Show modifed files</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionViewUnchanged"> |   <action name="actionViewUnchanged"> | ||||||
|    <property name="checkable"> |    <property name="checkable"> | ||||||
| @@ -486,6 +558,9 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Unchanged</string> |     <string>Unchanged</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Show unchanged files</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionViewUnknown"> |   <action name="actionViewUnknown"> | ||||||
|    <property name="checkable"> |    <property name="checkable"> | ||||||
| @@ -497,6 +572,9 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Unknown</string> |     <string>Unknown</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Show unknown files</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|   <action name="actionViewIgnored"> |   <action name="actionViewIgnored"> | ||||||
|    <property name="checkable"> |    <property name="checkable"> | ||||||
| @@ -505,28 +583,46 @@ | |||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>Ignored</string> |     <string>Ignored</string> | ||||||
|    </property> |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>Show ignored files</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionViewAsList"> | ||||||
|  |    <property name="checkable"> | ||||||
|  |     <bool>true</bool> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>View as List</string> | ||||||
|  |    </property> | ||||||
|  |    <property name="statusTip"> | ||||||
|  |     <string>View workspace as a list of files</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionOpenFolder"> | ||||||
|  |    <property name="icon"> | ||||||
|  |     <iconset resource="resources.qrc"> | ||||||
|  |      <normaloff>:/icons/icons/My Documents-01.png</normaloff>:/icons/icons/My Documents-01.png</iconset> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Open Folder</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionRenameFolder"> | ||||||
|  |    <property name="icon"> | ||||||
|  |     <iconset resource="resources.qrc"> | ||||||
|  |      <normaloff>:/icons/icons/Folder Open-01.png</normaloff>:/icons/icons/Folder Open-01.png</iconset> | ||||||
|  |    </property> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Rename Folder</string> | ||||||
|  |    </property> | ||||||
|  |    <property name="toolTip"> | ||||||
|  |     <string>Rename Folder</string> | ||||||
|  |    </property> | ||||||
|   </action> |   </action> | ||||||
|  </widget> |  </widget> | ||||||
|  <layoutdefault spacing="6" margin="11"/> |  <layoutdefault spacing="6" margin="11"/> | ||||||
|  <resources> |  <resources> | ||||||
|   <include location="resources.qrc"/> |   <include location="resources.qrc"/> | ||||||
|  </resources> |  </resources> | ||||||
|  <connections> |  <connections/> | ||||||
|   <connection> |  | ||||||
|    <sender>tableView</sender> |  | ||||||
|    <signal>customContextMenuRequested(QPoint)</signal> |  | ||||||
|    <receiver>MainWindow</receiver> |  | ||||||
|    <slot>deleteLater()</slot> |  | ||||||
|    <hints> |  | ||||||
|     <hint type="sourcelabel"> |  | ||||||
|      <x>432</x> |  | ||||||
|      <y>278</y> |  | ||||||
|     </hint> |  | ||||||
|     <hint type="destinationlabel"> |  | ||||||
|      <x>432</x> |  | ||||||
|      <y>319</y> |  | ||||||
|     </hint> |  | ||||||
|    </hints> |  | ||||||
|   </connection> |  | ||||||
|  </connections> |  | ||||||
| </ui> | </ui> | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								manifest
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								manifest
									
									
									
									
									
								
							| @@ -1,14 +1,14 @@ | |||||||
| C Added\sInstaller\sfor\sWin32 | C Added\sWorkspace\sTree\sview\nAdded\sRename\sFolder\saction\nMinor\sGUI\scleanups\n | ||||||
| D 2011-10-15T07:03:12.801 | D 2011-10-17T14:58:09.384 | ||||||
| F CommitDialog.cpp 8965e52d077c300cf1acb1b16fb2dcca5c7070f8 | F CommitDialog.cpp 8965e52d077c300cf1acb1b16fb2dcca5c7070f8 | ||||||
| F CommitDialog.h a9596d99865cf312b419d01d51334ffc916f5508 | F CommitDialog.h a9596d99865cf312b419d01d51334ffc916f5508 | ||||||
| F CommitDialog.ui 5067623f6af6f5a42c87df903278e383e945e154 | F CommitDialog.ui 5067623f6af6f5a42c87df903278e383e945e154 | ||||||
| F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8 | F FileActionDialog.cpp fcaebf9986f789b3440d5390b3458ad5f86fe0c8 | ||||||
| F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce | F FileActionDialog.h 15db1650b3a13d70bc338371e4c033c66e3b79ce | ||||||
| F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7 | F FileActionDialog.ui c63644428579741aeb5fa052e237ba799ced9ad7 | ||||||
| F MainWindow.cpp 25d3453d37711c8bb1b01d329892ef4d58d223d8 | F MainWindow.cpp 1ca79369fdb5cbe87dcc38d3f2aebd8a007d64f0 | ||||||
| F MainWindow.h 55f90fe948661a6b7382470f3cdc80dc592e76c4 | F MainWindow.h 6fdcb10c8a6da760c83dd05f1d07b69132ba3d4c | ||||||
| F MainWindow.ui d22becfdb32d4b31ed9a6e6d68dd144870d9a957 | F MainWindow.ui 82a3d869e043314a0c9a4c0821de2469d565b782 | ||||||
| F RepoDialog.cpp 8f20e1511526973555c774350ec413dcecf51c9e | F RepoDialog.cpp 8f20e1511526973555c774350ec413dcecf51c9e | ||||||
| F RepoDialog.h a958c5f98f1e6882bf41dbdd2e4df3cb89700802 | F RepoDialog.h a958c5f98f1e6882bf41dbdd2e4df3cb89700802 | ||||||
| F RepoDialog.ui be7b18199c04a3003f3c7534a616cd7441b7bb0c | F RepoDialog.ui be7b18199c04a3003f3c7534a616cd7441b7bb0c | ||||||
| @@ -175,7 +175,7 @@ F installer/fuel.iss 13b6a938bcdf273cbd3649d2549887baa1577214 | |||||||
| F installer/license.txt 4cc77b90af91e615a64ae04893fdffa7939db84c | F installer/license.txt 4cc77b90af91e615a64ae04893fdffa7939db84c | ||||||
| F main.cpp f67a9b5c9ca0b634b19ef08e7136032372d37f93 | F main.cpp f67a9b5c9ca0b634b19ef08e7136032372d37f93 | ||||||
| F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53 | F resources.qrc e98383ed205f4e37100c60057e0129c3b86dea53 | ||||||
| P 4e53a5ec6844f3a210ba2fbfc2185840d697b0bb | P a29a3fd0f7f4c26591e1ca168ad63f1f7530edbe | ||||||
| R 62600d2edbddf7a761b84fb85d9cbf33 | R 4d693a61ebb632ca6600c2150bca11d5 | ||||||
| U kostas | U kostas | ||||||
| Z eb7bffb75807cc22987af216d0cd4213 | Z a4c724920b064e72a32c87376626c0ab | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| a29a3fd0f7f4c26591e1ca168ad63f1f7530edbe | 5fc925ac68148c69db66e88e23be196807ffec22 | ||||||
		Reference in New Issue
	
	Block a user