void SludgeProjectManager::on_project_settings()
{
	gtk_entry_set_text(prefName, settings.windowName ? settings.windowName : "");
	gtk_entry_set_text(prefQuit, settings.quitMessage ? settings.quitMessage : "");
	gtk_entry_set_text(prefSave, settings.runtimeDataFolder ? settings.runtimeDataFolder : "");
	gtk_entry_set_text(prefLanguage, settings.originalLanguage ? settings.originalLanguage : "");
	gtk_entry_set_text(prefFilename, settings.finalFile ? settings.finalFile : "");
	gtk_entry_set_text(prefIcon, settings.customIcon ? settings.customIcon : "");
	gtk_entry_set_text(prefLogo, settings.customLogo ? settings.customLogo : "");
	gtk_spin_button_set_value(prefWidth, (double)settings.screenWidth);
	gtk_spin_button_set_value(prefHeight, (double)settings.screenHeight);
	gtk_spin_button_set_value(prefSpeed, (double)settings.frameSpeed);
	gtk_toggle_button_set_active(prefSilent, settings.forceSilent);

	if (gtk_dialog_run(projectSettingsDialog) == GTK_RESPONSE_OK)
	{
		killSettingsStrings();
		settings.quitMessage = copyString(gtk_entry_get_text(prefQuit));
		settings.customIcon = copyString(gtk_entry_get_text(prefIcon));
		settings.customLogo = copyString(gtk_entry_get_text(prefLogo));
		settings.runtimeDataFolder = copyString(gtk_entry_get_text(prefSave));
		settings.finalFile = copyString(gtk_entry_get_text(prefFilename));
		settings.windowName = copyString(gtk_entry_get_text(prefName));
		settings.originalLanguage = copyString(gtk_entry_get_text(prefLanguage));
		settings.screenHeight = gtk_spin_button_get_value_as_int(prefHeight);
		settings.screenWidth = gtk_spin_button_get_value_as_int(prefWidth);
		settings.frameSpeed = gtk_spin_button_get_value_as_int(prefSpeed);
		settings.forceSilent = gtk_toggle_button_get_active(prefSilent);
		setFileChanged();
	}
	gtk_widget_hide(GTK_WIDGET(projectSettingsDialog));
}
void SludgeProjectManager::on_remove_file_clicked()
{
	GList * selectedRows;
	GtkTreeIter iter;
	GtkTreePath *path;
	GtkTreeModel *model;
	gchar *indexStr;
	int index;

	if (! askAQuestion("Remove files?", "Do you want to remove the selected files from the project? (They will not be deleted from the disk.)")) {
		return;
	}

	selectedRows = gtk_tree_selection_get_selected_rows(filesSelection, &model);

	for (int j = g_list_length(selectedRows) - 1; j >= 0; j--)
	{
		path = gtk_tree_model_sort_convert_path_to_child_path(
					GTK_TREE_MODEL_SORT(model),
					(GtkTreePath *)g_list_nth(selectedRows, j)->data);

		indexStr = gtk_tree_path_to_string(path);
		index = atoi(indexStr);
        g_free(indexStr);

		removeFileFromList(index, fileList, &fileListNum);
		setFileChanged();

		gtk_tree_model_get_iter(GTK_TREE_MODEL(filesListStore), &iter, path);
		gtk_list_store_remove(filesListStore, &iter);
    }
	g_list_foreach(selectedRows, (GFunc) gtk_tree_path_free, NULL);
	g_list_free(selectedRows);
}
void SludgeZBufferMaker::on_spinbutton_value_changed(GtkSpinButton *theSpinButton)
{
	if (buffer() && bufferY() != backdrop.sprites[buffer()].special) {
		backdrop.sprites[buffer()].special = bufferY();
		setFileChanged();
	}
	render_timer_event(theDrawingarea);
}
void SludgeFloorMaker::button1Release(int local_pointx, int local_pointy)
{
		int xx, yy;

		awaitButton1Release = FALSE;

		selx2 = xx = (local_pointx+x)*zmul;
		sely2 = yy = (local_pointy-y)*zmul;

		lit = snapToClosest(&xx, &yy, getFloor());
		litX = xx; 
		litY = yy;
						
		if (lit && (xx != selx1 || yy != sely1)) {
			selx2 = xx;
			sely2 = yy;
		}
												
		selection = 0;

		switch (mode) {
			case 1: // Move vertices
				if (moveVertices(selx1, sely1, selx2, sely2, getFloor())) {
					setFileChanged();
				} else {
					errorBox("Can't move vertex", "Sorry - that vertex is already contained in one or more of the polygons you're changing.");
					return;
				}
			
				break;

			case 4: // Split lines
				splitLine(selx1, sely1, selx2, sely2, getFloor());
				setFileChanged();
				break;
			case 5: // Split segments
				struct polyList * firstPoly = getFloor();
				splitPoly(selx1, sely1, selx2, sely2, &firstPoly);
				setFloor(firstPoly);
				setFileChanged();
				break;
		}
}
void SludgeZBufferMaker::postNew()
{
	GtkWidget *dialog;

	dialog = gtk_file_chooser_dialog_new("Load file to zBuffer",
				      NULL,
				      GTK_FILE_CHOOSER_ACTION_OPEN,
				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
				      NULL);

	setFileChooserFilters(GTK_FILE_CHOOSER (dialog), FALSE, TRUE);

	if (currentFolder[0] != 0)
	{
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), currentFolder);
	}

	if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
	{
		char *filename;
		filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog));
		flipBackslashes(&filename);

		if (!loadZBufferFromTGA(filename, &backdrop))
		{
			errorBox("Error", "Loading TGA file failed.");
		} else {
			setFolderFromFilename(filename);
			setFilename(filename);
			int i, lastSlash;
			for (i = 0; filename[i] != 0; i++)
			{
				if (filename[i] == '/')
				lastSlash = i;
			}		
			currentShortname[i-lastSlash-4] = 'z';
			currentShortname[i-lastSlash-3] = 'b';
			currentShortname[i-lastSlash-2] = 'u';
			currentFilename[0] = 0;
			gtk_window_set_title(GTK_WINDOW(theWindow), getWindowTitle());
			setFileChanged();
			postOpen();
		}

		g_free(filename);
	}
	gtk_widget_destroy(dialog);

	setupButtons();
}
void SludgeProjectManager::on_add_file_clicked()
{
	GtkWidget *dialog;
	GtkFileFilter *filter, *slufilter, *sldfilter, *trafilter;

	dialog = gtk_file_chooser_dialog_new("Add file to SLUDGE project",
				      NULL,
				      GTK_FILE_CHOOSER_ACTION_OPEN,
				      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
				      GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
				      NULL);

	filter = gtk_file_filter_new();
	gtk_file_filter_set_name(filter, "SLU/SLD/TRA files");
	gtk_file_filter_add_pattern(filter, "*.[sS][lL][uU]");
	gtk_file_filter_add_pattern(filter, "*.[sS][lL][dD]");
	gtk_file_filter_add_pattern(filter, "*.[tT][rR][aA]");
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filter);

	slufilter = gtk_file_filter_new();
	gtk_file_filter_set_name(slufilter, "SLUDGE scripts (*.slu)");
	gtk_file_filter_add_pattern(slufilter, "*.[sS][lL][uU]");
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), slufilter);

	sldfilter = gtk_file_filter_new();
	gtk_file_filter_set_name(sldfilter, "SLUDGE constant definition files (*.sld)");
	gtk_file_filter_add_pattern(sldfilter, "*.[sS][lL][dD]");
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), sldfilter);

	trafilter = gtk_file_filter_new();
	gtk_file_filter_set_name(trafilter, "SLUDGE translation files (*.tra)");
	gtk_file_filter_add_pattern(trafilter, "*.[tT][rR][aA]");
	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), trafilter);

	gtk_file_chooser_set_filter(GTK_FILE_CHOOSER (dialog), filter);

	gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER (dialog), TRUE);

	if (currentFolder[0] != 0)
	{
		gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (dialog), currentFolder);
	}

	if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
	{
		GSList *filenames;
		char *filename;
		filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER (dialog));

		for (int j = 0; j < g_slist_length(filenames); j++) {
			filename = (char *) g_slist_nth(filenames, j)->data;
			flipBackslashes(&filename);

			getSourceDirFromName(currentFilename);
			addFileToProject(filename, sourceDirectory, fileList, &fileListNum);
			setFileChanged();
		
			g_free(filename);
		}
		g_slist_free(filenames);
	}
	gtk_widget_destroy(dialog);

	listChanged(FILE_TREEVIEW);
}
void SludgeFloorMaker::button1Press(int local_pointx, int local_pointy)
{
    	gboolean keepOn = TRUE;
		int i, xx, yy;

		mouseLoc1x = local_pointx;
		mouseLoc1y = local_pointy;

		xx = (local_pointx+x)*zmul;
		yy = (local_pointy-y)*zmul;
		
		switch (mode) {
		case 0: // Define floor border
			snapToClosest(&xx, &yy, getFloor());
			while (keepOn) {
				keepOn = FALSE;
				i = addVertex(xx, yy, getFloor());
				switch (i) {
					case 1:
						setFileChanged();
						return;
					case 0:
						errorBox("Can't add vertex", "Out of memory.");
						return;
						
					case 3:
						errorBox("Can't add vertex", "That vertex is already used in this polygon, but isn't the start point.");
						return;
						
					case 2:
						if ( askAQuestion("Can't add vertex", "Can't add another vertex as the floor is already complete... do you want to start a NEW polygon at this point?") ) { 
							setFloor( addPoly(getFloor()) );
							keepOn = TRUE;
							setFileChanged();
						} else {
							return;
						}
						break;
				}
			}
			break;
		case 1: // Move vertices
		case 4: // Split lines
		case 5: // Split segments
			if (! snapToClosest(&xx, &yy, getFloor()))
				return;
			
			selx1 = xx;
			sely1 = yy;
			selection = 1;
			awaitButton1Release = TRUE;
				
			break;
		case 2: // Remove vertices
			if (! snapToClosest(&xx, &yy, getFloor()))
				return;
			struct polyList * firstPoly = getFloor();
			
			killVertex(xx, yy, &firstPoly);
			setFloor(firstPoly);
			setFileChanged();
			break;
		}
		lit = snapToClosest(&xx, &yy, getFloor());
		litX = xx; litY = yy;
}