Fuel

Diff
Login

Differences From Artifact [27e87d3306]:

To Artifact [44316f743a]:


10
11
12
13
14
15
16

17
18
19
20
21
22
23
24
25
26
#include <QTemporaryFile>
#include <QMessageBox>
#include <QUrl>
#include <QInputDialog>
#include <QDrag>
#include <QMimeData>
#include <QFileIconProvider>

#include "CommitDialog.h"
#include "FileActionDialog.h"
#include <QDebug>
#include "Utils.h"

#define COUNTOF(array) (sizeof(array)/sizeof(array[0]))

#ifdef QT_WS_WIN
	const QString EOL_MARK("\r\n");
#else







>


<







10
11
12
13
14
15
16
17
18
19

20
21
22
23
24
25
26
#include <QTemporaryFile>
#include <QMessageBox>
#include <QUrl>
#include <QInputDialog>
#include <QDrag>
#include <QMimeData>
#include <QFileIconProvider>
#include <QDebug>
#include "CommitDialog.h"
#include "FileActionDialog.h"

#include "Utils.h"

#define COUNTOF(array) (sizeof(array)/sizeof(array[0]))

#ifdef QT_WS_WIN
	const QString EOL_MARK("\r\n");
#else
160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
		ui->menuFile->insertAction(recent_sep, recentWorkspaceActs[i]);
	}

	statusLabel = new QLabel();
	statusLabel->setMinimumSize( statusLabel->sizeHint() );
	ui->statusBar->addWidget( statusLabel, 1 );

// Native applications on OSX don't use menu icons
#ifdef Q_WS_MACX

	foreach(QAction *a, ui->menuBar->actions())
		a->setIconVisibleInMenu(false);
	foreach(QAction *a, ui->menuFile->actions())
		a->setIconVisibleInMenu(false);
#endif

	viewMode = VIEWMODE_TREE;
	loadSettings();

	// Apply any explict workspace path if available
	if(workspacePath && !workspacePath->isEmpty())
		openWorkspace(*workspacePath);

	refresh();
	rebuildRecent();

	// Select the Root of the tree to update the file view







<

>









|







160
161
162
163
164
165
166

167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
		ui->menuFile->insertAction(recent_sep, recentWorkspaceActs[i]);
	}

	statusLabel = new QLabel();
	statusLabel->setMinimumSize( statusLabel->sizeHint() );
	ui->statusBar->addWidget( statusLabel, 1 );


#ifdef Q_WS_MACX
	// Native applications on OSX don't use menu icons
	foreach(QAction *a, ui->menuBar->actions())
		a->setIconVisibleInMenu(false);
	foreach(QAction *a, ui->menuFile->actions())
		a->setIconVisibleInMenu(false);
#endif

	viewMode = VIEWMODE_TREE;
	loadSettings();

	// Apply any explicit workspace path if available
	if(workspacePath && !workspacePath->isEmpty())
		openWorkspace(*workspacePath);

	refresh();
	rebuildRecent();

	// Select the Root of the tree to update the file view
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	{
		wkspace = fi.absoluteDir().absolutePath();
		QString checkout_file1 = wkspace + PATH_SEP + FOSSIL_CHECKOUT1;
		QString checkout_file2 = wkspace + PATH_SEP + FOSSIL_CHECKOUT2;

		if(!(QFileInfo(checkout_file1).exists() || QFileInfo(checkout_file2).exists()) )
		{
			if(QMessageBox::Yes !=DialogQuery(this, tr("Open Fossil"), "A workspace does not exist in this folder.\nWould you like to create one here?"))
			{
				wkspace = QFileDialog::getExistingDirectory(
							this,
							tr("Select Workspace Folder"),
							wkspace);

				if(wkspace.isEmpty() || !QDir(wkspace).exists())







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	{
		wkspace = fi.absoluteDir().absolutePath();
		QString checkout_file1 = wkspace + PATH_SEP + FOSSIL_CHECKOUT1;
		QString checkout_file2 = wkspace + PATH_SEP + FOSSIL_CHECKOUT2;

		if(!(QFileInfo(checkout_file1).exists() || QFileInfo(checkout_file2).exists()) )
		{
			if(QMessageBox::Yes !=DialogQuery(this, tr("Open Fossil"), tr("A workspace does not exist in this folder.\nWould you like to create one here?")))
			{
				wkspace = QFileDialog::getExistingDirectory(
							this,
							tr("Select Workspace Folder"),
							wkspace);

				if(wkspace.isEmpty() || !QDir(wkspace).exists())
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
	}

	QFileInfo repo_path_info(repo_path);
	Q_ASSERT(repo_path_info.dir().exists());

	// Get Workspace path
	QString wkdir = repo_path_info.absoluteDir().absolutePath();
	if(QMessageBox::Yes != DialogQuery(this, tr("Create Workspace"), "Would you like to create a workspace in the same folder?"))
	{
		wkdir = QFileDialog::getExistingDirectory(
			this,
			tr("Select Workspace Folder"),
			wkdir);

		if(wkdir.isEmpty() || !QDir(wkdir).exists())







|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
	}

	QFileInfo repo_path_info(repo_path);
	Q_ASSERT(repo_path_info.dir().exists());

	// Get Workspace path
	QString wkdir = repo_path_info.absoluteDir().absolutePath();
	if(QMessageBox::Yes != DialogQuery(this, tr("Create Workspace"), tr("Would you like to create a workspace in the same folder?")))
	{
		wkdir = QFileDialog::getExistingDirectory(
			this,
			tr("Select Workspace Folder"),
			wkdir);

		if(wkdir.isEmpty() || !QDir(wkdir).exists())
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425

//------------------------------------------------------------------------------
void MainWindow::on_actionCloseRepository_triggered()
{
	if(getRepoStatus()!=REPO_OK)
		return;

	if(QMessageBox::Yes !=DialogQuery(this, tr("Close Workspace"), "Are you sure want to close this workspace?"))
		return;

	// Close Repo
	if(!runFossil(QStringList() << "close"))
	{
		QMessageBox::critical(this, tr("Error"), tr("Cannot close the workspace.\nAre there still uncommitted changes in available?"), QMessageBox::Ok );
		return;







|







411
412
413
414
415
416
417
418
419
420
421
422
423
424
425

//------------------------------------------------------------------------------
void MainWindow::on_actionCloseRepository_triggered()
{
	if(getRepoStatus()!=REPO_OK)
		return;

	if(QMessageBox::Yes !=DialogQuery(this, tr("Close Workspace"), tr("Are you sure want to close this workspace?")))
		return;

	// Close Repo
	if(!runFossil(QStringList() << "close"))
	{
		QMessageBox::critical(this, tr("Error"), tr("Cannot close the workspace.\nAre there still uncommitted changes in available?"), QMessageBox::Ok );
		return;
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757

	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)
			{







|







743
744
745
746
747
748
749
750
751
752
753
754
755
756
757

	QString fullpath;
	for(QStringList::iterator it = dirs.begin(); it!=dirs.end(); ++it)
	{
		const QString &dir = *it;
		fullpath += dir;

		// Find the child that matches this subdirectory
		bool found = false;
		for(int r=0; r<parent->rowCount(); ++r)
		{
			QStandardItem *child = parent->child(r, 0);
			Q_ASSERT(child);
			if(child->text() == dir)
			{
806
807
808
809
810
811
812
813


814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
	repoFileModel.clear();

	QStringList header;
	header << tr("S") << tr("File") << tr("Ext") << tr("Modified");

	bool multiple_dirs = selectedDirs.count()>1;

	if(viewMode==VIEWMODE_LIST || multiple_dirs)


		header << tr("Path");

	repoFileModel.setHorizontalHeaderLabels(header);

	struct { RepoFile::EntryType type; const char *tag; const char *tooltip; const char *icon; }
	stats[] =
	{
		{   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_ADDED, "A", "Added", ":icons/icons/Button Add-01.png" },
		{   RepoFile::TYPE_DELETED, "D", "Deleted", ":icons/icons/Button Close-01.png" },
		{   RepoFile::TYPE_RENAMED, "R", "Renamed", ":icons/icons/Button Reload-01.png" },
		{   RepoFile::TYPE_MISSING, "M", "Missing", ":icons/icons/Button Help-01.png" },
	};








|
>
>







|







806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
	repoFileModel.clear();

	QStringList header;
	header << tr("S") << tr("File") << tr("Ext") << tr("Modified");

	bool multiple_dirs = selectedDirs.count()>1;

	bool show_path = viewMode==VIEWMODE_LIST || multiple_dirs;

	if(show_path)
		header << tr("Path");

	repoFileModel.setHorizontalHeaderLabels(header);

	struct { RepoFile::EntryType type; const char *tag; const char *tooltip; const char *icon; }
	stats[] =
	{
		{   RepoFile::TYPE_EDITTED, "E", "Edited", ":icons/icons/Button Blank Yellow-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_DELETED, "D", "Deleted", ":icons/icons/Button Close-01.png" },
		{   RepoFile::TYPE_RENAMED, "R", "Renamed", ":icons/icons/Button Reload-01.png" },
		{   RepoFile::TYPE_MISSING, "M", "Missing", ":icons/icons/Button Help-01.png" },
	};

858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
		status->setToolTip(tooltip);
		repoFileModel.setItem(item_id, COLUMN_STATUS, status);

		QFileInfo finfo = e.getFileInfo();
		QIcon icon = icon_provider.icon(finfo);

		QStandardItem *filename_item = 0;
		if(viewMode==VIEWMODE_LIST || multiple_dirs)
		{
			repoFileModel.setItem(item_id, COLUMN_PATH, new QStandardItem(path));
			filename_item = new QStandardItem(icon, QDir::toNativeSeparators(e.getFilePath()));
		}
		else // In Tree mode the path is implicit so the file name is enough
		filename_item = new QStandardItem(icon, e.getFilename());








|







860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
		status->setToolTip(tooltip);
		repoFileModel.setItem(item_id, COLUMN_STATUS, status);

		QFileInfo finfo = e.getFileInfo();
		QIcon icon = icon_provider.icon(finfo);

		QStandardItem *filename_item = 0;
		if(show_path)
		{
			repoFileModel.setItem(item_id, COLUMN_PATH, new QStandardItem(path));
			filename_item = new QStandardItem(icon, QDir::toNativeSeparators(e.getFilePath()));
		}
		else // In Tree mode the path is implicit so the file name is enough
		filename_item = new QStandardItem(icon, e.getFilename());

881
882
883
884
885
886
887

888
889
890
891
892
893
894
895
		++item_id;
	}

	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_STATUS, QHeaderView::ResizeToContents);
	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_FILENAME, QHeaderView::Stretch);
	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_EXTENSION, QHeaderView::ResizeToContents);
	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_MODIFIED, QHeaderView::ResizeToContents);

	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_PATH, QHeaderView::ResizeToContents);
	ui->tableView->horizontalHeader()->setSortIndicatorShown(true);
	ui->tableView->resizeRowsToContents();
}

//------------------------------------------------------------------------------
MainWindow::RepoStatus MainWindow::getRepoStatus()
{







>
|







883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
		++item_id;
	}

	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_STATUS, QHeaderView::ResizeToContents);
	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_FILENAME, QHeaderView::Stretch);
	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_EXTENSION, QHeaderView::ResizeToContents);
	ui->tableView->horizontalHeader()->setResizeMode(COLUMN_MODIFIED, QHeaderView::ResizeToContents);
	if(show_path)
		ui->tableView->horizontalHeader()->setResizeMode(COLUMN_PATH, QHeaderView::ResizeToContents);
	ui->tableView->horizontalHeader()->setSortIndicatorShown(true);
	ui->tableView->resizeRowsToContents();
}

//------------------------------------------------------------------------------
MainWindow::RepoStatus MainWindow::getRepoStatus()
{
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
	}

	comment_file.write(msg.toUtf8());
	comment_file.close();

    // Generate fossil parameters.
    // When all files are selected avoid explicitly specifying filenames.
    // This is necessary when commiting after a merge where fossil thinks that
    // we a doing a partial commit, which is not allowed in this case.
    QStringList params;
    params << "commit" << "--message-file" << QuotePath(comment_fname);

    if(modified_files != commit_files)
        params  << QuotePaths(commit_files);








|







1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
	}

	comment_file.write(msg.toUtf8());
	comment_file.close();

    // Generate fossil parameters.
    // When all files are selected avoid explicitly specifying filenames.
    // This is necessary when committing after a merge where fossil thinks that
    // we a doing a partial commit, which is not allowed in this case.
    QStringList params;
    params << "commit" << "--message-file" << QuotePath(comment_fname);

    if(modified_files != commit_files)
        params  << QuotePaths(commit_files);

1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
	if(!ok)
		return;

	QFileInfo fi_after(new_name);

	if(fi_after.exists())
	{
		QMessageBox::critical(this, tr("Error"), tr("File ")+new_name+tr(" already exists.\nRename aborted."), QMessageBox::Ok );
		return;
	}

	// Do Rename
	runFossil(QStringList() << "mv" << QuotePath(fi_before.filePath()) << QuotePath(fi_after.filePath()) );

	QString wkdir = getCurrentWorkspace() + QDir::separator();







|







1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
	if(!ok)
		return;

	QFileInfo fi_after(new_name);

	if(fi_after.exists())
	{
		QMessageBox::critical(this, tr("Error"), tr("File %0 already exists.\nRename aborted.").arg(new_name), QMessageBox::Ok );
		return;
	}

	// Do Rename
	runFossil(QStringList() << "mv" << QuotePath(fi_before.filePath()) << QuotePath(fi_after.filePath()) );

	QString wkdir = getCurrentWorkspace() + QDir::separator();
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
	QMessageBox::about(this, "About Fuel...",
					   QCoreApplication::applicationName() + " "+ QCoreApplication::applicationVersion() + " " +
						tr("a GUI frontend to the Fossil SCM\n"
							"by Kostas Karanikolas\n"
							"Released under the GNU GPL\n\n")
					   + fossil_ver +
						tr("Icon-set by Deleket - Jojo Mendoza\n"
							"Available under the CC Attribution-Noncommercial-No Derivate 3.0 License"));
}

//------------------------------------------------------------------------------
void MainWindow::on_actionUpdate_triggered()
{
	QStringList res;








|







1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
	QMessageBox::about(this, "About Fuel...",
					   QCoreApplication::applicationName() + " "+ QCoreApplication::applicationVersion() + " " +
						tr("a GUI frontend to the Fossil SCM\n"
							"by Kostas Karanikolas\n"
							"Released under the GNU GPL\n\n")
					   + fossil_ver +
						tr("Icon-set by Deleket - Jojo Mendoza\n"
							"Available under the CC Attribution Noncommercial No Derivate 3.0 License"));
}

//------------------------------------------------------------------------------
void MainWindow::on_actionUpdate_triggered()
{
	QStringList res;

2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
		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());







|
|







2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
		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 '%0' to '%1'\n"
							  "The following files will be moved in the repository. Are you sure?").arg(old_path, new_path),
							  operations,
							  tr("Also move the workspace files"), &move_local)) {
		return;
	}

	// Rename files in fossil
	Q_ASSERT(files_to_move.length() == new_paths.length());
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
	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:







|







|













|





|







2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
	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 '%0' exists already").arg(new_file_path));
			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 '%0' to '%1'").arg(r->getFilePath(), 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 '%0' does not exist").arg(r->getFilePath()));
			goto _exit;
		}

		if(!QFile::remove(r->getFilePath()))
		{
			QMessageBox::critical(this, tr("Error"), tr("Cannot remove file '%0'").arg(r->getFilePath()));
			goto _exit;
		}
	}

	log(tr("Folder renamed completed. Don't forget to commit!\n"));

_exit: