sciteproj-0.7.08/ 0000755 0001750 0001750 00000000000 12143703722 013161 5 ustar gusnan gusnan sciteproj-0.7.08/Makefile 0000644 0001750 0001750 00000005054 12143703722 014625 0 ustar gusnan gusnan CC=gcc
SRC=src
BIN=bin
GRPH=graphics
OBJ=obj
ifdef DEBUG
STD_CFLAGS=-Wall -g3 -ggdb -D_DEBUG
else
STD_CFLAGS=-Wall -Wformat -Wno-format-extra-args -Wformat-security -Wformat-nonliteral -Wformat=2 -Wdeprecated-declarations
endif
OBJECTS=$(OBJ)/about.o $(OBJ)/addfiles.o $(OBJ)/clipboard.o $(OBJ)/drag_drop.o\
$(OBJ)/file_utils.o $(OBJ)/filelist.o $(OBJ)/folder_to_xml.o $(OBJ)/graphics.o\
$(OBJ)/gui.o $(OBJ)/gui_callbacks.o $(OBJ)/main.o $(OBJ)/prefs.o\
$(OBJ)/properties_dialog.o $(OBJ)/recent_files.o $(OBJ)/remove.o\
$(OBJ)/rename.o $(OBJ)/scite_utils.o $(OBJ)/search.o $(OBJ)/statusbar.o\
$(OBJ)/string_utils.o $(OBJ)/tree_manipulation.o $(OBJ)/xml_processing.o
GRAPHICS_INCLUDES=$(GRPH)/dir-close.xpm \
$(GRPH)/dir-open.xpm \
$(GRPH)/text-x-cpp.xpm \
$(GRPH)/text-x-h.xpm \
$(GRPH)/text-x-txt.xpm \
$(GRPH)/text-x-java.xpm \
$(GRPH)/text-x-lua.xpm \
$(GRPH)/sciteproj.xpm
ifndef PREFIX
ifdef INSTALL_PREFIX
PREFIX=$(INSTALL_PREFIX)
else
PREFIX=/usr/local
endif
endif
NAME=sciteproj
PROG=${BIN}/${NAME}
DEPEND=Makefile.dep
DATADIR= ${DESTDIR}${PREFIX}/share
LOCALEDIR = ${DATADIR}/locale
VERSION=$(shell cat ./VERSION)
ifdef GTK2
PKG_GTK=gtk+-2.0
CHECK_GTK3=1
else
PKG_GTK=gtk+-3.0
endif
LIB_CFLAGS=`pkg-config --cflags $(PKG_GTK)`
STD_LDFLAGS=
LIBS+=`pkg-config --libs $(PKG_GTK) pkg-config --libs gthread-2.0` -lX11
LOCAL_CFLAGS=$(STD_CFLAGS) $(DEPRECATED) $(CFLAGS) $(LIB_CFLAGS)
LOCAL_LDFLAGS=$(LDFLAGS) $(STD_LDFLAGS)
LOCAL_CPPFLAGS=$(STD_CPPFLAGS) $(CPPFLAGS)
ifdef CHECK_GTK3
LOCAL_CFLAGS+=-DGTK_DISABLE_SINGLE_INCLUDES
LOCAL_CFLAGS+=-DGSEAL_ENABLE
CHECK_DEPRECATED=1
endif
ifdef CHECK_DEPRECATED
LOCAL_CFLAGS+=-DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED -DGTK_DISABLE_DEPRECATED
endif
LOCAL_CFLAGS+=-DLOCALEDIR=\"$(LOCALEDIR)\" -DPACKAGE=\"$(NAME)\" -DSCITEPROJ_VERSION=\"$(VERSION)\"
all: $(BIN)/$(NAME)
${MAKE} -C po all
$(OBJ)/%.o: $(SRC)/%.c
$(CC) $(LOCAL_CFLAGS) $(LOCAL_CPPFLAGS) -c $< -o $@
$(BIN)/$(NAME): $(OBJECTS)
$(CC) $(LOCAL_CFLAGS) $(LOCAL_LDFLAGS) $(OBJECTS) -o $(PROG) $(LIBS)
clean:
rm -rf $(OBJECTS) $(PROG) $(DEPEND)
${MAKE} -C po clean
install:
install -d $(DESTDIR)$(PREFIX)/bin
install -m 755 $(PROG) $(DESTDIR)$(PREFIX)/bin
install -d $(DESTDIR)$(PREFIX)/share/pixmaps
install -m 644 graphics/sciteproj.xpm $(DESTDIR)$(PREFIX)/share/pixmaps
${MAKE} -C po install
uninstall:
rm -f $(DESTDIR)$(PREFIX)/$(PROG)
rm -f $(DESTDIR)$(PREFIX)/share/pixmaps/sciteproj.xpm
${MAKE} -C po uninstall
$(DEPEND):
$(CC) -MM $(SRC)/*.c | sed -e "s/\([A-Za-z0-9+-0._&+-]*:\)/\$(OBJ)\/\1/g" > $(DEPEND)
-include $(DEPEND)
sciteproj-0.7.08/sciteproj.xml 0000644 0001750 0001750 00000004664 12143703722 015717 0 ustar gusnan gusnan
./src/about.c
./src/addfiles.c
./src/clipboard.c
./src/drag_drop.c
./src/filelist.c
./src/file_utils.c
./src/folder_to_xml.c
./src/graphics.c
./src/gui.c
./src/gui_callbacks.c
./src/main.c
./src/prefs.c
./src/properties_dialog.c
./src/recent_files.c
./src/remove.c
./src/rename.c
./src/scite_utils.c
./src/search.c
./src/statusbar.c
./src/string_utils.c
./src/tree_manipulation.c
./src/xml_processing.c
./src/about.h
./src/addfiles.h
./src/clicked_node.h
./src/clipboard.h
./src/drag_drop.h
./src/filelist.h
./src/file_utils.h
./src/folder_to_xml.h
./src/graphics.h
./src/gtk3_compat.h
./src/gui.h
./src/gui_callbacks.h
./src/menus.h
./src/prefs.h
./src/properties_dialog.h
./src/recent_files.h
./src/remove.h
./src/rename.h
./src/scite_utils.h
./src/search.h
./src/statusbar.h
./src/string_utils.h
./src/tree_manipulation.h
./src/xml_processing.h
./sciteproj.xml
./sciteproj.1
./Makefile
./VERSION
./po/Makefile
./po/sv_SE.po
./ChangeLog
./COPYING
./GPL3.txt
./INSTALL
./README
./README.translators
./sciteproj.desktop
./graphics/dir-close.xpm
./graphics/dir-open.xpm
./graphics/sciteproj.xpm
./graphics/text-x-cpp.xpm
./graphics/text-x-h.xpm
./graphics/text-x-txt.xpm
sciteproj-0.7.08/INSTALL 0000644 0001750 0001750 00000001701 12143703722 014211 0 ustar gusnan gusnan
Installation:
-------------
To build, first check that you have the packages required. The ones required
to build are:
pkg-config
libgtk-3-dev
gettext
or if you are still using GTK version 2:
pkg-config
libgtk2.0-dev
gettext
Then the build process is simple - to build the program, just type
make
or on GTK2, you need to pass
make GTK2=1
which will in the end create an executable in the bin folder. If you want to
build an executable with debug symbols enable, run
make DEBUG=1
To install the program run
make install
with super user priviliges, on a system using root:
su -c "make install"
or on a system using sudo, run
sudo make install
This will install the program in the system. This installs a desktop file too,
so now you should have an icon in the development part of your X menu.
This will default to /usr/local, installing the executable to /usr/local/bin.
This can be changed using PREFIX variable:
make install PREFIX=/usr
sciteproj-0.7.08/obj/ 0000755 0001750 0001750 00000000000 12143703722 013733 5 ustar gusnan gusnan sciteproj-0.7.08/obj/placeholder.txt 0000644 0001750 0001750 00000000000 12143703722 016744 0 ustar gusnan gusnan sciteproj-0.7.08/README.translators 0000644 0001750 0001750 00000003054 12143703722 016416 0 ustar gusnan gusnan
Information for new translators
-------------------------------
Starting fresh
--------------
Get a copy of the sciteproj sources, and create a sciteproj.pot file:
cd po
make sciteproj.pot
Generate a new po for your language with sciteproj.pot as input:
msginit --input=sciteproj.pot
This will read your environment, and init the translation meta information with
values based on that info. See msginit --help for more info.
Then start translating all strings in the po using your favourite texteditor,
or a "gettext catalogs (.po files) editor" like poedit (which can be found at
http://www.poedit.net.)
Note that hot-keys are illustrated with the "_" character, the character
following "_" is the keyboard shortcut for that menu item.
Checking your translation for errors and completeness
-----------------------------------------------------
msgfmt -c --statistics sv_SE.po -o /dev/null
Building SciteProj with your translation included
--------------------------------------------------
Edit the Makefile in the po folder to include your translation in the listing
under the LANGUAGES variable.
Then build sciteproj as usual with make and install using make install as root.
Updating your translation
-------------------------
When it is time to update your translation, get the latest git version of
sciteproj, and then do the following:
cd po
rm sciteproj.pot
make sciteproj.pot
Next issue the following command to update your po file:
msgmerge --update sv_SE.po sciteproj.pot
Then open your file and locate the strings that need updating.
sciteproj-0.7.08/sciteproj.1 0000644 0001750 0001750 00000005571 12143703722 015255 0 ustar gusnan gusnan .TH sciteproj 1 "12 May 2013" "Version 0.7.08"
.SH NAME
SciteProj - a Project Manager for the SciTE editor
.SH DESCRIPTION
.B SciteProj
is a Project Manager for the SciTE editor - It is used to group a bunch
of files into a project for easy access in SciTE giving the possibility
to group files in folders, and saves the project to disc in XML format.
It is based on the program ScitePM by Roy Wood. It uses the director
interface of SciTE to communicate between SciTE and SciteProj.
.SH OPTIONS
.IP "-s, --scite FILENAME"
Sets the filename for the instance of SciTE to open.
.IP "-v, --version"
Displays the version number of SciteProj
.IP "-g, --generate=XML_FILENAME"
Generate a sciteproj project file with the name FILENAME from the contents of
the current folder. This option will not consider adding hidden files to the
generated project.
.IP "-m, --max_depth=MAX_DEPTH"
Set maximum depth of folders to read through to MAX_DEPTH when generating
project file.
.IP "-h, --help"
Display a short help
.SH CONFIG FILE
The config file that SciteProj is using is named sciteprojrc, and is loaded from
the directory that the glib function g_get_user_config_dir is returning.
Normally this is ($HOME)/.config/ - If this file isn't found, sciteproj searches
for the file .sciteproj located in the users $HOME directory. It is loaded on
every program start. There is a menuitem in the program to open the file
directly in SciTE for editing.
If there isn't a .sciteproj in the user home when starting SciteProj,
one will be created filled with default values.
The following options are supported in the config file:
.IP "xpos, ypos, xsize and ysize"
Specifies the position and size of the program window on start
.IP "give_scite_focus"
Specifies wether SciTE shall get focus when opening a file from SciteProj (TRUE or FALSE)
.IP "dirty_on_folder_change"
Specifies wether SciteProj shall flag your project as dirty when you exapand or collapse a folder (TRUE or FALSE)
.IP allow_duplicates
Specifies wether several files with the same name should be allowed in one project (TRUE or FALSE)
.IP identify_sciteproj_xml
Specifies wether SciteProj shall try to recognize XML files saved by SciteProj (TRUE or FALSE)
.IP "search_xpos, search_ypos, search_width, search_height"
The position of the search dialog when opened. If any of these values are set to \-1, a default will be selected.
.IP search_match_case
Should the search dialog check the Search match case option by default
.IP search_match_whole_words
Should the checkbutton Match whole words be checked in the search dialog by defualt
.IP search_give_scite_focus
Should the SciTE window be focused when double-clicking a search result in the search dialog?
.IP search_file_alert_warning
If the project contains filename that doesn't exist on disk, should SciteProj give a warning during search?
.SH AUTHOR
.B SciteProj
was written by Andreas Rönnquist .
sciteproj-0.7.08/src/ 0000755 0001750 0001750 00000000000 12143703722 013750 5 ustar gusnan gusnan sciteproj-0.7.08/src/recent_files.c 0000644 0001750 0001750 00000040500 12143703722 016555 0 ustar gusnan gusnan /**
* recent_files.c - list of recently opened files
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include "recent_files.h"
#include "prefs.h"
#include "graphics.h"
#include "tree_manipulation.h"
#include "string_utils.h"
#include "clicked_node.h"
#include "file_utils.h"
#include "statusbar.h"
#include "scite_utils.h"
#include "clipboard.h"
#include "properties_dialog.h"
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_GUI_ERROR")
/**
*
*/
GtkCellRenderer *recentPixbuffCellRenderer = NULL;
GtkWidget *recentTreeView=NULL;
GtkTreeStore *recentTreeStore = NULL;
ClickedNode recent_clicked_node;
GtkWidget *recentPopupMenu=NULL;
/**
* forward declarations
*/
static gboolean recent_mouse_button_pressed_cb(GtkWidget *treeView, GdkEventButton *event, gpointer userData);
static void recent_tree_row_activated_cb(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, gpointer userData);
/**
* Get the GTKTreeStore (evil, but necessary for setup_gui).
*
* @return the GtkTreeStore* for the project or NULL if a GtkTreeStore could not be allocate
*
* @param err returns any error information
*/
GtkTreeStore* create_treestore_recent(GError **err)
{
GtkTreeStore *result=NULL;
result= gtk_tree_store_new(COLUMN_EOL, TYPE_ITEMTYPE, TYPE_FILEPATH, TYPE_FILENAME, TYPE_FILESIZE, TYPE_FONTWEIGHT, TYPE_FONTWEIGHTSET, TYPE_ICON, TYPE_EXPANDED);
if (result == NULL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_tree_store_new() = NULL",
__func__,
"Couldn't init treestore"
);
}
return result;
}
/**
*
*/
GtkWidget *init_recent_files(GError **err)
{
GtkCellRenderer *recentCellRenderer = NULL;
GtkTreeViewColumn *recentColumn1 = NULL;
GtkWidget *recentScrolledWindow = NULL;
GError *tempErr=NULL;
// add a scrolledwindow for recent files
if (!(recentScrolledWindow=gtk_scrolled_window_new(NULL,NULL))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_scrolled_window_new() = NULL",
__func__,
"Couldn't init recent scrolled window"
);
goto EXITPOINT;
}
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(recentScrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
if ((recentTreeStore=create_treestore_recent(&tempErr))==NULL) {
if (tempErr) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1 ,
"%s: %s",
tempErr->message,
"Coudn't init recent treestore"
);
}
goto EXITPOINT;
}
if (!(recentTreeView=gtk_tree_view_new_with_model(GTK_TREE_MODEL(recentTreeStore)))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_tree_view_new_with_model() = NULL",
__func__,
"Couldn't init recent gtk_tree_view"
);
goto EXITPOINT;
}
gtk_widget_show(recentScrolledWindow);
gtk_container_add(GTK_CONTAINER(recentScrolledWindow), recentTreeView);
if (!(recentCellRenderer = gtk_cell_renderer_text_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_cell_renderer_text_new() = NULL",
__func__,
"Couldn't init recent gtk_cell_renderer"
);
goto EXITPOINT;
}
if (!(recentColumn1 = gtk_tree_view_column_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_tree_view_column_new() = NULL",
__func__,
"Couldn't init recent gtk_tree_view_column"
);
goto EXITPOINT;
}
g_object_set(recentColumn1,"title",_("Recently opened files:"),NULL);
if (!(recentPixbuffCellRenderer = gtk_cell_renderer_pixbuf_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_cell_renderer_pixbuf_new() = NULL",
__func__,
"Couldn't init recent gtk_cell_renderer_pixbuf"
);
goto EXITPOINT;
}
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(recentTreeView), TRUE);
gtk_tree_view_column_set_resizable(recentColumn1, TRUE);
gtk_tree_view_column_set_min_width(recentColumn1, (int)(gPrefs.width*.75));
gtk_tree_view_column_pack_start(recentColumn1, recentPixbuffCellRenderer , FALSE);
gtk_tree_view_column_add_attribute(recentColumn1, recentPixbuffCellRenderer , "pixbuf", COLUMN_ICON);
gtk_tree_view_column_pack_start(recentColumn1, recentCellRenderer, TRUE);
gtk_tree_view_column_add_attribute(recentColumn1, recentCellRenderer, "text", COLUMN_FILENAME);
gtk_tree_view_column_add_attribute(recentColumn1, recentCellRenderer, "weight", COLUMN_FONTWEIGHT);
gtk_tree_view_column_add_attribute(recentColumn1, recentCellRenderer, "weight-set", COLUMN_FONTWEIGHTSET);
g_signal_connect(G_OBJECT(recentTreeView), "button-press-event", G_CALLBACK(recent_mouse_button_pressed_cb), recentTreeView);
g_signal_connect(G_OBJECT(recentTreeView), "row-activated", G_CALLBACK(recent_tree_row_activated_cb), NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(recentTreeView), recentColumn1);
gtk_widget_show(recentTreeView);
EXITPOINT:
return recentScrolledWindow;
}
/**
* GtkTreeModelForeachFunc
*/
gboolean tree_for_each(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data)
{
gchar *filepath,*filename;
gchar *inFile=(gchar*)(data);
gtk_tree_model_get(model, iter, COLUMN_FILEPATH, &filename, -1);
filepath= get_filename_from_full_path((gchar*)filename);
if (g_strcmp0(filepath,inFile)==0) {
//savedIter=iter;
gtk_tree_store_remove(recentTreeStore,iter);
return TRUE;
}
return FALSE;
}
/**
*
*/
void remove_if_already_exists(const gchar *filepath)
{
gtk_tree_model_foreach(gtk_tree_view_get_model(GTK_TREE_VIEW(recentTreeView)),tree_for_each,(gpointer)(filepath));
}
/**
* add_file
* @returns TRUE if added the file successfully, FALSE otherwise
*/
gboolean add_file_to_recent(gchar *filepath,GError **err)
{
g_assert(recentTreeStore != NULL);
g_assert(filepath != NULL);
//g_assert(position == ADD_BEFORE || position == ADD_AFTER || position == ADD_CHILD);
gboolean finalResult = FALSE;
GtkTreeIter iter;
const gchar* fileName = NULL;
gchar *relFilename = NULL;
gchar *fileExt=NULL;
relFilename = NULL; //g_strdup(filepath);
/*
if (!makeRelative) {
relFilename = g_strdup(filepath);
}
else
*/
if (!abs_path_to_relative_path(filepath, &relFilename, get_project_directory(), err)) {
printf("--- abs_path_to_relative_path FAILED!\n");
goto EXITPOINT;
}
// Extract filename from filepath
fileName = get_filename_from_full_path((gchar*)filepath);
remove_if_already_exists(fileName);
// Append to root, or before/after/within an existing node?
//if (currentIter == NULL) {
if (!gPrefs.recent_add_to_bottom) {
gtk_tree_store_insert_after(recentTreeStore, &iter, NULL, NULL);
} else {
// get the iter of the last item
gtk_tree_store_append(recentTreeStore,&iter,NULL);
}
//}
/*
else if (position == ADD_BEFORE) {
gtk_tree_store_insert_before(recentTreeStore, &iter, NULL, currentIter);
}
else if (position == ADD_AFTER) {
gtk_tree_store_insert_after(recentTreeStore, &iter, NULL, currentIter);
}
else if (position == ADD_CHILD) {
gtk_tree_store_insert(recentTreeStore,&iter,currentIter,1000);
}
*/
fileExt=strrchr(fileName,'.');
if (fileExt!=NULL) {
++fileExt;
}
if (fileExt == NULL || strlen(fileExt) <= 0) {
fileExt=(gchar*)fileName;
}
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_ITEMTYPE, ITEMTYPE_FILE, -1);
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_FILEPATH, relFilename, -1);
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_FILENAME, fileName, -1);
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_EXPANDED, FALSE, -1);
if (
(strcmp(fileExt,"cc")==0) ||
(strcmp(fileExt,"c++")==0) ||
(strcmp(fileExt,"c")==0) ||
(strcmp(fileExt,"cpp")==0)
) {
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_ICON, cpp_file_pixbuf, -1);
} else if (
(strcmp(fileExt,"hh")==0) ||
(strcmp(fileExt,"h++")==0) ||
(strcmp(fileExt,"h")==0) ||
(strcmp(fileExt,"hpp")==0)
) {
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_ICON, header_file_pixbuf, -1);
} else {
gtk_tree_store_set(recentTreeStore, &iter, COLUMN_ICON, txt_file_pixbuf, -1);
}
GtkTreePath *path;
if (!gPrefs.recent_add_to_bottom) {
path=gtk_tree_path_new_from_string("0");
gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(recentTreeView),path,NULL,NULL,FALSE);
} else {
GtkTreeModel *treeModel = gtk_tree_view_get_model(GTK_TREE_VIEW(recentTreeView));
path=gtk_tree_model_get_path(treeModel,&iter);
gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(recentTreeView),path,NULL,NULL,FALSE);
}
finalResult = TRUE;
EXITPOINT:
if (relFilename) g_free(relFilename);
return finalResult;
}
/**
* Respond to a Gtk "button-press-event" message.
*
* @param treeView is the GTKTreeView widget in which the mouse-button event occurred
* @param event is the GdkEventButton event object
* @param userData is not currently used
*/
static gboolean recent_mouse_button_pressed_cb(GtkWidget *treeView, GdkEventButton *event, gpointer userData)
{
gboolean eventHandled = FALSE;
GtkTreePath *path = NULL;
GtkTreeModel *treeModel = NULL;
gchar *nodeName = NULL;
gint nodeItemType;
GtkTreeIter iter;
GtkTreeSelection *tree_selection=NULL;
g_assert(treeView != NULL);
g_assert(event != NULL);
// Until we know for sure, assume that the user has not clicked on a node
recent_clicked_node.valid=FALSE;
// If it is not a right-click, then ignore it
if (event->type != GDK_BUTTON_PRESS || event->button != 3) {
goto EXITPOINT;
}
// Find if the user has clicked on a node
if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeView), (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL)) {
// Nope-- user clicked in the GtkTreeView, but not on a node
//gtk_menu_popup(GTK_MENU(sGeneralPopupMenu), NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent*) event));
goto EXITPOINT;
}
// User clicked on a node, so retrieve the particulars
treeModel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
if (!gtk_tree_model_get_iter(treeModel, &iter, path)) {
goto EXITPOINT;
}
gtk_tree_model_get(treeModel, &iter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &nodeName, -1);
// Save the node info for use by the popup menu callbacks
if (recent_clicked_node.name) g_free(recent_clicked_node.name);
recent_clicked_node.name=NULL;
recent_clicked_node.valid=TRUE;
recent_clicked_node.iter=iter;
recent_clicked_node.type=nodeItemType;
recent_clicked_node.name=nodeName;
nodeName = NULL;
// Check if something is selected
tree_selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
if (tree_selection!=NULL) {
// Check if clicked on something in the selection, otherwise make the clicked one the selection.
if (gtk_tree_selection_path_is_selected(tree_selection,path)==FALSE) {
// clear selection and make current line selected
gtk_tree_selection_unselect_all(tree_selection);
gtk_tree_selection_select_path (tree_selection,path);
}
}
// Pop up the appropriate menu for the node type
//if (nodeItemType == ITEMTYPE_FILE) {
gtk_menu_popup(GTK_MENU(recentPopupMenu), NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent*) event));
/*
}
else if (nodeItemType == ITEMTYPE_GROUP) {
gtk_menu_popup(GTK_MENU(sGroupPopupMenu), NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent*) event));
}
*/
// We took care of the event, so no need to propogate it
eventHandled = TRUE;
EXITPOINT:
if (path) gtk_tree_path_free(path);
if (nodeName) g_free(nodeName);
return eventHandled;
}
/**
* Open the selected file.
* This is called when a file is rightclicked and open is selected in the menu
*/
void popup_open_recent_file_cb()
{
gchar *command = NULL;
GError *err = NULL;
GtkWidget *dialog = NULL;
gchar *absFilePath = NULL;
// We can only open files
if (!recent_clicked_node.valid || recent_clicked_node.type != ITEMTYPE_FILE) {
goto EXITPOINT;
}
//debug_printf("name:%s\n",recent_clicked_node.name);
if (!open_filename(recent_clicked_node.name,(gchar*)get_project_directory(),&err)) {
goto EXITPOINT;
}
EXITPOINT:
if (err != NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Could not open selected file: \n\n%s", err->message);
gtk_dialog_run(GTK_DIALOG (dialog));
}
if (command) g_free(command);
if (absFilePath) g_free(absFilePath);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
* Callback handler for Gtk "row-activated" event.
*
* @param treeView is the GtkTreeView
* @param path is the GtkTreePath of the activated row
* @param column is not used
* @param userData is not used
*/
static void recent_tree_row_activated_cb(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, gpointer userData)
{
GtkTreeModel *treeModel = NULL;
GtkTreeIter iter;
gchar *relFilePath = NULL;
gchar *absFilePath = NULL;
gchar *command = NULL;
GError *err = NULL;
GtkWidget *dialog = NULL;
gint nodeItemType;
gchar *fixed=NULL;
// Get the data from the row that was activated
treeModel = gtk_tree_view_get_model(treeView);
gtk_tree_model_get_iter(treeModel, &iter, path);
gtk_tree_model_get(treeModel, &iter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &relFilePath, -1);
absFilePath=fix_path((gchar*)get_project_directory(),relFilePath);
fixed=fix_path((gchar*)get_project_directory(),relFilePath);
if ((command = g_strdup_printf("open:%s\n", fixed)) == NULL) {
g_set_error(&err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, g_strdup_printf() = NULL",
__func__,
"Error formatting SciTE command"
);
}
else {
if (send_scite_command(command, &err)) {
// Try to activate SciTE; ignore errors
activate_scite(NULL);
if (gPrefs.give_scite_focus==TRUE) {
send_scite_command((gchar*)"focus:0",NULL);
}
add_file_to_recent(fixed,NULL);
gchar *statusbar_text=NULL;
statusbar_text=g_strdup_printf(_("Opened %s"),remove_newline(get_filename_from_full_path(command)));
set_statusbar_text(statusbar_text);
g_free(statusbar_text);
}
}
//EXITPOINT:
if (err != NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
_("Could not open selected file: \n\n%s"),
err->message
);
gtk_dialog_run(GTK_DIALOG (dialog));
}
if (relFilePath) g_free(relFilePath);
if (absFilePath) g_free(absFilePath);
if (command) g_free(command);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
if (fixed) g_free(fixed);
}
/**
*
*/
void popup_remove_recent_file_cb()
{
gchar *command = NULL;
GError *err = NULL;
GtkWidget *dialog = NULL;
gchar *absFilePath = NULL;
gchar *fileName=NULL;
// There are only files in this list
if (!recent_clicked_node.valid || recent_clicked_node.type != ITEMTYPE_FILE) {
goto EXITPOINT;
}
fileName = get_filename_from_full_path((gchar*)recent_clicked_node.name);
remove_if_already_exists(fileName);
EXITPOINT:
if (err != NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
_("Could not open selected file: \n\n%s"),
err->message
);
gtk_dialog_run(GTK_DIALOG (dialog));
}
if (command) g_free(command);
if (absFilePath) g_free(absFilePath);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
* Callback for the menu item
*/
void copy_recent_filename_to_clipboard_cb()
{
if (!recent_clicked_node.valid || recent_clicked_node.type != ITEMTYPE_FILE) {
//goto EXITPOINT;
} else {
copy_filename_to_clipboard(gtk_tree_view_get_model(GTK_TREE_VIEW(recentTreeView)),&(recent_clicked_node.iter));
}
}
/**
*
*/
void properties_recent_file_cb()
{
if (!recent_clicked_node.valid || recent_clicked_node.type != ITEMTYPE_FILE) {
//goto EXITPOINT;
} else {
file_properties_gui(gtk_tree_view_get_model(GTK_TREE_VIEW(recentTreeView)),&(recent_clicked_node.iter));
}
}
sciteproj-0.7.08/src/search.h 0000644 0001750 0001750 00000001672 12143703722 015374 0 ustar gusnan gusnan /**
* search.h - Search dialog for searching SciteProj project
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*/
#ifndef __HEADER_SEARCH_DIALOG_
#define __HEADER_SEARCH_DIALOG_
/**
*
*/
void search_dialog();
void search_dialog_cb();
#endif /*__HEADER_SEARCH_DIALOG_*/
sciteproj-0.7.08/src/remove.c 0000644 0001750 0001750 00000011703 12143703722 015413 0 ustar gusnan gusnan /**
* remove.c - code for removing nodes
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*/
#include
#include
#include
#include
#include "clicked_node.h"
#include "gui.h"
#include "tree_manipulation.h"
#include "remove.h"
/**
* Actually remove selected nodes
*/
void remove_selected_items ( GtkTreeView *treeview )
{
GtkTreeSelection *selection = gtk_tree_view_get_selection ( treeview );
GtkTreeModel *model;
GtkTreeIter iter;
//GtkTreeStore *store;
GError *error=NULL;
if (gtk_tree_selection_count_selected_rows(selection) == 0)
return;
model=gtk_tree_view_get_model(treeview);
GList *list = gtk_tree_selection_get_selected_rows( selection, &model );
int nRemoved = 0;
// Begin at the end and go to the start
list=g_list_last(list);
while(list) {
GString *fixed_path = g_string_new("");
g_string_printf(fixed_path, "%s", gtk_tree_path_to_string((GtkTreePath*)list->data)/*ipath*/);
GtkTreePath *path = gtk_tree_path_new_from_string(fixed_path->str);
g_string_free(fixed_path, TRUE);
if (path) {
if ( gtk_tree_model_get_iter ( model, &iter, path) ) { // get iter from specified path
remove_tree_node(&iter,&error);
nRemoved++;
}
else { // invalid path
g_error(_("Error!!!\n"));
}
gtk_tree_path_free (path);
}
else {
g_error(_("Error!!!\n"));
}
list=list->prev;
}
g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
g_list_free (list);
}
/**
*
*/
void do_remove_node(gboolean ignore_clicked_node)
{
GError *err = NULL;
GtkWidget *dialog = NULL;
gint dialogResponse;
gchar *nodename = NULL;
gint selected_rows=0;
gboolean multiple_selected=FALSE;
// Make sure a node has been selected
if (!ignore_clicked_node) {
if (!clicked_node.valid) {
goto EXITPOINT;
}
}
GtkTreeSelection *treeSelect;
treeSelect=gtk_tree_view_get_selection(GTK_TREE_VIEW(projectTreeView));
selected_rows=gtk_tree_selection_count_selected_rows(treeSelect);
if (selected_rows>1) {
multiple_selected=TRUE;
}
if (!ignore_clicked_node) {
// Figure out the node name
nodename = strrchr(clicked_node.name, '/');
if (nodename != NULL) {
++nodename;
}
else {
nodename = clicked_node.name;
}
} else {
// if there is only one selected, get its name
nodename=NULL;
multiple_selected=TRUE;
}
// Confirm removal from project
if (multiple_selected==TRUE) {
dialog=gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, _("Remove all selected items?") /*, nodename*/);
dialogResponse = gtk_dialog_run(GTK_DIALOG (dialog));
if (dialog_response_is_exit(dialogResponse)) {
goto EXITPOINT;
}
// remove them!
remove_selected_items(GTK_TREE_VIEW(projectTreeView));
} else {
if (clicked_node.type == ITEMTYPE_FILE) {
if (nodename!=NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, _("Remove file '%s' from project?"), nodename);
} else {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, _("Remove file from project?"));
}
}
else {
if (nodename!=NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, _("Remove group '%s' and any contained files from project?"), nodename);
} else {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, _("Remove group and any contained files from project?"));
}
}
dialogResponse = gtk_dialog_run(GTK_DIALOG (dialog));
if (dialog_response_is_exit(dialogResponse)) {
goto EXITPOINT;
}
// Remove the node
if (!remove_tree_node(&(clicked_node.iter), &err)) {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Could not remove the selected node: \n\n%s"), err->message);
gtk_dialog_run(GTK_DIALOG (errDialog));
gtk_widget_destroy(errDialog);
}
}
EXITPOINT:
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
* Remove the selected file/group.
*/
void popup_remove_node_cb()
{
do_remove_node(FALSE);
}
/**
* Callback for Remove Item(s) menu item
*/
void removeitem_menu_cb()
{
do_remove_node(TRUE);
}
sciteproj-0.7.08/src/properties_dialog.c 0000644 0001750 0001750 00000020406 12143703722 017631 0 ustar gusnan gusnan /**
* properties_dialog.c - Properties Dialogs code for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include "properties_dialog.h"
#include "tree_manipulation.h"
#include "clicked_node.h"
#include "gui.h"
#include "string_utils.h"
/**
*
*/
static int counter_step_through(GtkTreeModel *tree_model,int how_many_to_check,int *counter,GtkTreeIter newiter)
{
gchar *relFilePath;
gint nodeItemType;
GtkTreeIter iter=newiter;
int foldercounter=0;
int result=0;
do {
gtk_tree_model_get(tree_model, &iter, COLUMN_ITEMTYPE, &nodeItemType, -1);
if (nodeItemType==ITEMTYPE_GROUP) {
(*counter)++;
result++;
if (gtk_tree_model_iter_has_child(tree_model,&iter)) {
GtkTreeIter newIter=iter;
int num=gtk_tree_model_iter_n_children(tree_model,&newiter);
if (num!=0) {
gtk_tree_model_iter_children(tree_model,&newIter,&iter);
result+=counter_step_through(tree_model,num,counter,newIter);
}
}
foldercounter++;
} else {
gtk_tree_model_get(tree_model, &iter, COLUMN_FILEPATH, &relFilePath, -1);
(*counter)++;
result++;
foldercounter++;
}
} while((gtk_tree_model_iter_next(tree_model,&iter)) && (foldercounter=3
table=gtk_grid_new();
gtk_grid_attach(GTK_GRID(table),label1,0,0,1,1);
gtk_grid_attach(GTK_GRID(table),label2,0,1,1,1);
gtk_grid_attach(GTK_GRID(table),filename,1,0,4,1);
gtk_grid_attach(GTK_GRID(table),number_of_files_label,1,1,4,1);
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
#else
table=gtk_table_new(3,2,FALSE);
gtk_table_attach_defaults(GTK_TABLE(table),label1,0,1,0,1);
gtk_table_attach_defaults(GTK_TABLE(table),label2,0,1,1,2);
gtk_table_attach_defaults(GTK_TABLE(table),filename,1,2,0,1);
gtk_table_attach_defaults(GTK_TABLE(table),number_of_files_label,1,2,1,2);
gtk_table_set_row_spacings(GTK_TABLE(table),5);
gtk_table_set_col_spacings(GTK_TABLE(table),5);
gtk_container_set_border_width(GTK_CONTAINER(table),5);
#endif
GtkWidget *container_vbox=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
gtk_box_pack_start(GTK_BOX(container_vbox),table,TRUE,TRUE,0);
gtk_widget_show_all(dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
//EXITPOINT:
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
* File properties callback
*/
void file_properties_gui(GtkTreeModel *model,GtkTreeIter *iter)
{
GError *err = NULL;
GtkWidget *dialog = NULL;
gchar *nodename = NULL;
GtkWidget *table;
GtkWidget *label1,*label2,*label3;
GtkWidget *path,*filename,*filesize_label;
GtkWidget *container_vbox=NULL;
gchar *filePath=NULL;
int nodeType=-1;
gtk_tree_model_get(model, iter, COLUMN_FILENAME, &nodename ,COLUMN_ITEMTYPE, &nodeType, COLUMN_FILEPATH, &filePath, -1);
debug_printf((gchar*)"Node name: %s\n",nodename);
debug_printf((gchar*)"File name: %s\n",filePath);
dialog=gtk_dialog_new_with_buttons(_("File Properties"),NULL,GTK_DIALOG_MODAL,GTK_STOCK_OK,GTK_RESPONSE_OK,NULL);
gtk_dialog_set_default_response(GTK_DIALOG(dialog),GTK_RESPONSE_OK);
gchar *absFilePath = NULL; //g_strdup_printf("%s",filePath);
// filePath is NULL?
//if (!relative_path_to_abs_path(sClickedNodeName, &absFilePath, get_project_directory(), &err)) {
if (!relative_path_to_abs_path(filePath, &absFilePath, get_project_directory(), &err)) {
goto EXITPOINT;
}
gchar *size_string;
// get the size of the file
struct stat file_status;
if(stat(absFilePath, &file_status) != 0) {
perror("could not stat");
//goto EXITPOINT;
}
size_string=g_strdup_printf("%d bytes",(int)(file_status.st_size));
label1=gtk_label_new(_("Filename:"));
label2=gtk_label_new(_("Path:"));
label3=gtk_label_new(_("File size:"));
filename=gtk_label_new(nodename);
path=gtk_label_new(absFilePath/*sClickedNodeName*/);
filesize_label=gtk_label_new(size_string);
gtk_misc_set_alignment(GTK_MISC(filename),0,0);
gtk_misc_set_alignment(GTK_MISC(path),0,0);
gtk_misc_set_alignment(GTK_MISC(filesize_label),0,0);
gtk_misc_set_alignment(GTK_MISC(label1),0,0);
gtk_misc_set_alignment(GTK_MISC(label2),0,0);
gtk_misc_set_alignment(GTK_MISC(label3),0,0);
#if GTK_MAJOR_VERSION>=3
table=gtk_grid_new();
gtk_grid_attach(GTK_GRID(table),label1,0,0,1,1);
gtk_grid_attach(GTK_GRID(table),label2,0,1,1,1);
gtk_grid_attach(GTK_GRID(table),label3,0,2,1,1);
gtk_grid_attach(GTK_GRID(table),filename,1,0,4,1);
gtk_grid_attach(GTK_GRID(table),path,1,1,4,1);
gtk_grid_attach(GTK_GRID(table),filesize_label,1,2,4,1);
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
gtk_grid_set_column_spacing (GTK_GRID (table), 6);
#else
table=gtk_table_new(3,2,FALSE);
gtk_table_attach_defaults(GTK_TABLE(table),label1,0,1,0,1);
gtk_table_attach_defaults(GTK_TABLE(table),label2,0,1,1,2);
gtk_table_attach_defaults(GTK_TABLE(table),label3,0,1,2,3);
gtk_table_attach_defaults(GTK_TABLE(table),filename,1,2,0,1);
gtk_table_attach_defaults(GTK_TABLE(table),path,1,2,1,2);
gtk_table_attach_defaults(GTK_TABLE(table),filesize_label,1,2,2,3);
gtk_table_set_row_spacings(GTK_TABLE(table),5);
gtk_table_set_col_spacings(GTK_TABLE(table),5);
gtk_container_set_border_width(GTK_CONTAINER(table),5);
#endif
container_vbox=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
gtk_box_pack_start(GTK_BOX(container_vbox),table,TRUE,TRUE,0);
gtk_widget_show_all(dialog);
gtk_dialog_run(GTK_DIALOG(dialog));
EXITPOINT:
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
*
*/
void group_properties_cb()
{
if (!clicked_node.valid || clicked_node.type != ITEMTYPE_GROUP) {
//goto EXITPOINT;
} else {
group_properties_gui(gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView)),&(clicked_node.iter));
}
}
/**
*
*/
void file_properties_cb()
{
if (!clicked_node.valid || clicked_node.type != ITEMTYPE_FILE) {
//goto EXITPOINT;
} else {
file_properties_gui(gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView)),&(clicked_node.iter));
}
}
sciteproj-0.7.08/src/statusbar.c 0000644 0001750 0001750 00000005446 12143703722 016135 0 ustar gusnan gusnan /**
* statusbar.c - statusbar for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include "statusbar.h"
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_GUI_ERROR")
GtkWidget *statusbar=NULL;
guint context_id;
/**
* init_statusbar
*/
gboolean init_statusbar(GtkWidget *widget,GtkWidget *next_to,GError **err)
{
statusbar=gtk_statusbar_new();
if (!statusbar) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not init statusbar", __func__);
return FALSE;
}
// gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(statusbar),TRUE);
gtk_widget_set_size_request(statusbar, 1, -1);
context_id=gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar),"Info");
set_statusbar_text(_("Welcome to SciteProj\n"));
gtk_widget_set_size_request(statusbar, -1, 20);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(widget),statusbar,next_to,GTK_POS_BOTTOM,1,1);
#else
gtk_box_pack_end (GTK_BOX (widget), statusbar,FALSE, FALSE, 0);
#endif
gtk_widget_show (statusbar);
return TRUE;
}
/**
* set_statusbar_text
*/
void set_statusbar_text(const gchar *text)
{
if (statusbar) {
int co=0;
// new string - fill it with characters from text indata, but skip
// non-showable characters.
gchar *newstring=(gchar*)(g_malloc((int)(strlen(text)+1)));
int newco=0;
for (co=0;co<(int)strlen(text);co++) {
if (text[co]!='\n') {
newstring[newco]=text[co];
newco++;
}
}
newstring[newco]='\0';
// Pop what message that was previously on the statusbar stack
gtk_statusbar_pop(GTK_STATUSBAR(statusbar),context_id);
// Push the new message (the statusbar will show the message that
// is on top of the statusbar stack, the one pushed will be shown)
// We popped the last one, because we don't take advantage of the
// context_id system of the statusbar.
gtk_statusbar_push(GTK_STATUSBAR(statusbar),context_id,newstring);
g_free(newstring);
}
}
/**
* done_statusbar
*/
void done_statusbar()
{
if (statusbar!=NULL) gtk_widget_destroy(statusbar);
}
sciteproj-0.7.08/src/string_utils.c 0000644 0001750 0001750 00000021617 12143703722 016651 0 ustar gusnan gusnan /**
* string_utils.c - misc string utils for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include "string_utils.h"
#include "file_utils.h"
#include
#include
#include
#include
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_STRINGUTILS_ERROR")
void debug_printf(const char *st, ...);
/**
* Convert an absolute file path to a relative file path.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param absPath is the absolute file path
* @param relativePath returns the relative file path (must be later freed with g_free() )
* @param basePath is the base file path against which the relative path is determined; pass NULL if the current working directory should be used as the base path
* @param err returns any errors
*/
gboolean abs_path_to_relative_path(const gchar *absPath, gchar **relativePath, const gchar *basePath, GError **err)
{
g_assert(absPath != NULL);
g_assert(relativePath != NULL);
gboolean finalResult = FALSE;
gchar *localBasePath = NULL;
char *workingDir = NULL;
int localBasePathLength = 0;
int absPathLength = strlen(absPath);
int i = 0;
int dirSlashOffset = 0;
if (!g_path_is_absolute(absPath)) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Specified path, '%s', is not absolute", __func__ , absPath);
goto EXITPOINT;
}
// If no basepath specified, use current working dir
if (!basePath) {
workingDir = getcwd(NULL, 0);
if (!workingDir) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not determine current working directory, getcwd() = NULL, errno = %d", __func__ , errno);
goto EXITPOINT;
}
basePath = workingDir;
}
// Set up a local copy of the base path, and ensure it ends with a '/'
if (!str_append(&localBasePath, basePath, err)) {
goto EXITPOINT;
}
localBasePathLength = strlen(localBasePath);
if (localBasePathLength <= 0 || localBasePath[localBasePathLength - 1] != G_DIR_SEPARATOR) {
if (!str_append(&localBasePath, G_DIR_SEPARATOR_S, err)) {
goto EXITPOINT;
}
++localBasePathLength;
}
// Start relative path with local dir
if (!str_append(relativePath, "./", err)) {
goto EXITPOINT;
}
// Skip over matching parent dirs
while (i < localBasePathLength && i < absPathLength && localBasePath[i] == absPath[i]) {
if (absPath[i] == G_DIR_SEPARATOR) {
dirSlashOffset = i + 1;
}
++i;
}
// Step up one dir for every dir in the leftover part of the base path
for (i = dirSlashOffset; i < localBasePathLength; ++i) {
if (localBasePath[i] == G_DIR_SEPARATOR) {
if (!str_append(relativePath, "../", err)) {
goto EXITPOINT;
}
}
}
// Finally, add the leftover part of the absolute path
if (!str_append(relativePath, absPath + dirSlashOffset, err)) {
goto EXITPOINT;
}
finalResult = TRUE;
EXITPOINT:
free(workingDir);
if (localBasePath) g_free(localBasePath);
return finalResult;
}
/**
* Convert a relative file path to an absolute file path.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param relativePath is the relative file path
* @param absPath returns the absolute file path (must be later freed with g_free() )
* @param basePath is the base file path used to formulate the absolute path; pass NULL if the current working directory should be used as the base path
* @param err returns any errors
*/
gboolean relative_path_to_abs_path(gchar *relativePath, gchar **absPath, const gchar *basePath, GError **err)
{
g_assert(absPath != NULL);
g_assert(relativePath != NULL);
int i=0;
gboolean finalResult = FALSE;
char *workingDir = NULL;
gchar *localAbsPath = NULL;
int absPathLength;
int co;
for (co=0;co 0) ? i - 1 : 0;
} while (i > 0 && !is_separator(localAbsPath[i])/* != G_DIR_SEPARATOR*/);
}
if (tail != NULL) {
g_memmove(localAbsPath + i, tail, tailLength);
absPathLength -= (tail - localAbsPath - i);
}
else {
++i;
}
}
*absPath = localAbsPath;
localAbsPath = NULL;
finalResult = TRUE;
EXITPOINT:
if (workingDir) free(workingDir);
if (localAbsPath) g_free(localAbsPath);
return finalResult;
}
/**
* Append a string to an existing string, expanding the allocation of the string.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param dst is the string to append onto
* @param src is the string to append to dst
* @param err returns any errors
*/
gboolean str_append(gchar **dst, const gchar *src, GError **err)
{
gboolean finalResult = FALSE;
g_assert(dst != NULL);
g_assert(src != NULL);
gulong dstLength = (*dst == NULL) ? 0 : strlen(*dst);
gulong srcLength = strlen(src);
gulong totalLength = dstLength + srcLength + 1;
gchar *newDst = (gchar *) g_try_realloc(*dst, totalLength);
if (newDst == NULL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not allocate memory, g_try_realloc(%ld) = NULL", __func__, totalLength);
goto EXITPOINT;
}
g_memmove(newDst + dstLength, src, srcLength + 1);
*dst = newDst;
finalResult = TRUE;
EXITPOINT:
return finalResult;
}
/**
* get_filename_from_full_path
*/
gchar *get_filename_from_full_path(gchar *src)
{
gchar *pointer=NULL;
gchar *result=NULL;
gboolean slashFound=FALSE;
g_assert(src!=NULL);
pointer=src;
do {
if ((*pointer==G_DIR_SEPARATOR) || (*pointer=='\\') || (*pointer=='/')) {
// point to the character after the slash
result=++pointer;
slashFound=TRUE;
}
pointer++;
} while((*pointer)!='\0');
if (!slashFound) result=src;
return result;
}
/**
*
*/
void debug_printf(const char *st, ...)
{
va_list ap;
va_start(ap,st);
#ifdef _DEBUG
vprintf(st,ap);
#endif
va_end(ap);
}
/**
*
*/
char *remove_newline( char *s )
{
int len=strlen(s);
if (s[len-1]=='\n') {
s[len-1]='\0';
}
return s;
}
/**
* returns true if a gchar is an integer
* (Very limited functionality at the moment)
*/
gboolean is_integer(gchar *string)
{
int co;
for (co=0;co<(int)strlen(string);co++) {
// returns zero if it isn't a digit
if (isdigit(string[co])==0) {
return FALSE;
}
}
return TRUE;
}
/**
*
*/
gboolean is_word_character(char ch)
{
gboolean result=FALSE;
if ((ch=='_') || (g_ascii_isalnum(ch))) result=TRUE;
return result;
}
sciteproj-0.7.08/src/clicked_node.h 0000644 0001750 0001750 00000002021 12143703722 016517 0 ustar gusnan gusnan /**
* clicked_node.h - clicked node struct for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_CLICKED_NODE_
#define __HEADER_CLICKED_NODE_
/**
*
*/
struct ClickedNode
{
gboolean valid;
GtkTreeIter iter;
gchar *name;
gint type;
};
typedef struct ClickedNode ClickedNode;
#endif /*__HEADER_CLICKED_NODE_*/
sciteproj-0.7.08/src/gui.c 0000644 0001750 0001750 00000062272 12143703722 014711 0 ustar gusnan gusnan /**
* gui.c - GUI code for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "clicked_node.h"
#include "gui.h"
#include "drag_drop.h"
#include "tree_manipulation.h"
#include "scite_utils.h"
#include "string_utils.h"
#include "prefs.h"
#include "statusbar.h"
#include "graphics.h"
#include "about.h"
#include "properties_dialog.h"
#include "file_utils.h"
#include "search.h"
#include "clipboard.h"
#include "rename.h"
#include "remove.h"
#include "addfiles.h"
#include "recent_files.h"
#include "filelist.h"
#include "gui_callbacks.h"
#include "menus.h"
#include "search.h"
#include "gtk3_compat.h"
// Forward-declare static functions
static gint window_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data);
static void tree_row_activated_cb(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, gpointer userData);
static gboolean mouse_button_pressed_cb(GtkWidget *treeView, GdkEventButton *event, gpointer userData);
//gboolean dialog_response_is_exit(gint test);
void recent_files_switch_visible();
gboolean tree_view_search_equal_func(GtkTreeModel *model,gint column,const gchar *key,GtkTreeIter *iter,gpointer search_data);
gboolean is_name_valid(gchar *instring);
gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer userData);
gchar *window_saved_title=NULL;
static guint sNumMenuActions = G_N_ELEMENTS(sMenuActions);
static TreeViewDragStruct sDragStruct;
static GtkWidget *sMainWindow = NULL;
GtkWidget *projectTreeView = NULL;
static GtkWidget *sGroupPopupMenu = NULL;
static GtkWidget *sFilePopupMenu = NULL;
static GtkWidget *sGeneralPopupMenu = NULL;
ClickedNode clicked_node;
static GtkActionGroup *sActionGroup = NULL;
static GtkUIManager *sGtkUIManager = NULL;
GtkCellRenderer *textCellRenderer = NULL;
GtkCellRenderer *pixbuffCellRenderer = NULL;
GtkWidget *scrolledWindow = NULL;
GtkTreeViewColumn *column1 = NULL;
#if GTK_MAJOR_VERSION>=3
GtkWidget *recentGrid=NULL;
#else
GtkWidget *recentVbox=NULL;
#endif
GtkWidget *recentHbox=NULL;
/**
* Initialize globals (i.e. create the main window and populate it). This is a long chunk of code.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param err returns any errors
*/
gboolean setup_gui(GError **err)
{
gboolean resultCode = FALSE;
GtkTreeSelection *selection = NULL;
GtkWidget *vpaned=NULL;
GtkTargetEntry dragTargets[] = { { (gchar*)"text/uri-list", 0, DND_URI_TYPE } };
GtkTreeStore *projectTreeStore = NULL;
GtkAccelGroup* accelgroup = NULL;
GError *tempErr = NULL;
#if GTK_MAJOR_VERSION>=3
GtkWidget *grid;
GtkWidget *fullGrid=NULL;
#else
GtkWidget *vbox=NULL;
GtkWidget *hbox=NULL;
GtkWidget *statusBarVbox=NULL;
GtkWidget *fullVbox=NULL;
#endif
GtkWidget *recentScrolledWindow=NULL;
clicked_node.valid=FALSE;
clicked_node.name=NULL;
clicked_node.type=-1;
window_saved_title=g_strdup_printf(_("[UNTITLED]"));
// Create top-level window, configure it
if (!(sMainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_window_new() = NULL",
__func__,
"Couldn't init main window"
);
goto EXITPOINT;
}
// TODO: call these in load_graphics instead
if (!(load_graphics(err))) {
goto EXITPOINT;
}
gtk_window_set_icon(GTK_WINDOW(sMainWindow),program_icon_pixbuf);
gtk_window_set_default_icon(program_icon_pixbuf);
gtk_window_set_title(GTK_WINDOW(sMainWindow), window_saved_title);
gtk_container_set_border_width(GTK_CONTAINER(sMainWindow), 0); //3
g_signal_connect(G_OBJECT(sMainWindow), "delete_event", G_CALLBACK(window_delete_event_cb), NULL);
// Main content of the window is a vpaned
#if GTK_MAJOR_VERSION>=3
vpaned=gtk_paned_new(GTK_ORIENTATION_VERTICAL);
// Then we need a grid
grid=gtk_grid_new();
#else
vpaned=gtk_vpaned_new();
// Then we need a vbox
if (!(vbox = gtk_vbox_new(FALSE, 0))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_vbox_new() = NULL",
__func__,
"Couldn't init main vbox"
);
goto EXITPOINT;
}
//gtk_container_add(GTK_CONTAINER(sMainWindow), vbox);
#endif
// Create menus
if (!(sActionGroup = gtk_action_group_new("SciteProjActions"))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_action_group_new() = NULL",
__func__,
"Couldn't init gtk_action_group"
);
goto EXITPOINT;
}
if (!(sGtkUIManager = gtk_ui_manager_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_ui_manager_new() = NULL",
__func__,
"Couldn't init gtk_ui_manager"
);
goto EXITPOINT;
}
#if GTK_MAJOR_VERSION>=3
g_signal_connect(sGtkUIManager, "add_widget", G_CALLBACK(menu_add_widget_cb), grid);
#else
//g_signal_connect(sGtkUIManager, "add_widget", G_CALLBACK(menu_add_widget_cb), vpaned);
g_signal_connect(sGtkUIManager, "add_widget", G_CALLBACK(menu_add_widget_cb), vbox);
#endif
// Fix the context-based translations for the menu strings
int co=0;
gchar *temp=NULL;
gchar *context=NULL;
do {
context=menustrings[co].context;
if (context!=NULL) {
temp=(gchar*)g_dpgettext2(PACKAGE,menustrings[co].context,menustrings[co].string);
if (temp!=NULL) {
sMenuActions[co].label=g_strdup_printf("%s",temp);
++co;
}
}
} while (context!=NULL);
gtk_action_group_set_translation_domain(sActionGroup,PACKAGE);
gtk_action_group_add_actions(sActionGroup, sMenuActions, sNumMenuActions, NULL);
gtk_ui_manager_insert_action_group(sGtkUIManager, sActionGroup, 0);
if (gtk_ui_manager_add_ui_from_string(sGtkUIManager, sMenuDefXML, strlen(sMenuDefXML), &tempErr) == 0) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_ui_manager_add_ui_from_string() = %s",
__func__,
"Couldn't init menus from XML",
tempErr->message
);
goto EXITPOINT;
}
gtk_ui_manager_ensure_update(sGtkUIManager);
// Activate the keyboard accelerators
accelgroup = gtk_ui_manager_get_accel_group(sGtkUIManager);
gtk_window_add_accel_group(GTK_WINDOW(sMainWindow), accelgroup);
// Create popup menus (shown when user right-clicks in gui elements)
sGeneralPopupMenu = gtk_ui_manager_get_widget(sGtkUIManager, "/ui/GeneralPopup");
sGroupPopupMenu = gtk_ui_manager_get_widget(sGtkUIManager, "/ui/GroupPopup");
sFilePopupMenu = gtk_ui_manager_get_widget(sGtkUIManager, "/ui/FilePopup");
recentPopupMenu = gtk_ui_manager_get_widget(sGtkUIManager, "/ui/RecentPopup");
// Add a scrolled window to the main window
if (!(scrolledWindow = gtk_scrolled_window_new(NULL, NULL))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_scrolled_window_new() = NULL",
__func__,
"Couldn't init main scrolled window"
);
goto EXITPOINT;
}
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(grid),scrolledWindow,0,1,1,1);
gtk_widget_set_vexpand(scrolledWindow,TRUE);
gtk_widget_set_hexpand(scrolledWindow,TRUE);
#else
gtk_box_pack_start(GTK_BOX(vbox), scrolledWindow, TRUE, TRUE, 0);
hbox=gtk_hbox_new(FALSE,0);
gtk_widget_show(hbox);
gtk_box_pack_end(GTK_BOX(vbox),hbox,FALSE,TRUE,0);
#endif
// Create the tree datastore
if ((projectTreeStore = create_treestore(&tempErr)) == NULL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s",
tempErr->message,
"Couldn't init treestore"
);
goto EXITPOINT;
}
// Create the treeview, set it up to render the tree datastore, and add it to the hbox
if (!(projectTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(projectTreeStore)))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_tree_view_new_with_model() = NULL",
__func__,
"Couldn't init gtk_tree_view"
);
goto EXITPOINT;
}
g_object_unref(G_OBJECT(projectTreeStore));
gtk_tree_view_set_enable_search(GTK_TREE_VIEW(projectTreeView),TRUE);
if (!(textCellRenderer = gtk_cell_renderer_text_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s, gtk_cell_renderer_text_new() = NULL",
__func__,
"Couldn't init cell renderer"
);
goto EXITPOINT;
}
g_object_set(G_OBJECT(textCellRenderer),
"editable",FALSE,
"mode",GTK_CELL_RENDERER_MODE_EDITABLE,
NULL);
if (!(pixbuffCellRenderer = gtk_cell_renderer_pixbuf_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_cell_renderer_pixbuf_new() = NULL",
__func__,
"Couldn't init gtk_cell_renderer_pixbuf"
);
goto EXITPOINT;
}
if (!(column1 = gtk_tree_view_column_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_tree_view_column_new() = NULL",
__func__,
"Couldn't init gtk_tree_view_column"
);
goto EXITPOINT;
}
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(projectTreeView), FALSE);
gtk_tree_view_column_set_resizable(column1, TRUE);
gtk_tree_view_column_set_min_width(column1, (int)(gPrefs.width*.75));
gtk_tree_view_column_pack_start(column1, pixbuffCellRenderer, FALSE);
gtk_tree_view_column_add_attribute(column1, pixbuffCellRenderer, "pixbuf", COLUMN_ICON);
gtk_tree_view_column_pack_start(column1, textCellRenderer, TRUE);
gtk_tree_view_column_add_attribute(column1, textCellRenderer, "text", COLUMN_FILENAME);
gtk_tree_view_column_add_attribute(column1, textCellRenderer, "weight", COLUMN_FONTWEIGHT);
gtk_tree_view_column_add_attribute(column1, textCellRenderer, "weight-set", COLUMN_FONTWEIGHTSET);
g_signal_connect(G_OBJECT(textCellRenderer), "edited", G_CALLBACK(rename_cb), NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(projectTreeView), column1);
// Stoopid gtk always expands the last column
gtk_container_add(GTK_CONTAINER(scrolledWindow), projectTreeView);
// Get tree events
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(projectTreeView));
gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
g_signal_connect(G_OBJECT(projectTreeView), "row-activated", G_CALLBACK(tree_row_activated_cb), NULL);
gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(projectTreeView),tree_view_search_equal_func,NULL,NULL);
gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(projectTreeView), GDK_BUTTON1_MASK, dragTargets, 1, GDK_ACTION_MOVE);
gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(projectTreeView), dragTargets, 1, GDK_ACTION_MOVE);
sDragStruct.treeView = GTK_TREE_VIEW(projectTreeView);
sDragStruct.treeStore = projectTreeStore;
sDragStruct.isLocalDrag = FALSE;
sDragStruct.dragNodes = NULL;
g_signal_connect(G_OBJECT(projectTreeView), "drag-data-received", G_CALLBACK(drag_data_received_cb), &sDragStruct);
g_signal_connect(G_OBJECT(projectTreeView), "drag-data-get", G_CALLBACK(drag_data_get_cb), &sDragStruct);
g_signal_connect(G_OBJECT(projectTreeView), "drag-motion", G_CALLBACK(drag_motion_cb), &sDragStruct);
g_signal_connect(G_OBJECT(projectTreeView), "row-expanded", G_CALLBACK(row_expand_or_collapse_cb), NULL);
g_signal_connect(G_OBJECT(projectTreeView), "row-collapsed", G_CALLBACK(row_expand_or_collapse_cb), NULL);
g_signal_connect(G_OBJECT(projectTreeView), "button-press-event", G_CALLBACK(mouse_button_pressed_cb), projectTreeView);
g_signal_connect(G_OBJECT(projectTreeView), "key-press-event", G_CALLBACK(key_press_cb), projectTreeView);
// --------------------------------
// Recent file stuff:
#if GTK_MAJOR_VERSION>=3
if (!(recentGrid=gtk_grid_new())) {
g_set_error(err, APP_SCITEPROJ_ERROR,-1,
"%s: %s, gtk_grid_new() = NULL",
"Couldn't init recent grid",
__func__);
goto EXITPOINT;
}
#else
if (!(recentVbox=gtk_vbox_new(FALSE, 0))) {
g_set_error(err, APP_SCITEPROJ_ERROR,-1,
"%s: %s, gtk_vbox_new() = NULL",
__func__,
"Couldn't init recent grid"
);
goto EXITPOINT;
}
#endif
#if GTK_MAJOR_VERSION>=3
if (!(recentHbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0))) {
#else
if (!(recentHbox=gtk_hbox_new(FALSE,0))) {
#endif
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_hbox_new() = NULL",
__func__,
"Couldn't init main vbox"
);
goto EXITPOINT;
}
if ((recentScrolledWindow=init_recent_files(&tempErr)) == NULL) {
goto EXITPOINT;
}
#if GTK_MAJOR_VERSION>=3
gtk_widget_set_vexpand(recentScrolledWindow,TRUE);
gtk_widget_set_hexpand(recentScrolledWindow,TRUE);
gtk_grid_attach(GTK_GRID(recentGrid),recentScrolledWindow,0,0,1,1);
fullGrid=gtk_grid_new();
#else
if (!(fullVbox=gtk_vbox_new(FALSE,0))) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_hbox_new() = NULL",
__func__,
"Couldn't init full_vbox"
);
goto EXITPOINT;
}
gtk_box_pack_start(GTK_BOX(recentVbox),recentScrolledWindow, TRUE,TRUE,0);
gtk_box_pack_end(GTK_BOX(recentVbox),recentHbox,FALSE,TRUE,0);
statusBarVbox=gtk_vbox_new(FALSE,0);
if (!statusBarVbox) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, gtk_hbox_new() = NULL",
__func__,
"Couldn't init statusbar_vbox"
);
goto EXITPOINT;
}
#endif
#if GTK_MAJOR_VERSION>=3
gtk_paned_pack1(GTK_PANED(vpaned),grid,TRUE,FALSE);
gtk_paned_pack2(GTK_PANED(vpaned),recentGrid,TRUE,TRUE);
#else
gtk_paned_pack1(GTK_PANED(vpaned),vbox,TRUE,FALSE);
gtk_paned_pack2(GTK_PANED(vpaned),recentVbox,TRUE,TRUE);
#endif
gtk_widget_show(vpaned);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(fullGrid),vpaned,0,0,1,1);
gtk_widget_show(GTK_WIDGET(fullGrid));
if (!gPrefs.hide_statusbar) {
if (!init_statusbar(fullGrid,vpaned,&tempErr)) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s", tempErr->message,"Error initing statusbar");
goto EXITPOINT;
}
}
gtk_container_add(GTK_CONTAINER(sMainWindow), fullGrid);
#else
gtk_box_pack_start(GTK_BOX(fullVbox),vpaned,TRUE,TRUE,0);
gtk_widget_show(GTK_WIDGET(fullVbox));
if (!gPrefs.hide_statusbar) {
if (!init_statusbar(fullVbox,vpaned,&tempErr)) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: %s",
tempErr->message,
"Couldn't init statusbar"
);
goto EXITPOINT;
}
}
gtk_container_add(GTK_CONTAINER(sMainWindow), fullVbox);
gtk_widget_show(fullVbox);
gtk_widget_show(vpaned);
#endif
g_signal_connect(G_OBJECT(recentTreeView), "key-press-event", G_CALLBACK(key_press_cb), recentTreeView);
gtk_window_resize(GTK_WINDOW(sMainWindow), gPrefs.width, gPrefs.height);
gtk_window_move(GTK_WINDOW(sMainWindow),gPrefs.xpos,gPrefs.ypos);
int window_xsize,window_ysize;
gtk_window_get_size(GTK_WINDOW(sMainWindow),&window_xsize,&window_ysize);
gtk_paned_set_position(GTK_PANED(vpaned),(int)(window_ysize*0.75));
// Show it all....
#if GTK_MAJOR_VERSION>=3
gtk_widget_show(recentGrid);
if (!gPrefs.show_recent) {
gtk_widget_hide(recentGrid);
} else {
gtk_widget_show(recentGrid);
}
#else
gtk_widget_show(recentVbox);
if (!gPrefs.show_recent) {
gtk_widget_hide(recentVbox);
} else {
gtk_widget_show(recentVbox);
}
#endif
gtk_widget_show(projectTreeView);
gtk_widget_show(scrolledWindow);
#if GTK_MAJOR_VERSION>=3
gtk_widget_show(grid);
#else
gtk_widget_show(vbox);
#endif
gtk_widget_show(sMainWindow);
resultCode = TRUE;
// init the filelist
init_filelist();
EXITPOINT:
if (tempErr) g_error_free(tempErr);
return resultCode;
}
/**
*
*/
void gui_close()
{
if (window_saved_title) g_free(window_saved_title);
if (scrolledWindow) gtk_widget_destroy(scrolledWindow);
unload_graphics();
done_statusbar();
done_filelist();
if (sMainWindow) gtk_widget_destroy(sMainWindow);
}
/**
*
*/
void get_dimensions(gint *left, gint *top, gint *width, gint *height) {
gtk_window_get_position(GTK_WINDOW(sMainWindow), left, top);
gtk_window_get_size(GTK_WINDOW(sMainWindow), width, height);
return;
}
/**
* Determine whether a specified row in the tree is expanded.
*
* @return TRUE if the row is expanded; FALSE otherwise
*
* @param path is the GtkTreePath referencing the row
*/
gboolean tree_row_is_expanded(GtkTreePath *path)
{
g_assert(path != NULL);
return gtk_tree_view_row_expanded(GTK_TREE_VIEW(projectTreeView), path);
}
/**
* Expand a row in the tree.
*
* @param path is the GtkTreePath referencing the row
* @param expandChildren indicates whether all children should be expanded
*/
void expand_tree_row(GtkTreePath *path, gboolean expandChildren)
{
if (path!=NULL) {
gtk_tree_view_expand_row(GTK_TREE_VIEW(projectTreeView), path, FALSE);
}
}
/**
* Expand a row in the tree.
*
* @param path is the GtkTreePath referencing the row
* @param expandChildren indicates whether all children should be expanded
*/
void collapse_tree_row(GtkTreePath *path)
{
gtk_tree_view_collapse_row(GTK_TREE_VIEW(projectTreeView), path);
}
/**
* Enable/disable the "Save Project" button.
*
* @param enabled indicates whether the button should be enabled or disabled
*/
void set_save_button_sensitivity(gboolean enabled)
{
//~ if (sSaveProjectButton) {
//~ gtk_widget_set_sensitive(GTK_WIDGET(sSaveProjectButton), enabled);
//~ }
}
/**
* Callback for Gtk "delete_event" message for the top-level application window.
*
* @param widget is not used
* @param event is not used
* @param data is not used
*/
static gint window_delete_event_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
{
gboolean eventHandled = TRUE;
prompt_user_to_save_project();
if (!project_is_dirty()) {
gtk_main_quit();
}
return eventHandled;
}
/**
*
*/
static void switch_folder_icon(GtkTreeView *treeView,GtkTreePath *path)
{
GtkTreeModel *treeModel = NULL;
GtkTreeIter iter;
gint nodeItemType;
gchar *relFilePath = NULL;
treeModel = gtk_tree_view_get_model(treeView);
gtk_tree_model_get_iter(treeModel, &iter, path);
gtk_tree_model_get(treeModel, &iter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &relFilePath, -1);
GdkPixbuf *pixbuf;
gtk_tree_model_get(treeModel, &iter, COLUMN_ICON, &pixbuf,-1);
gboolean res=gtk_tree_view_row_expanded(treeView,path);
if (res) {
gtk_tree_view_collapse_row(treeView,path);
} else {
gtk_tree_view_expand_row(treeView,path,FALSE);
}
g_free(relFilePath);
}
/**
* Callback handler for Gtk "row-activated" event.
*
* @param treeView is the GtkTreeView
* @param path is the GtkTreePath of the activated row
* @param column is not used
* @param userData is not used
*/
static void tree_row_activated_cb(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, gpointer userData)
{
GtkTreeModel *treeModel = NULL;
GtkTreeIter iter;
gchar *relFilePath = NULL;
gchar *absFilePath = NULL;
gchar *command = NULL;
GError *err = NULL;
GtkWidget *dialog = NULL;
gint nodeItemType;
gchar *fixed=NULL;
// Get the data from the row that was activated
treeModel = gtk_tree_view_get_model(treeView);
gtk_tree_model_get_iter(treeModel, &iter, path);
gtk_tree_model_get(treeModel, &iter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &relFilePath, -1);
// We can only open files
if (nodeItemType != ITEMTYPE_FILE) {
switch_folder_icon(treeView,path);
if (gPrefs.dirty_on_folder_change) {
set_project_dirty_status(TRUE);
}
goto EXITPOINT;
}
absFilePath=fix_path((gchar*)get_project_directory(),relFilePath);
fixed=fix_path((gchar*)get_project_directory(),relFilePath);
if ((command = g_strdup_printf("open:%s\n", fixed)) == NULL) {
g_set_error(&err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, g_strdup_printf() = NULL",
"Error formatting SciTE command",
__func__);
}
else {
if (send_scite_command(command, &err)) {
// Try to activate SciTE; ignore errors
activate_scite(NULL);
if (gPrefs.give_scite_focus==TRUE) {
send_scite_command((gchar*)"focus:0",NULL);
}
add_file_to_recent(fixed,NULL);
gchar *statusbar_text=NULL;
statusbar_text=g_strdup_printf(_("Opened %s"),remove_newline(get_filename_from_full_path(command)));
set_statusbar_text(statusbar_text);
g_free(statusbar_text);
}
}
EXITPOINT:
if (err != NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
_("Could not open selected file: \n\n%s"), err->message);
gtk_dialog_run(GTK_DIALOG (dialog));
}
if (relFilePath) g_free(relFilePath);
if (absFilePath) g_free(absFilePath);
if (command) g_free(command);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
if (fixed) g_free(fixed);
}
/**
* Respond to a Gtk "button-press-event" message.
*
* @param treeView is the GTKTreeView widget in which the mouse-button event occurred
* @param event is the GdkEventButton event object
* @param userData is not currently used
*/
static gboolean mouse_button_pressed_cb(GtkWidget *treeView, GdkEventButton *event, gpointer userData)
{
gboolean eventHandled = FALSE;
GtkTreePath *path = NULL;
GtkTreeModel *treeModel = NULL;
gchar *nodeName = NULL;
gint nodeItemType;
GtkTreeIter iter;
GtkTreeSelection *tree_selection=NULL;
g_assert(treeView != NULL);
g_assert(event != NULL);
// Until we know for sure, assume that the user has not clicked on a node
clicked_node.valid=FALSE;
// If it is not a right-click, then ignore it
if (event->type != GDK_BUTTON_PRESS || event->button != 3) {
goto EXITPOINT;
}
// Find if the user has clicked on a node
if (!gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeView), (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL)) {
// Nope-- user clicked in the GtkTreeView, but not on a node
gtk_menu_popup(GTK_MENU(sGeneralPopupMenu), NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent*) event));
goto EXITPOINT;
}
// User clicked on a node, so retrieve the particulars
treeModel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
if (!gtk_tree_model_get_iter(treeModel, &iter, path)) {
goto EXITPOINT;
}
gtk_tree_model_get(treeModel, &iter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &nodeName, -1);
// Save the node info for use by the popup menu callbacks
if (clicked_node.name) g_free(clicked_node.name);
clicked_node.name=NULL;
clicked_node.valid=TRUE;
clicked_node.iter=iter;
clicked_node.type=nodeItemType;
clicked_node.name=nodeName;
nodeName = NULL;
// Check if something is selected
tree_selection=gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));
if (tree_selection!=NULL) {
// Check if clicked on something in the selection, otherwise make the clicked one the selection.
if (gtk_tree_selection_path_is_selected(tree_selection,path)==FALSE) {
// clear selection and make current line selected
gtk_tree_selection_unselect_all(tree_selection);
gtk_tree_selection_select_path (tree_selection,path);
}
}
// Pop up the appropriate menu for the node type
if (nodeItemType == ITEMTYPE_FILE) {
gtk_menu_popup(GTK_MENU(sFilePopupMenu), NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent*) event));
}
else if (nodeItemType == ITEMTYPE_GROUP) {
gtk_menu_popup(GTK_MENU(sGroupPopupMenu), NULL, NULL, NULL, NULL, event->button, gdk_event_get_time((GdkEvent*) event));
}
// We took care of the event, so no need to propogate it
eventHandled = TRUE;
EXITPOINT:
if (path) gtk_tree_path_free(path);
if (nodeName) g_free(nodeName);
return eventHandled;
}
/**
* Set the title of the main window.
*
* @param newName is the desired new name of the window.
*/
void set_window_title(const gchar *newName)
{
g_assert(newName != NULL);
gchar *temp_string=g_new(gchar,512);
g_snprintf(temp_string,512,"%s",newName);
gtk_window_set_title(GTK_WINDOW(sMainWindow), temp_string);
g_free(window_saved_title);
window_saved_title=g_strdup_printf("%s",newName);
g_free(temp_string);
}
/**
*
*/
void update_project_is_dirty(gboolean dirty)
{
gchar *temp_string=g_new(gchar,512);
if ((int)strlen((char*)(window_saved_title))==0) {
g_snprintf(window_saved_title,512,_("[UNTITLED]"));
}
if (!dirty) {
g_snprintf(temp_string,512,"%s",window_saved_title);
} else {
g_snprintf(temp_string,512,"%s *",window_saved_title);
}
gtk_window_set_title(GTK_WINDOW(sMainWindow), temp_string);
g_free(temp_string);
}
/**
*
*/
gboolean dialog_response_is_exit(gint test)
{
gboolean result=FALSE;
if ((test==GTK_RESPONSE_REJECT) || (test==GTK_RESPONSE_CANCEL) ||
(test==GTK_RESPONSE_DELETE_EVENT) || (test==GTK_RESPONSE_NONE)) {
result=TRUE;
}
return result;
}
/**
*
*/
void recent_files_switch_visible()
{
gboolean visible=FALSE;
#if GTK_MAJOR_VERSION>=3
g_object_get(G_OBJECT(recentGrid),"visible", &visible,NULL);
if (visible) {
gtk_widget_hide(recentGrid);
gtk_widget_grab_focus(projectTreeView);
} else {
gtk_widget_show(recentGrid);
}
#else
g_object_get(G_OBJECT(recentVbox),"visible", &visible,NULL);
if (visible) {
gtk_widget_hide(recentVbox);
gtk_widget_grab_focus(projectTreeView);
} else {
gtk_widget_show(recentVbox);
}
#endif
}
sciteproj-0.7.08/src/drag_drop.h 0000644 0001750 0001750 00000004025 12143703722 016063 0 ustar gusnan gusnan /**
* drag_drop.h - Drag-and-drop support for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_DRAG_DROP_
#define __HEADER_DRAG_DROP_
struct TreeNodeStruct {
gint nodeItemType;
GtkTreePath *nodePath;
GtkTreeIter nodeIter;
};
typedef struct TreeNodeStruct TreeNodeStruct;
struct TreeViewDragStruct {
GtkTreeView *treeView;
GtkTreeStore *treeStore;
gboolean isLocalDrag;
TreeNodeStruct *dragNodes;
gint numDragNodes;
GtkTreeViewDropPosition dropPositionHint;
};
typedef struct TreeViewDragStruct TreeViewDragStruct;
#define DND_STRING_TYPE 12345
#define DND_URI_TYPE 12346
// Callback for "drag-drop" event
extern gboolean drag_drop_cb(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data);
// Callback for "drag-motion" event
extern gboolean drag_motion_cb(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data);
// Callback for "drag-data-received" event
extern void drag_data_received_cb(GtkWidget *widget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, gpointer data);
// Callback for "drag-data-get" event
extern void drag_data_get_cb(GtkWidget *widget, GdkDragContext *dc, GtkSelectionData *selection_data, guint info, guint t, gpointer data);
#endif /*__HEADER_DRAG_DROP_*/
sciteproj-0.7.08/src/prefs.h 0000644 0001750 0001750 00000003133 12143703722 015240 0 ustar gusnan gusnan /**
* prefs.h - prefs for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_PREFS_
#define __HEADER_PREFS_
#define PREFS_BUFSIZE 256
/**
*
*/
typedef struct {
int lhs;
int width, height;
int verbosity;
int last_file_filter;
int xpos,ypos;
int search_xpos,search_ypos;
int search_width,search_height;
gboolean dirty_on_folder_change;
gboolean give_scite_focus;
gboolean search_give_scite_focus;
gboolean search_match_whole_words;
gboolean search_match_case;
gboolean allow_duplicates;
gchar *scite_path;
gchar *file_to_load;
gboolean identify_sciteproj_xml;
gboolean show_recent;
gboolean recent_add_to_bottom;
gboolean search_alert_file_warnings;
gboolean search_trim_results;
gboolean hide_statusbar;
} sciteproj_prefs;
extern sciteproj_prefs gPrefs;
extern gchar *prefs_filename;
gboolean init_prefs();
void done_prefs();
#endif /*__HEADER_PREFS_*/
sciteproj-0.7.08/src/search.c 0000644 0001750 0001750 00000060634 12143703722 015372 0 ustar gusnan gusnan /**
* search.c - Search dialog for searching the files in the SciteProj project
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#include "search.h"
#include "tree_manipulation.h"
#include "graphics.h"
#include "string_utils.h"
#include "scite_utils.h"
#include "statusbar.h"
#include "prefs.h"
#include "filelist.h"
#include "gtk3_compat.h"
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_SEARCH_ERROR")
/**
*
*/
enum
{
FILENAME=0,
LINENUMBER,
FILE_CONTENTS,
COLUMNS
};
typedef struct _Data
{
GAsyncQueue *queue;
GList *search_list;
GtkListStore *store;
GtkWidget *search_button;
GtkWidget *result_label;
GtkWidget *search_string_entry;
gchar *text_to_search_for;
gboolean search_give_scite_focus;
gboolean match_case;
gboolean match_whole_words;
gchar *error;
sciteproj_prefs prefs;
int number_of_results;
} Data;
typedef struct _Message
{
gchar *filename;
glong line_number;
gchar *file_contents;
} Message;
/**
*
*/
GtkWidget *window;
gboolean is_searching=FALSE;
GtkWidget *treeview;
GtkWidget *match_case_checkbutton=NULL;
GtkWidget *match_whole_words_only_checkbutton=NULL;
GdkCursor *standard_cursor;
static GThread *thread=NULL;
static gint threaded_flag;
static gboolean search_dialog_open=FALSE;
/**
*
*/
static void setup_tree_view(GtkWidget *treeview);
static void tree_row_activated_cb(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, gpointer userData);
void dialog_response(GtkDialog *dialog,gint response_id,gpointer user_data);
gboolean search_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer userData);
static void destroy_search_dialog_cb(GtkWidget *widget,GdkEvent *event,gpointer data);
G_MODULE_EXPORT void close_button_pressed_cb(GtkWidget *widget,gpointer data);
static void search_button_clicked_cb(GtkButton *button,gpointer data);
static gpointer thread_func(Data *data);
static void cancel_search(gpointer data);
/**
*
*/
void search_dialog_cb()
{
if (!search_dialog_open) {
search_dialog();
search_dialog_open=TRUE;
} else {
gtk_window_present(GTK_WINDOW(window));
}
}
/**
*
*/
void search_dialog()
{
GtkWidget *find_label;
GtkWidget *close_button;
GtkWidget *scrolled_win;
#if GTK_MAJOR_VERSION>=3
GtkWidget *grid;
#else
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *close_hbox;
GtkWidget *check_button_box;
#endif
Data *data;
data=g_slice_new(Data);
data->search_list=list;
data->prefs=gPrefs;
data->error=NULL;
// Make the dialog
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(window), 8);
gtk_window_set_title(GTK_WINDOW(window),_("Search project"));
// Set up size and position from prefs
gtk_window_resize(GTK_WINDOW(window), gPrefs.search_width, gPrefs.search_height);
if (gPrefs.search_xpos!=-1) {
gtk_window_move(GTK_WINDOW(window),gPrefs.search_xpos,gPrefs.search_ypos);
}
#if GTK_MAJOR_VERSION>=3
grid=gtk_grid_new();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
#else
hbox=gtk_hbox_new(FALSE,8);
#endif
find_label=gtk_label_new(_("Find What:"));
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(grid),find_label,0,0,1,1);
#else
gtk_box_pack_start(GTK_BOX(hbox),find_label,FALSE,TRUE,5);
#endif
data->search_string_entry=gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(data->search_string_entry),TRUE);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),data->search_string_entry,find_label,GTK_POS_RIGHT,3,1);
#else
gtk_box_pack_start(GTK_BOX(hbox),data->search_string_entry,TRUE,TRUE,5);
#endif
/*
GtkBox *hbox=gtk_hbox_new(TRUE,0);
gtk_box_pack_end(hbox,search_text_entry,TRUE,TRUE,0);
*/
data->number_of_results=0;
data->search_button=gtk_button_new_from_stock(GTK_STOCK_FIND);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),data->search_button,data->search_string_entry,GTK_POS_RIGHT,1,1);
#else
gtk_box_pack_start(GTK_BOX(hbox),data->search_button,FALSE,FALSE,5);
vbox=gtk_vbox_new(FALSE,8);
gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
check_button_box=gtk_hbox_new(FALSE,8);
#endif
match_case_checkbutton=gtk_check_button_new_with_label(_("Match case"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(match_case_checkbutton),gPrefs.search_match_case);
//gtk_table_attach(GTK_TABLE(table),match_case_checkbutton,0,2,1,2, GTK_SHRINK, GTK_SHRINK, 0,0);
#if GTK_MAJOR_VERSION<3
gtk_box_pack_start(GTK_BOX(check_button_box),match_case_checkbutton,FALSE,TRUE,5);
#endif
//gtk_grid_attach_next_to(GTK_GRID(grid),match_case_checkbutton,
match_whole_words_only_checkbutton=gtk_check_button_new_with_label(_("Match whole word only"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(match_whole_words_only_checkbutton),gPrefs.search_match_whole_words);
//gtk_table_attach(GTK_TABLE(table),match_whole_words_only_checkbutton,2,4,1,2, GTK_SHRINK,GTK_SHRINK, 0,0);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(grid),match_case_checkbutton,0,1,1,1);
gtk_grid_attach(GTK_GRID(grid),match_whole_words_only_checkbutton,1,1,1,1);
#else
gtk_box_pack_start(GTK_BOX(check_button_box),match_whole_words_only_checkbutton,FALSE,TRUE,5);
gtk_box_pack_start(GTK_BOX(vbox),check_button_box,FALSE,FALSE,0);
#endif
treeview=gtk_tree_view_new();
setup_tree_view(treeview);
// init the list store
data->store=gtk_list_store_new(COLUMNS,G_TYPE_STRING,G_TYPE_INT,G_TYPE_STRING);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview),GTK_TREE_MODEL(data->store));
g_object_unref(data->store);
data->search_give_scite_focus=gPrefs.search_give_scite_focus;
g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(tree_row_activated_cb), data);
scrolled_win=gtk_scrolled_window_new(NULL,NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_win),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrolled_win),treeview);
#if GTK_MAJOR_VERSION>=3
gtk_widget_set_vexpand(scrolled_win,TRUE);
gtk_widget_set_hexpand(scrolled_win,TRUE);
gtk_grid_attach(GTK_GRID(grid),scrolled_win,0,2,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox),scrolled_win,TRUE,TRUE,0);
#endif
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_win),
GTK_SHADOW_IN);
close_button=gtk_button_new_from_stock(GTK_STOCK_CLOSE);
#if GTK_MAJOR_VERSION<3
close_hbox=gtk_hbox_new(FALSE,8);
#endif
data->result_label=gtk_label_new(NULL);
gtk_label_set_text(GTK_LABEL(data->result_label),"");
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(grid),data->result_label,0,3,1,1);
gtk_grid_attach(GTK_GRID(grid),close_button,4,3,1,1);
// add the table to the window
gtk_container_add(GTK_CONTAINER(window),grid);
#else
gtk_box_pack_start(GTK_BOX(close_hbox),data->result_label,FALSE,FALSE,0);
gtk_box_pack_end(GTK_BOX(close_hbox),close_button,FALSE,FALSE,5);
gtk_box_pack_start(GTK_BOX(vbox),close_hbox,FALSE,FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
#endif
g_signal_connect(G_OBJECT(window), "destroy",G_CALLBACK (destroy_search_dialog_cb), &window);
g_signal_connect(G_OBJECT(close_button),"clicked",G_CALLBACK(close_button_pressed_cb),data);
g_signal_connect(G_OBJECT(data->search_button),"clicked",G_CALLBACK(search_button_clicked_cb),data);
g_signal_connect(G_OBJECT(window),"key-press-event",G_CALLBACK(search_key_press_cb),data);
gtk_widget_show_all(window);
}
/**
*
*/
static gboolean update_tree(Data *data)
{
GtkTreeIter iter;
Message *msg;
msg=(Message*)g_async_queue_pop(data->queue);
gtk_list_store_append(data->store,&iter);
gtk_list_store_set(data->store,&iter,0,msg->filename,1,msg->line_number,2,msg->file_contents,-1);
g_free(msg->filename);
g_slice_free(Message,msg);
return FALSE;
}
/**
*
*/
gboolean whole_word_helper(gchar before,gchar after)
{
gboolean result=TRUE;
if (is_word_character(after)) {
result=FALSE;
} else {
if (is_word_character(before)) {
result=FALSE;
}
}
return result;
}
/**
*
*/
gboolean check_match(gchar *full_line,int begin_temp_string,gchar *tempString,gchar *text_to_search_for,gint length,gpointer user_data)
{
gboolean result=FALSE;;
Data *data=(Data*)(user_data);
gboolean whole_word=TRUE;
if (data->match_case) {
//printf("%s\n",data->text_to_search_for);
if (!data->match_whole_words) {
// match case, but not whole words
if (strncmp(tempString,text_to_search_for,length)==0) result=TRUE;
} else {
// match the whole word, and also case
if (strncmp(tempString,text_to_search_for,length)==0) {
result=TRUE;
// check if we are at the beginning of the string (full_line points to same location as
// tempString
if (full_line!=tempString) {
gchar before=*(tempString-1);
if (begin_temp_string+length>=((int)strlen(full_line))) {
// we are at the end (no more characters after)
} else {
// there are more characters after
gchar after=*(tempString+length);
whole_word=whole_word_helper(before,after);
}
}
}
if (!whole_word) result=FALSE;
}
} else {
gchar *indep1=g_utf8_casefold(tempString,length);
gchar *indep2=g_utf8_casefold(text_to_search_for,length);
if (!data->match_whole_words) {
// match whole word, but don't match case
if (strncmp(indep1,indep2,length)==0) result=TRUE;
} else {
// match the whole word only, and don't match case
if (strncmp(indep1,indep2,length)==0) {
result=TRUE;
// check if we are at the beginning of the string (full_line points to same location as
// tempString
if (full_line!=tempString) {
gchar before=*(tempString-1);
if (begin_temp_string+length>=((int)strlen(full_line))) {
// we are at the end (no more characters after)
} else {
// there are more characters after
gchar after=*(tempString+length);
whole_word=whole_word_helper(before,after);
}
}
}
if (!whole_word) result=FALSE;
}
}
return result;
}
/**
*
*/
static gpointer thread_func(Data *data)
{
gboolean do_work=TRUE;
Message *msg;
GError *err;
gchar *absFilePath;
GList *file_error_list=NULL;
gint counter=0;
int line_number;
char line[512];
int co;
GList *search_list=data->search_list;
GList *saved_list=search_list;
g_async_queue_ref(data->queue);
while(g_atomic_int_get(&threaded_flag) && do_work && search_list!=NULL) {
msg=g_slice_new(Message);
msg->filename=NULL;
msg->file_contents=NULL;
if (search_list!=NULL) {
if ((gchar*)(search_list->data)!=NULL) {
File *file=(File*)(search_list->data);
gchar *filename=(gchar*)(file->full_path);
// convert to a full path
if (!relative_path_to_abs_path(filename, &absFilePath, get_project_directory(), &err)) {
goto EXITPOINT;
}
// Create a list to store the found elements.
GList *result_list=NULL;
// Open the file
FILE *file_read;
file_read=fopen((const char*)absFilePath,"r");
if (file_read==NULL) {
gchar *temp;
temp=g_strdup_printf("%s",filename);
file_error_list=g_list_prepend(file_error_list,(gpointer)(temp));
} else {
line_number=0;
while(fgets(line,512,file_read)!=NULL) {
char *tempString=line;
line_number++;
for (co=0;cotext_to_search_for);
gboolean text_found=check_match(line,co,tempString,data->text_to_search_for,length,data);
// text found!
if (text_found) {
Message *tempMessage=g_slice_new(Message);
tempMessage->line_number=line_number;
tempMessage->filename=g_strdup_printf("%s",filename);
gchar *resulttemp=remove_newline(line);
if (gPrefs.search_trim_results) {
resulttemp=g_strchug(resulttemp);
resulttemp=g_strchomp(resulttemp);
}
tempMessage->file_contents=g_strdup_printf("%s",resulttemp);
//result_list=g_list_insert_sorted(result_list,(gpointer)(tempMessage),insert_sorted_func);
result_list=g_list_append(result_list,(gpointer)tempMessage);
data->number_of_results++;
text_found=FALSE;
}
tempString++;
}
}
fclose(file_read);
// Now that we have the results for the current file in the list, go
// through that list, and add the results to the tree
GList *iter=result_list;
while ((iter) && (g_atomic_int_get(&threaded_flag))) {
Message *msg=(Message*)iter->data;
//printf("N:%s compared to %s\n",data->full_path,full_path);
//printf("%s%ld\n",msg->filename,msg->line_number);
if (msg->filename!=NULL) {
g_async_queue_push(data->queue,msg);
g_idle_add((GSourceFunc)update_tree,data);
sleep(0);
}
iter=g_list_next(iter);
}
msg->line_number=counter;
counter++;
}
// go to the next element in the list
search_list=g_list_next(search_list);
g_free(absFilePath);
// final element?
if (!search_list) do_work=FALSE;
}
}
}
g_async_queue_unref(data->queue);
if (g_atomic_int_get(&threaded_flag)) {
g_idle_add((GSourceFunc)cancel_search,data);
}
data->search_list=saved_list;
if (file_error_list!=NULL) {
gchar *error_message=NULL;
data->error=NULL;
error_message=g_strdup_printf(_("There was problems opening the following files in the project:\n\n"));
while((file_error_list)) {
gchar *temp=(gchar*)file_error_list->data;
gchar *temp2=g_strconcat(error_message,temp,", \n",NULL);
error_message=temp2;
g_free(temp);
file_error_list=g_list_next(file_error_list);
}
gchar *temp2=g_strconcat(error_message,_("\nThey couldn't be opened for reading in the search.\n"),NULL);
g_free(error_message);
error_message=temp2;
if (error_message!=NULL)
{
data->error=g_strdup(error_message);
g_free(error_message);
}
}
EXITPOINT:
return NULL;
}
/**
*
*/
static void search_button_clicked_cb(GtkButton *button,gpointer user_data)
{
Data *data=(Data*)user_data;
// clear the list
gtk_list_store_clear(data->store);
if (!is_searching) {
if (gtk_entry_get_text_length(GTK_ENTRY(data->search_string_entry))!=0) {
data->number_of_results=0;
// get the text from the search string entry
data->text_to_search_for=(gchar*)(gtk_entry_get_text(GTK_ENTRY(data->search_string_entry)));
data->match_case=(gboolean)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(match_case_checkbutton));
data->match_whole_words=(gboolean)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(match_whole_words_only_checkbutton));
gtk_widget_set_sensitive(GTK_WIDGET(data->search_button),FALSE);
g_atomic_int_set(&threaded_flag,1);
data->queue=g_async_queue_new();
#if ((GLIB_MAJOR_VERSION>=2) && (GLIB_MINOR_VERSION>=31))
thread=g_thread_new("search_thread",(GThreadFunc)thread_func,NULL);
#else
thread=g_thread_create((GThreadFunc)thread_func,data,TRUE,NULL);
#endif
is_searching=TRUE;
// set the mouse cursor
gdk_window_set_cursor(gtk_widget_get_window(window),busy_cursor);
} else {
// string to search for has a length of zero.
GtkWidget *warningDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
_("Please enter a text to search for!\n")
);
gtk_dialog_run(GTK_DIALOG(warningDialog));
gtk_widget_destroy(warningDialog);
}
}
}
/**
*
*/
gboolean search_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
Data *data=(Data*)(user_data);
switch (event->keyval)
{
// Check for both return and Keypad enter
case GDK_KEY_Return:
case GDK_KEY_KP_Enter:
{
//g_print((gchar*)"key_press_cb: keyval = %d = GDK_Return, hardware_keycode = %d\n", event->keyval, event->hardware_keycode);
if (data->search_string_entry!=NULL) {
data->text_to_search_for=(gchar*)gtk_entry_get_text(GTK_ENTRY(data->search_string_entry));
search_button_clicked_cb(GTK_BUTTON(data->search_button),user_data);
}
break;
}
case GDK_KEY_Escape:
{
gtk_widget_destroy(GTK_WIDGET(window));
break;
}
}
/*
if (event->state & GDK_SHIFT_MASK) debug_printf(", GDK_SHIFT_MASK");
if (event->state & GDK_CONTROL_MASK) debug_printf(", GDK_CONTROL_MASK");
if (event->state & GDK_MOD1_MASK) debug_printf(", GDK_MOD1_MASK");
if (event->state & GDK_MOD2_MASK) debug_printf(", GDK_MOD2_MASK");
if (event->state & GDK_MOD3_MASK) debug_printf(", GDK_MOD3_MASK");
if (event->state & GDK_MOD4_MASK) debug_printf(", GDK_MOD4_MASK");
if (event->state & GDK_MOD5_MASK) debug_printf(", GDK_MOD5_MASK");
debug_printf("\n");
*/
return FALSE;
}
/**
* Callback handler for Gtk "row-activated" event.
*
* @param treeView is the GtkTreeView
* @param path is the GtkTreePath of the activated row
* @param column is not used
* @param userData is not used
*/
static void tree_row_activated_cb(GtkTreeView *treeView, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
{
GtkTreeModel *treeModel = NULL;
GtkTreeIter iter;
gchar *relFilePath = NULL;
gchar *absFilePath = NULL;
gchar *command = NULL;
GError *err = NULL;
GtkWidget *dialog = NULL;
//gint nodeItemType;
Data *data=(Data*)(user_data);
gint line_number=-1;
// Get the data from the row that was activated
// We need to do this before launching Scite - because if SciTE wasn't ran before, we need to
// provide the line number to SciTE in the launching command.
gchar *temppath;
treeModel = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
gtk_tree_model_get_iter(treeModel, &iter, path);
gtk_tree_model_get(treeModel, &iter, /*COLUMN_ITEMTYPE, &nodeItemType,*/ FILENAME, &temppath, LINENUMBER, &line_number, -1);
// convert to a full path
if (!relative_path_to_abs_path(temppath, &absFilePath, get_project_directory(), &err)) {
printf(_("Error:%s\n"),err->message);
goto EXITPOINT;
}
// Launch scite if it isn't already launched
if (!scite_ready()) {
gchar *run_options;
run_options=g_strdup_printf("%s -goto:%d",absFilePath,line_number);
if (!launch_scite(run_options,&err)) {
printf(_("Error:%s\n"),err->message);
//goto EXITPOINT;
/*
gchar *errorstring=g_strdup_printf("Couldn't launch scite: %s",newerr->message);
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, errorstring);
gtk_dialog_run(GTK_DIALOG(errDialog));
g_free(errorstring);
gtk_widget_destroy(errDialog);
return;
*/
goto EXITPOINT;
}
}
// It's a file, so try to open it
if ((command = g_strdup_printf("open:%s\n", absFilePath)) == NULL) {
g_set_error(&err, APP_SCITEPROJ_ERROR, -1, "%s: Error formatting Scite director command, g_strdup_printf() = NULL", __func__);
goto EXITPOINT;
}
else {
GError *err;
if (send_scite_command(command, &err)) {
// Try to activate SciTE; ignore errors
activate_scite(NULL);
if (data->search_give_scite_focus) {
GError *err=NULL;
send_scite_command((gchar*)"focus:1",&err);
}
//GError *err;
gchar *statusbar_text=NULL;
statusbar_text=g_strdup_printf(_("Opened %s"),remove_newline(get_filename_from_full_path(command)));
set_statusbar_text(statusbar_text);
g_free(statusbar_text);
} else {
if (err) {
printf(_("Error:%s\n"),err->message);
}
}
}
debug_printf("Go to the line number...\n");
// go to the right line number:
if ((command = g_strdup_printf("goto:%d\n", line_number)) == NULL) {
g_set_error(&err, APP_SCITEPROJ_ERROR, -1, "%s: Error formatting Scite director command, g_strdup_printf() = NULL", __func__);
}
else {
if (send_scite_command(command, &err)) {
// Try to activate SciTE; ignore errors
debug_printf("Send the commend worked!\n");
if (data->search_give_scite_focus!=FALSE) {
send_scite_command((gchar*)"focus:0",NULL);
}
//activate_scite(NULL);
//GError *err;
gchar *statusbar_text=NULL;
statusbar_text=g_strdup_printf(_("Opened %s"),remove_newline(get_filename_from_full_path(command)));
set_statusbar_text(statusbar_text);
g_free(statusbar_text);
} else {
printf("goto didn't work...\n");
if (err) {
printf(_("Error:%s\n"),err->message);
}
}
}
debug_printf("Set scite focus...\n");
if (gPrefs.search_give_scite_focus) {
send_scite_command((gchar*)"focus:1",NULL);
/*
GError *err=NULL;
activate_scite(&err);
if (err) {
printf("focus\n");
printf("Error:%s\n",err->message);
}
*/
}
if (err != NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Could not open selected file: \n\n%s", err->message);
gtk_dialog_run(GTK_DIALOG (dialog));
}
EXITPOINT:
if (relFilePath) g_free(relFilePath);
if (absFilePath) g_free(absFilePath);
if (command) g_free(command);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
*
*/
static void setup_tree_view(GtkWidget *treeview)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
renderer=gtk_cell_renderer_text_new();
column=gtk_tree_view_column_new_with_attributes(_("Filename"),renderer,"text",FILENAME,NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),column);
renderer=gtk_cell_renderer_text_new();
column=gtk_tree_view_column_new_with_attributes(_("Line"),renderer,"text",LINENUMBER,NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),column);
renderer=gtk_cell_renderer_text_new();
column=gtk_tree_view_column_new_with_attributes(_("File contents"),renderer,"text",FILE_CONTENTS,NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview),column);
}
/**
*
*/
void dialog_response(GtkDialog *dialog, gint response_id,gpointer user_data)
{
if (response_id==GTK_RESPONSE_CLOSE) {
// Close all (threads and everything)
gtk_widget_destroy(GTK_WIDGET(window));
}
}
/**
* stop_search
*/
static void stop_search(gpointer user_data)
{
Data *data=(Data*)(user_data);
if (is_searching==1) {
is_searching=0;
g_atomic_int_set(&threaded_flag,0);
if (thread!=NULL) g_thread_join(thread);
g_async_queue_unref(data->queue);
gtk_widget_set_sensitive(GTK_WIDGET(data->search_button),TRUE);
gdk_window_set_cursor(gtk_widget_get_window(window),NULL);
// If we have error results from the search - open a dialog, and show it
if (data->error!=NULL) {
if (data->prefs.search_alert_file_warnings) {
GtkWidget *warningDialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,"%s",data->error);
gtk_dialog_run(GTK_DIALOG(warningDialog));
gtk_widget_destroy(warningDialog);
}
}
gchar *string=g_strdup_printf(_("Found %d elements"),data->number_of_results);
gtk_label_set_text(GTK_LABEL(data->result_label),string);
g_free(string);
// Give a dialog if the search didn't find anything.
if (data->number_of_results==0) {
GtkWidget *dialog=gtk_message_dialog_new(NULL,
GTK_DIALOG_MODAL,GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,_("The search didn't give any results."));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
}
}
/**
*
*/
static void cancel_search(gpointer data)
{
stop_search((Data*)data);
}
/**
*
*/
static void destroy_search_dialog_cb(GtkWidget *widget,GdkEvent *event,gpointer data)
{
stop_search(data);
search_dialog_open=FALSE;
}
/**
*
*/
G_MODULE_EXPORT void close_button_pressed_cb(GtkWidget *widget,gpointer user_data)
{
Data *data=(Data*)user_data;
stop_search(data);
// close the window (calls the destroy_search_dialog_cb function)
gtk_widget_destroy(GTK_WIDGET(window));
}
sciteproj-0.7.08/src/addfiles.c 0000644 0001750 0001750 00000017541 12143703722 015677 0 ustar gusnan gusnan /**
* addfiles.c - Interface for adding files to the project
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include "clicked_node.h"
#include "gui.h"
#include "tree_manipulation.h"
#include "addfiles.h"
/**
* Callback to handle "activation" message from a GtkEntry widget. This code allows a return/enter
* keystroke to trigger dismissal of the dialog box containing the GtkEntry.
*
* @param entry is the GtkEntry widget
* @param dialog is the dialog that contains the GtkEntry widget
*/
void entry_widget_activated_cb(GtkEntry *entry, gpointer dialog)
{
if (dialog != NULL) {
gtk_dialog_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
}
}
/**
* Callback for "Add File" menu item
*/
void addfile_menu_cb()
{
GError *err = NULL;
// Get the selction, and add to that group
GtkTreeIter *parentIter=NULL;
GtkTreeIter nodeIter;
gboolean nodeValid=FALSE;
GList *list=NULL;
GtkTreeSelection *treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(projectTreeView));
GtkTreeModel *tree_model=gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView)); //GTK_TREE_MODEL(get_treestore(&err));
list = gtk_tree_selection_get_selected_rows(treeSelection, NULL);
// is the list empty?
if (list) {
list=g_list_first(list);
GtkTreePath *path=(GtkTreePath*)list->data;
gtk_tree_model_get_iter (tree_model, &nodeIter, path);
nodeValid=TRUE;
g_list_foreach (list, (GFunc)(gtk_tree_path_free), NULL);
g_list_free (list);
}
if (nodeValid) {
int nodeType=-1;
gtk_tree_model_get(tree_model, &nodeIter, COLUMN_ITEMTYPE, &nodeType, -1);
if (nodeType==ITEMTYPE_GROUP) {
parentIter=&nodeIter;
} else {
GtkTreeIter newIter;
if (gtk_tree_model_iter_parent(tree_model,&newIter,&nodeIter)) {
parentIter=&newIter;
}
}
}
if (parentIter!=NULL) {
gchar *nodeContents=NULL;
gtk_tree_model_get(tree_model, parentIter, COLUMN_FILENAME, &nodeContents, -1);
g_free(nodeContents);
} else {
}
if (!add_files_to_project(parentIter, &err)) {
GtkWidget *dialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
"An error occurred while trying add files to the project: %s", err->message);
if (dialog) {
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
}
if (err) g_error_free(err);
}
/**
* Callback for menu manager to populate GUI widgets
*
* @param ui is the GtkUIManager
* @param widget is the GtkWidget to add to the UI
* @param container is the container to add widget to
*/
void menu_add_widget_cb(GtkUIManager *ui, GtkWidget *widget, GtkContainer *container)
{
// use Grid instead of box packing on GTK3
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(container),widget,0,0,1,1);
#else
gtk_box_pack_start(GTK_BOX(container), widget, FALSE, FALSE, 0);
#endif
gtk_widget_show(widget);
}
/**
* Add files to a group or the root of the tree
*/
void popup_add_files_cb()
{
GtkWidget *dialog = NULL;
GError *err = NULL;
GtkTreeIter *nodeIter = NULL;
//debug_printf("%s!\n",__func__);
// Files cannot be added to files!
if (clicked_node.valid && clicked_node.type == ITEMTYPE_FILE) {
goto EXITPOINT;
}
// Add to the root or to a group?
if (clicked_node.valid) {
nodeIter = &(clicked_node.iter);
}
if (!add_files_to_project(nodeIter, &err)) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "An error occurred while trying add files to the project: %s", err->message);
gtk_dialog_run(GTK_DIALOG(dialog));
} else {
}
EXITPOINT:
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
* Add a group to the root of the tree, or to an existing group
*/
void popup_add_group_cb()
{
GtkTreeIter *nodeIter = NULL;
// Groups cannot be added to files!
if (clicked_node.valid && clicked_node.type == ITEMTYPE_FILE) {
goto EXITPOINT;
}
// Are we adding this to the root of the tree, or to an existing group?
if (clicked_node.valid) {
nodeIter = &(clicked_node.iter);
}
ask_name_add_group(nodeIter);
EXITPOINT:
return;
}
/**
* Ask the user for the name of a group and add it to the tree
*
* @param nodeIter is the node the group will be added to as a child; if NULL, then the group is added to the root of the tree
*/
void ask_name_add_group(GtkTreeIter *nodeIter)
{
GError *err = NULL;
GtkWidget *dialog = NULL;
GtkWidget* gtkEntry = NULL;
GtkWidget* gtkLabel = NULL;
GtkWidget* table = NULL;
#if GTK_MAJOR_VERSION<3
GtkAttachOptions options = (GtkAttachOptions) (GTK_EXPAND | GTK_SHRINK | GTK_FILL);
#endif
const gchar *groupName = NULL;
gint dialogResponse;
// Create a dialog box with a nicely-centered text entry widget
dialog = gtk_dialog_new_with_buttons(_("Create Group"), NULL, GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_hide), dialog);
gtk_container_set_border_width(GTK_CONTAINER(dialog), 0);
#if GTK_MAJOR_VERSION>=3
table=gtk_grid_new();
gtk_grid_set_row_spacing (GTK_GRID (table), 6);
gtk_grid_set_column_spacing(GTK_GRID(table),6);
#else
table = gtk_table_new(1, 2, FALSE);
#endif
gtkLabel = gtk_label_new(_("Enter name of new group:"));
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(table),gtkLabel,0,0,3,1);
#else
gtk_table_attach(GTK_TABLE(table), gtkLabel, 0, 1, 0, 1, options, options, 5, 5);
#endif
gtkEntry = gtk_entry_new();
g_signal_connect(G_OBJECT(gtkEntry), "activate", G_CALLBACK(entry_widget_activated_cb), dialog);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(table),gtkEntry,gtkLabel,GTK_POS_RIGHT,3,1);
#else
gtk_table_attach(GTK_TABLE(table), gtkEntry, 1, 2, 0, 1, options, options, 5, 5);
#endif
GtkWidget *container_vbox=gtk_dialog_get_content_area(GTK_DIALOG(dialog));
gtk_container_add(GTK_CONTAINER(container_vbox), table);
gtk_widget_show_all(dialog);
// Let the user enter a name or cancel the whole thing
dialogResponse=gtk_dialog_run(GTK_DIALOG(dialog));
if (dialog_response_is_exit(dialogResponse)) {
goto EXITPOINT;
}
groupName = gtk_entry_get_text(GTK_ENTRY(gtkEntry));
if (groupName == NULL || *groupName == '\0') {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Invalid group name");
gtk_dialog_run(GTK_DIALOG(errDialog));
gtk_widget_destroy(errDialog);
goto EXITPOINT;
}
// Add the group
if (!add_tree_group(nodeIter, ADD_CHILD, groupName, TRUE, NULL, &err)) {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "An error occurred while adding the group: %s", err->message);
gtk_dialog_run(GTK_DIALOG(errDialog));
gtk_widget_destroy(errDialog);
}
EXITPOINT:
// Destroying the dialog should also destroy the table, label, and entry widgets
if (gtkLabel) gtk_widget_destroy(GTK_WIDGET(gtkLabel));
if (table) gtk_widget_destroy(GTK_WIDGET(table));
if (dialog) gtk_widget_destroy(GTK_WIDGET(dialog));
if (err) g_error_free(err);
// Do NOT free groupName, since that is owned by the GtkEntry widget!
}
sciteproj-0.7.08/src/gui_callbacks.h 0000644 0001750 0001750 00000002611 12143703722 016704 0 ustar gusnan gusnan /**
* gui_callbacks.h - GUI callback code for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_GUI_CALLBACKS_
#define __HEADER_GUI_CALLBACKS_
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_GUI_ERROR")
void row_expand_or_collapse_cb(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer user_data);
void quit_menu_cb();
void about_menu_cb();
void saveproject_menu_cb();
void saveproject_as_menu_cb();
void openproject_menu_cb();
void creategroup_menu_cb();
void popup_open_file_cb();
void expand_all_items_cb();
void collapse_all_items_cb();
void sort_ascending_cb();
void sort_descending_cb();
void edit_options_cb();
#endif /*__HEADER_GUI_CALLBACKS_*/
sciteproj-0.7.08/src/about.h 0000644 0001750 0001750 00000002026 12143703722 015233 0 ustar gusnan gusnan /**
* about.h - about dialog for SciteProj
*
* Copyright 2008-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_ABOUT_
#define __HEADER_ABOUT_
/* extern gchar *sVersion;*/
void show_about_dialog();
void show_usage_dialog();
void show_version();
void init_version_string();
void done_version_string();
extern gchar *version_string;
#endif /*__HEADER_ABOUT_*/
sciteproj-0.7.08/src/filelist.c 0000644 0001750 0001750 00000005451 12143703722 015734 0 ustar gusnan gusnan /**
* filelist.c - list containing all files in the project
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include "filelist.h"
/**
*
*/
GList *list=NULL;
/**
* init the list of files in the project
*
*/
gboolean init_filelist()
{
return TRUE;
}
/**
* free the data of every item
*/
static void free_list_data(gpointer data,gpointer priv)
{
File *file=(File*)data;
g_free(file);
}
/**
*
*/
void done_filelist()
{
// go through the list and free all
g_list_foreach(list,free_list_data,NULL);
// free the actual list structure
if (list!=NULL) g_list_free(list);
}
/**
*
*/
static void printitem(gpointer data,gpointer priv)
{
File *file=(File*)data;
gchar *filename=file->filename;
gchar *full_path=file->full_path;
printf("File: %d - %s, %s\n",file->count,filename,full_path);
}
/**
*
*/
void print_filelist()
{
printf("Filelist:-----------------\n");
g_list_foreach(list,printitem,NULL);
}
/**
*
*/
File *exists_in_list(gchar *full_path)
{
File *result=NULL;
GList *iter=list;
while(iter) {
File *data=(File*)iter->data;
if (result==NULL) {
//printf("N:%s compared to %s\n",data->full_path,full_path);
if (g_strcmp0(data->full_path,full_path)==0) {
result=data;
}
}
iter=iter->next;
}
return result;
}
/**
*
*/
void add_item(gchar *filename, gchar *full_path)
{
File *newFile;
// printf("Full:%s\n",full_path);
newFile=exists_in_list(full_path);
if (newFile==NULL) {
// doesn't exist in list, create it
newFile=(File*)(g_malloc0(sizeof(File)));
newFile->filename=g_strdup(filename);
newFile->full_path=g_strdup(full_path);
newFile->count=1;
list=g_list_append(list,newFile);
} else {
newFile->count++;
}
}
/**
*
*/
gboolean remove_item(gchar *filename, gchar *full_path)
{
File *file=exists_in_list(full_path);
if (file) {
if (file->count>1) {
// decrease the usage count
file->count--;
} else {
// if the usage count is zero, remove the object from the list
list=g_list_remove(list,file);
}
return TRUE;
}
return FALSE;
}
sciteproj-0.7.08/src/graphics.c 0000644 0001750 0001750 00000006740 12143703722 015723 0 ustar gusnan gusnan /**
* graphics.c - graphics code for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include "string_utils.h"
#include "graphics.h"
#include "about.h"
#include "../graphics/dir-close.xpm"
#include "../graphics/dir-open.xpm"
#include "../graphics/text-x-cpp.xpm"
#include "../graphics/text-x-h.xpm"
#include "../graphics/text-x-txt.xpm"
#include "../graphics/text-x-java.xpm"
#include "../graphics/text-x-lua.xpm"
#include "../graphics/sciteproj.xpm"
GdkPixbuf *header_file_pixbuf=NULL;
GdkPixbuf *cpp_file_pixbuf=NULL;
GdkPixbuf *txt_file_pixbuf=NULL;
GdkPixbuf *java_file_pixbuf=NULL;
GdkPixbuf *lua_file_pixbuf=NULL;
GdkPixbuf *directory_closed_pixbuf=NULL;
GdkPixbuf *directory_open_pixbuf=NULL;
GdkPixbuf *program_icon_pixbuf=NULL;
GdkCursor *standard_cursor=NULL;
GdkCursor *busy_cursor=NULL;
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_GRAPHICS_ERROR")
/**
* Loads all graphics required by the program
* @return TRUE on success, FALSE on failure
* @param err returns any errors
*/
gboolean load_graphics(GError **err)
{
GdkPixbuf *temp=NULL;
program_icon_pixbuf=gdk_pixbuf_new_from_xpm_data((const char **)sciteproj_xpm);
directory_closed_pixbuf=gdk_pixbuf_new_from_xpm_data((const char**)dir_close_xpm);
directory_open_pixbuf=gdk_pixbuf_new_from_xpm_data((const char **)dir_open_xpm);
temp=gdk_pixbuf_new_from_xpm_data((const char **)text_x_cpp_xpm);
cpp_file_pixbuf=gdk_pixbuf_scale_simple(temp,16,16,GDK_INTERP_HYPER);
g_object_unref(temp);
temp=gdk_pixbuf_new_from_xpm_data((const char **)text_x_h_xpm);
header_file_pixbuf=gdk_pixbuf_scale_simple(temp,16,16,GDK_INTERP_HYPER);
g_object_unref(temp);
temp=gdk_pixbuf_new_from_xpm_data((const char **)text_x_txt_xpm);
txt_file_pixbuf=gdk_pixbuf_scale_simple(temp,16,16,GDK_INTERP_HYPER);
g_object_unref(temp);
temp=gdk_pixbuf_new_from_xpm_data((const char **)text_x_java_xpm);
java_file_pixbuf=gdk_pixbuf_scale_simple(temp,16,16,GDK_INTERP_HYPER);
g_object_unref(temp);
temp=gdk_pixbuf_new_from_xpm_data((const char **)text_x_lua_xpm);
lua_file_pixbuf=gdk_pixbuf_scale_simple(temp,16,16,GDK_INTERP_HYPER);
g_object_unref(temp);
standard_cursor=gdk_cursor_new(GDK_X_CURSOR);
busy_cursor=gdk_cursor_new(GDK_WATCH);
return TRUE;
}
/**
*
*/
void unload_graphics()
{
if (program_icon_pixbuf!=NULL) g_object_unref(program_icon_pixbuf);
if (cpp_file_pixbuf!=NULL) g_object_unref(cpp_file_pixbuf);
if (header_file_pixbuf!=NULL) g_object_unref(header_file_pixbuf);
if (txt_file_pixbuf!=NULL) g_object_unref(txt_file_pixbuf);
if (java_file_pixbuf!=NULL) g_object_unref(java_file_pixbuf);
if (lua_file_pixbuf!=NULL) g_object_unref(lua_file_pixbuf);
if (directory_closed_pixbuf!=NULL) g_object_unref(directory_closed_pixbuf);
if (directory_open_pixbuf!=NULL) g_object_unref(directory_open_pixbuf);
}
sciteproj-0.7.08/src/graphics.h 0000644 0001750 0001750 00000002440 12143703722 015721 0 ustar gusnan gusnan /**
* graphics.h - graphics code for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_GRAPHICS_
#define __HEADER_GRAPHICS_
/**
*
*/
extern GdkPixbuf *header_file_pixbuf;
extern GdkPixbuf *cpp_file_pixbuf;
extern GdkPixbuf *txt_file_pixbuf;
extern GdkPixbuf *lua_file_pixbuf;
extern GdkPixbuf *java_file_pixbuf;
extern GdkPixbuf *directory_closed_pixbuf;
extern GdkPixbuf *directory_open_pixbuf;
extern GdkPixbuf *program_icon_pixbuf;
gboolean load_graphics(GError **err);
void unload_graphics();
extern GdkCursor *standard_cursor;
extern GdkCursor *busy_cursor;
#endif /*__HEADER_GRAPHICS_*/
sciteproj-0.7.08/src/gui.h 0000644 0001750 0001750 00000003317 12143703722 014711 0 ustar gusnan gusnan /**
* gui.h - GUI code for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_GUI_
#define __HEADER_GUI_
/**
* Variables
*/
extern gchar *window_saved_title;
extern GtkWidget *projectTreeView;
extern GtkWidget *recentTreeView;
extern GtkCellRenderer *textCellRenderer;
extern ClickedNode clicked_node;
extern GtkTreeViewColumn *column1;
// Initialize the GUI
gboolean setup_gui(GError **err);
void gui_close();
// Enable/Disable the "Save Project" button
void set_save_button_sensitivity(gboolean enabled);
// Set the window title
void set_window_title(const gchar *newName);
// Is a given row expanded?
gboolean tree_row_is_expanded(GtkTreePath *path);
// Expand a row
void expand_tree_row(GtkTreePath *path, gboolean expandChildren);
void collapse_tree_row(GtkTreePath *path);
void get_dimensions(gint *left, gint *top, gint *width, gint *height);
void update_project_is_dirty(gboolean dirty);
gboolean dialog_response_is_exit(gint test);
void recent_files_switch_visible();
#endif /*__HEADER_GUI_*/
sciteproj-0.7.08/src/folder_to_xml.h 0000644 0001750 0001750 00000001721 12143703722 016757 0 ustar gusnan gusnan /**
* folder_to_xml.h - file system to xml convertion for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_FOLDER_TO_XML_
#define __HEADER_FOLDER_TO_XML_
gboolean folder_to_xml(gchar *folder,gchar *save_filename,int max_depth);
#endif /*__HEADER_FOLDER_TO_XML_*/
sciteproj-0.7.08/src/string_utils.h 0000644 0001750 0001750 00000003115 12143703722 016647 0 ustar gusnan gusnan /**
* string_utils.h - misc string utils for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_STRING_UTILS_
#define __HEADER_STRING_UTILS_
// Append a string to a (possibly) existing string
gboolean str_append(gchar **dst, const gchar *src, GError **err);
// Convert an absolute file path to a relative file path
gboolean abs_path_to_relative_path(const gchar *absPath, gchar **relativePath, const gchar *basePath, GError **err);
// Convert a relative file path to an absolute file path
gboolean relative_path_to_abs_path(gchar *relativePath, gchar **absPath, const gchar *basePath, GError **err);
// get the filename from a full path+filename
gchar *get_filename_from_full_path(gchar *src);
void debug_printf(const char *st, ...);
char *remove_newline( char *s );
gboolean is_integer(gchar *string);
gboolean is_word_character(char ch);
#endif /*__HEADER_STRING_UTILS_*/
sciteproj-0.7.08/src/gui_callbacks.c 0000644 0001750 0001750 00000022444 12143703722 016705 0 ustar gusnan gusnan /**
* gui_callbacks.c - GUI callback code for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "gui_callbacks.h"
#include "clicked_node.h"
#include "gui.h"
#include "drag_drop.h"
#include "tree_manipulation.h"
#include "scite_utils.h"
#include "string_utils.h"
#include "prefs.h"
#include "statusbar.h"
#include "graphics.h"
#include "about.h"
#include "properties_dialog.h"
#include "file_utils.h"
#include "addfiles.h"
#include "recent_files.h"
#include "remove.h"
#include "rename.h"
#include "filelist.h"
#include "gtk3_compat.h"
/**
* Expands all folders
*/
static gboolean foreach_expand(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data)
{
expand_tree_row(path,TRUE);
return FALSE;
}
/**
* Collapses all folders
*/
gboolean foreach_collapse(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data)
{
collapse_tree_row(path);
return FALSE;
}
/**
*
*/
void sort_ascending_cb()
{
GError *err = NULL;
if (clicked_node.valid && clicked_node.type==ITEMTYPE_FILE) {
goto EXITPOINT;
}
sort_children(&(clicked_node.iter),&err,compare_strings_smaller);
EXITPOINT:
//
if (err) g_error_free(err);
}
/**
*
*/
void sort_descending_cb()
{
GError *err = NULL;
if (clicked_node.valid && clicked_node.type==ITEMTYPE_FILE) {
goto EXITPOINT;
}
sort_children(&clicked_node.iter,&err,compare_strings_bigger);
EXITPOINT:
//
if (err) g_error_free(err);
}
/**
* Open the selected file.
* This is called when a file is rightclicked and open is selected in the menu
*/
void popup_open_file_cb()
{
gchar *command = NULL;
GError *err = NULL;
GtkWidget *dialog = NULL;
gchar *absFilePath = NULL;
// several files in selection?
// We can only open files
if (!clicked_node.valid || clicked_node.type != ITEMTYPE_FILE) {
goto EXITPOINT;
}
if (!open_filename(clicked_node.name,(gchar*)(get_project_directory()),&err)) {
goto EXITPOINT;
}
add_file_to_recent(clicked_node.name,NULL);
EXITPOINT:
if (err != NULL) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
_("Could not open selected file: \n\n%s"), err->message);
gtk_dialog_run(GTK_DIALOG (dialog));
}
if (command) g_free(command);
if (absFilePath) g_free(absFilePath);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
*
*/
void collapse_all_items_cb()
{
gtk_tree_model_foreach(gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView)),foreach_collapse,NULL);
}
/**
* edit_options_cb
* opens the user-specific options-file ($HOME/.sciteproj) in SciTE.
*/
void edit_options_cb()
{
GError *err=NULL;
gchar *command=NULL;
if ((command = g_strdup_printf("open:%s\n", prefs_filename)) == NULL) {
g_set_error(&err, APP_SCITEPROJ_ERROR, -1,
"%s: %s, g_strdup_printf() = NULL",
"Error formatting SciTE command",
__func__);
}
else {
if (send_scite_command(command, &err)) {
// Try to activate SciTE; ignore errors
activate_scite(NULL);
if (gPrefs.give_scite_focus==TRUE) {
send_scite_command((gchar*)"focus:0",NULL);
}
}
}
}
/**
*
*/
void expand_all_items_cb()
{
gtk_tree_model_foreach(gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView)),foreach_expand,NULL);
}
/**
* step-through function for expand/collapse folder
*
* @param tree_view
* @param newiter
* @param tree_path
*/
static void fix_folders_step_through(GtkTreeView *tree_view, GtkTreeIter newiter,GtkTreePath *tree_path)
{
GtkTreeModel *tree_model = gtk_tree_view_get_model(tree_view);
gchar *relFilePath;
GError *error;
gint nodeItemType;
GtkTreeIter iter=newiter;
do {
gtk_tree_model_get(tree_model, &iter, COLUMN_ITEMTYPE, &nodeItemType, -1);
if (nodeItemType==ITEMTYPE_GROUP) {
GtkTreePath *srcPath = gtk_tree_model_get_path(tree_model, &iter);
gboolean groupIsExpanded = tree_row_is_expanded(srcPath);
if (groupIsExpanded) {
set_tree_node_icon(&iter,directory_open_pixbuf,&error);
} else {
set_tree_node_icon(&iter,directory_closed_pixbuf,&error);
}
gtk_tree_model_get(tree_model, &iter, COLUMN_FILEPATH, &relFilePath, -1);
if (gtk_tree_model_iter_has_child(tree_model,&iter)) {
GtkTreeIter newIter;
gtk_tree_model_iter_children(tree_model,&newIter,&iter);
fix_folders_step_through(tree_view,newIter,tree_path);
}
g_free(relFilePath);
gtk_tree_path_free(srcPath);
} else {
}
} while(gtk_tree_model_iter_next(tree_model,&iter));
}
/**
* Callback for expand/collapse event of GtkTreeView
*
* @param treeView is not used
* @param arg1 is not used
* @param arg2 is not used
* @param user_data is not used
*/
void row_expand_or_collapse_cb(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *tree_path, gpointer user_data)
{
/* Switch the folder icon open/closed*/
// make sure all icons the folder (and folders inside it) are set to a correct icon.
fix_folders_step_through(tree_view,*iter,tree_path);
}
/**
* Callback for "Quit" menu item
*/
void quit_menu_cb()
{
prompt_user_to_save_project();
if (!project_is_dirty()) {
gtk_main_quit();
}
}
/**
* Callback for "About" menu item
*/
void about_menu_cb()
{
show_about_dialog();
}
/**
* Callback for "Save Project As..." menu item
*/
void saveproject_as_menu_cb()
{
GError *err = NULL;
if (!save_project(NULL,&err)) {
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("An error occurred while saving the project: %s"), err->message);
if (dialog) {
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
}
if (err) g_error_free(err);
}
/**
* Callback for "Save Project" menu item
*/
void saveproject_menu_cb()
{
GError *err = NULL;
gchar *temp_filepath=get_project_filepath();
if (!save_project(temp_filepath,&err)) {
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("An error occurred while saving the project: %s"), err->message);
if (dialog) {
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
}
if (err) g_error_free(err);
}
/**
* Callback for "Open Project" menu item
*/
void openproject_menu_cb()
{
GError *err = NULL;
if (!load_project(NULL, &err)) {
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("An error occurred while opening project file: %s"), err->message);
if (dialog) {
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
}
if (err) g_error_free(err);
}
/**
* Callback for "Create Group" menu item
*/
void creategroup_menu_cb()
{
ask_name_add_group(NULL);
}
/**
*
*/
gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer userData)
{
switch (event->keyval)
{
case GDK_KEY_BackSpace:
{
debug_printf((gchar*)"key_press_cb: keyval = %d = GDK_BackSpace, hardware_keycode = %d\n", event->keyval, event->hardware_keycode);
break;
}
case GDK_KEY_Delete:
{
do_remove_node(TRUE);
break;
}
case GDK_KEY_Insert:
{
break;
}
case GDK_KEY_F2:
{
do_rename_node(TRUE);
return TRUE;
}
case GDK_KEY_F5:
{
print_filelist();
break;
}
default:
{
debug_printf("key_press_cb: keyval = %d = '%c', hardware_keycode = %d\n", event->keyval, (char) event->keyval, event->hardware_keycode);
return FALSE;
}
}
if (event->state & GDK_SHIFT_MASK) debug_printf(", GDK_SHIFT_MASK");
if (event->state & GDK_CONTROL_MASK) debug_printf(", GDK_CONTROL_MASK");
if (event->state & GDK_MOD1_MASK) debug_printf(", GDK_MOD1_MASK");
if (event->state & GDK_MOD2_MASK) debug_printf(", GDK_MOD2_MASK");
if (event->state & GDK_MOD3_MASK) debug_printf(", GDK_MOD3_MASK");
if (event->state & GDK_MOD4_MASK) debug_printf(", GDK_MOD4_MASK");
if (event->state & GDK_MOD5_MASK) debug_printf(", GDK_MOD5_MASK");
debug_printf("\n");
return FALSE;
}
/**
* search function for the gtk_tree_view_set_search_equal_func
* @return TRUE when rows DONT match, FALSE when rows match
*/
gboolean tree_view_search_equal_func(GtkTreeModel *model,gint column,const gchar *key,GtkTreeIter *iter,gpointer search_data)
{
gchar *filename;
// For some reason this should return TRUE if the row DONT match
gboolean res=TRUE;
gtk_tree_model_get(model, iter, COLUMN_FILENAME, &filename, -1);
// zero when matches, which means we should return FALSE
if (g_ascii_strncasecmp(key,filename,strlen(key))==0) res=FALSE;
g_free(filename);
return res;
}
sciteproj-0.7.08/src/addfiles.h 0000644 0001750 0001750 00000002124 12143703722 015673 0 ustar gusnan gusnan /**
* addfiles.h - Interface for adding files to the project
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_ADDFILES_
#define __HEADER_ADDFILES_
/**
*
*/
void popup_add_files_cb();
void popup_add_group_cb();
void ask_name_add_group(GtkTreeIter *nodeIter);
void addfile_menu_cb();
void menu_add_widget_cb(GtkUIManager *ui, GtkWidget *widget, GtkContainer *container);
#endif /*__HEADER_ADDFILES_*/
sciteproj-0.7.08/src/rename.c 0000644 0001750 0001750 00000010624 12143703722 015366 0 ustar gusnan gusnan /**
* rename.c - code for renaming a group for SciteProj
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include "tree_manipulation.h"
#include "clicked_node.h"
#include "gui.h"
#include "rename.h"
/**
*
*/
/**
*
*/
void rename_cb(gchar *new_text, gchar *path_string,gpointer user_data)
{
gchar *new_folder_name=(gchar*)user_data;
GError *err = NULL;
GtkTreePath *path=gtk_tree_path_new_from_string(path_string);
GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView));
GtkTreeIter iter;
if ( !gtk_tree_model_get_iter ( model, &iter, path) ) { // get iter from specified path
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "An error occurred in gtk_tree_model_get_iter");
gtk_dialog_run(GTK_DIALOG(errDialog));
gtk_widget_destroy(errDialog);
}
if (!set_tree_node_name(&iter,new_folder_name,&err)) {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "An error occurred while renaming the group: %s", err->message);
gtk_dialog_run(GTK_DIALOG(errDialog));
gtk_widget_destroy(errDialog);
}
if (err) g_error_free(err);
}
/**
*
*/
void do_rename_iter(GtkTreeIter iter)
{
GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView));
int nodeItemType;
//gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_model_get(model, &iter, COLUMN_ITEMTYPE, &nodeItemType, -1);
// We can only rename groups
if (nodeItemType==ITEMTYPE_GROUP) {
// Set the node as editable
g_object_set(G_OBJECT(textCellRenderer), "editable",TRUE, NULL);
GtkTreePath *path;
path=gtk_tree_model_get_path(model,&iter);
// set the cursor on the cell that is to be edited, and activate the editing
gtk_tree_view_set_cursor_on_cell(GTK_TREE_VIEW(projectTreeView),path,column1,NULL,TRUE);
// Set the node as not editable after we are done
g_object_set(G_OBJECT(textCellRenderer), "editable",FALSE, NULL);
}
}
/**
*
*/
void do_rename_node(gboolean ignore_clicked_node)
{
GError *err = NULL;
GtkWidget *dialog = NULL;
// if there is only one selected, get its name
GtkTreeSelection *selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW(projectTreeView) );
GtkTreeModel *model;
GtkTreeIter iter;
if (gtk_tree_selection_count_selected_rows(selection) == 0)
return;
model=gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView));
GList *list = gtk_tree_selection_get_selected_rows( selection, &model );
// Begin at the end and go to the start
list=g_list_last(list);
while(list) {
GString *fixed_path = g_string_new("");
g_string_printf(fixed_path, "%s", gtk_tree_path_to_string((GtkTreePath*)list->data)/*ipath*/);
GtkTreePath *path = gtk_tree_path_new_from_string(fixed_path->str);
g_string_free(fixed_path, TRUE);
if (path) {
if ( gtk_tree_model_get_iter ( model, &iter, path) ) { // get iter from specified path
do_rename_iter(iter);
}
else { // invalid path
g_error(_("Error!!!\n"));
}
gtk_tree_path_free (path);
}
else {
g_error(_("Error!!!\n"));
}
list=list->prev;
}
g_list_foreach (list, (GFunc)gtk_tree_path_free, NULL);
g_list_free (list);
if (err) g_error_free(err);
if (dialog) gtk_widget_destroy(dialog);
}
/**
* Rename a group
*/
void popup_rename_group_cb()
{
GError *err = NULL;
// We can only rename groups!
if (!clicked_node.valid || clicked_node.type != ITEMTYPE_GROUP) {
goto EXITPOINT;
}
do_rename_iter(clicked_node.iter);
EXITPOINT:
// Destroying the dialog should also destroy the table, label, and entry widgets
if (err) g_error_free(err);
// Do NOT free newGroupName, since that is owned by the GtkEntry widget!
}
sciteproj-0.7.08/src/scite_utils.h 0000644 0001750 0001750 00000003114 12143703722 016447 0 ustar gusnan gusnan /**
* scite_utils_linux.h - Code for working with Scite (Linux version)
*
* Copyright 2006 Roy Wood, 2009-2011 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_SCITE_UTILS_
#define __HEADER_SCITE_UTILS_
//your declarations
extern gboolean scite_exists;
// Fork a child process and launch Scite from it
//gboolean launch_scite(gchar *sciteExecutableName, GError **err);
gboolean launch_scite(gchar *instring,GError **err);
// Send a command to Scite, launching Scite if necessary
gboolean send_scite_command(gchar *command, GError **err);
// Determine whether Scite is currently launched and the communication pipes are open
gboolean scite_ready();
// Activate the SciTE window (i.e. bring it the front)
gboolean activate_scite(GError **err);
gboolean check_if_scite_exists();
void init_scite_connection();
gboolean open_filename(gchar *filename,gchar *project_directory,GError **err);
#endif /*__HEADER_SCITE_UTILS_*/
sciteproj-0.7.08/src/drag_drop.c 0000644 0001750 0001750 00000046425 12143703722 016070 0 ustar gusnan gusnan /**
* drag_drop.c - Drag-and-drop support for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include "drag_drop.h"
#include "string_utils.h"
#include "tree_manipulation.h"
// #define DEBUG_DRAG_DROP
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_DRAGDROP_ERROR")
// Forward-declare static functions
static void global_coords_to_local(GtkTreeView* treeView, gint *x, gint *y);
static gboolean handle_local_drag_drop(TreeViewDragStruct *dragStruct, GtkTreePath *dropPath, enum NodePosition position);
/**
* Process Gtk drag-data-received events on the GtkTreeView. This gets uglier than I'd hoped....
*
*
* @param widget is the pointer to the drag target (should always be the GtkTreeView widget)
* @param drag_context is a pointer to the GdkDragContext object
* @param x is the x coordinate of the mouse in window coordinates (I think)
* @param y is the y coordinate of the mouse in window coordinates (I think)
* @param selection_data is the dropped data
* @param info is the data flavour as registered in the call to gtk_tree_view_enable_model_drag_dest()
* @param time is the timestamp for the event
* @param user_data is a pointer to the TreeViewDragStruct for the drag operation
*/
void drag_data_received_cb(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, gpointer user_data)
{
#ifdef __DEBUG_FOLDERS_DRAG_AND_DROP_
debug_printf("drag_data_received_cb\n");
#endif
TreeViewDragStruct *dragStruct = (TreeViewDragStruct *) user_data;
g_assert(drag_context != NULL);
g_assert(selection_data != NULL);
g_assert(dragStruct != NULL);
g_assert(dragStruct->treeView != NULL);
g_assert(dragStruct->treeStore != NULL);
g_assert(GTK_TREE_VIEW(widget) == dragStruct->treeView);
gchar **uriList = (gchar**)NULL;
GtkTreePath *dropPath = NULL;
GtkTreeIter dropIter;
gint nodeItemType;
gchar *nodeName = NULL;
GtkTreePath *dragPath = NULL;
GError *err = NULL;
enum NodePosition position = ADD_CHILD;
int i=0;
//static gchar *fileURI; // = (gchar*)"file://";
static int fileURILength; // = strlen(fileURI);
#ifdef DEBUG_DRAG_DROP
gchar *typeName = gdk_atom_name(selection_data->type);
g_print("%s: info = %d, type = '%s', data = '%s'\n", __func__, info, typeName, (gchar *) selection_data->data);
if (typeName) g_free(typeName);
#endif
// Filter the types of drop data we accept
if (!(info == DND_URI_TYPE || info == 0)) {
goto EXITPOINT;
}
// Get a GtkTreeIter that refers to the drop point in the tree, and figure out what type of node it is
global_coords_to_local(dragStruct->treeView, &x, &y);
if (gtk_tree_view_get_path_at_pos(dragStruct->treeView, x, y, &dropPath, NULL, NULL, NULL)) {
if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dragStruct->treeStore), &dropIter, dropPath)) {
goto EXITPOINT;
}
gtk_tree_model_get(GTK_TREE_MODEL(dragStruct->treeStore), &dropIter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &nodeName, -1);
#ifdef DEBUG_DRAG_DROP
g_print("%s: drop node = '%s'\n", __func__, nodeName);
#endif
}
// Figure out where to drop the data relative to the target node
if (dropPath == NULL) {
position = ADD_AFTER;
}
else if (dragStruct->dropPositionHint == GTK_TREE_VIEW_DROP_BEFORE) {
position = ADD_BEFORE;
}
else if (dragStruct->dropPositionHint == GTK_TREE_VIEW_DROP_AFTER) {
position = ADD_AFTER;
}
else if (nodeItemType == ITEMTYPE_FILE && dragStruct->dropPositionHint == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE) {
position = ADD_BEFORE;
}
else if (nodeItemType == ITEMTYPE_FILE && dragStruct->dropPositionHint == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) {
position = ADD_AFTER;
}
else {
position = ADD_CHILD;
}
// If the drag data originated locally, deal with it
if (dragStruct->isLocalDrag && dragStruct->dragNodes) {
handle_local_drag_drop(dragStruct, dropPath, position);
goto EXITPOINT;
}
// Drag originated externally, so parse all the received URIs and add them to the tree
if (!(uriList = gtk_selection_data_get_uris(selection_data))) {
goto EXITPOINT;
}
for (i = 0; uriList[i] != NULL; ++i) {
gchar *fileURI = (gchar*)"file://";
fileURILength = strlen(fileURI);
#ifdef DEBUG_DRAG_DROP
g_print("%s: checking drag/drop data '%s'\n", __func__, uriList[i]);
#endif
// If it doesn't start with "file://", then ignore it
if (!g_str_has_prefix(uriList[i], fileURI)) {
continue;
}
// Skip the "file://" prefix
gchar *filePath = uriList[i] + fileURILength;
// Add the data to the tree
GError *err = NULL;
// Append to a node, or to the root of the tree?
#ifdef DEBUG_DRAG_DROP
if (position == ADD_AFTER) g_print("%s: add_tree_file(ADD_AFTER)\n", __func__);
if (position == ADD_BEFORE) g_print("%s: add_tree_file(ADD_BEFORE)\n", __func__);
if (position == ADD_CHILD) g_print("%s: add_tree_file(ADD_CHILD)\n", __func__);
#endif
if (dropPath == NULL && i == 0) {
if (!add_tree_file(NULL, ADD_CHILD, filePath, &dropIter, TRUE, &err)) {
g_warning("%s: Could not add drag/drop data: %s\n", __func__, err->message);
}
}
else {
if (!add_tree_file(&dropIter, position, filePath, &dropIter, TRUE, &err)) {
g_warning("%s: Could not add drag/drop data: %s\n", __func__, err->message);
}
}
// Everything after the first dropped item is added as a sibling to preserve the drop order!
position = ADD_AFTER;
// Clean up the error message for the next pass around
if (err) g_error_free(err);
}
EXITPOINT:
if (dragStruct) {
dragStruct->isLocalDrag = FALSE;
if (dragStruct->dragNodes) {
for (i = 0; i < dragStruct->numDragNodes; ++i) {
if (dragStruct->dragNodes[i].nodePath) {
gtk_tree_path_free(dragStruct->dragNodes[i].nodePath);
}
}
g_free(dragStruct->dragNodes);
dragStruct->dragNodes = NULL;
}
}
if (dropPath) gtk_tree_path_free(dropPath);
if (dragPath) gtk_tree_path_free(dragPath);
if (uriList) g_strfreev(uriList);
if (nodeName) g_free(nodeName);
if (err) g_error_free(err);
}
/**
* Process Gtk drag-motion events on the GtkTreeView.
*
* @param widget is the pointer to the drag target (should always be the GtkTreeView widget)
* @param drag_context is a pointer to the GdkDragContext object
* @param x is the x coordinate of the mouse in window coordinates (I think)
* @param y is the y coordinate of the mouse in window coordinates (I think)
* @param time is the timestamp for the event
* @param user_data is a pointer to the TreeViewDragStruct for the drag operation
*/
gboolean drag_motion_cb(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data)
{
#ifdef __DEBUG_FOLDERS_DRAG_AND_DROP_
debug_printf("drag_motion_cb\n");
#endif
TreeViewDragStruct *dragStruct = (TreeViewDragStruct *) user_data;
g_assert(dragStruct != NULL);
g_assert(dragStruct->treeView != NULL);
g_assert(GTK_TREE_VIEW(widget) == dragStruct->treeView);
// Note the current drop position for use later when we receive the actual drag-data-received message
gtk_tree_view_get_drag_dest_row(dragStruct->treeView, NULL, &(dragStruct->dropPositionHint));
// Return FALSE to indicate that we do NOT take responsibility for this event, and the GtkTreeView should do its usual visual feedback work
return FALSE;
}
/**
* Process Gtk drag-data-get events on the GtkTreeView.
*
* @param widget is the pointer to the drag target (should always be the GtkTreeView widget)
* @param drag_context is a pointer to the GdkDragContext object
* @param selection_data is the dropped data
* @param info is the data flavour as registered in the call to gtk_tree_view_enable_model_drag_dest()
* @param time is the timestamp for the event
* @param user_data is a pointer to the TreeViewDragStruct for the drag operation
*/
void drag_data_get_cb(GtkWidget *widget, GdkDragContext *drag_context, GtkSelectionData *selection_data, guint info, guint time, gpointer user_data)
{
#ifdef __DEBUG_FOLDERS_DRAG_AND_DROP_
debug_printf("drag_data_get_cb\n");
#endif
TreeViewDragStruct *dragStruct = (TreeViewDragStruct *) user_data;
g_assert(dragStruct != NULL);
g_assert(dragStruct->treeView != NULL);
g_assert(dragStruct->treeStore != NULL);
g_assert(GTK_TREE_VIEW(widget) == dragStruct->treeView);
gchar *fileURI = NULL;
GError *err = NULL;
gchar** uriList = NULL;
GList* selectedNodeList = NULL;
GtkTreeSelection *treeSelection = NULL;
gint numSelectedRows;
gchar *nodeContentString = NULL;
TreeNodeStruct *nodeInfoPtr = NULL;
GList *selectionIter=NULL;
#ifdef DEBUG_DRAG_DROP
g_print("------------------------------\n");
#endif
// Get the currently-selected nodes, if possible
treeSelection = gtk_tree_view_get_selection(dragStruct->treeView);
selectedNodeList = gtk_tree_selection_get_selected_rows(treeSelection, NULL);
if (!selectedNodeList) {
goto EXITPOINT;
}
// We need to store the iters that refer to the nodes in the TreeViewDragStruct so drag_data_received_cb() can use it later
numSelectedRows = g_list_length(selectedNodeList);
#ifdef DEBUG_DRAG_DROP
g_print("%s: numSelectedRows = %d\n", __func__, numSelectedRows);
#endif
if (dragStruct->dragNodes) {
g_free(dragStruct->dragNodes);
dragStruct->dragNodes = NULL;
}
dragStruct->dragNodes = (TreeNodeStruct*) g_malloc(numSelectedRows * sizeof(TreeNodeStruct));
dragStruct->numDragNodes = 0;
// Iterate over all selected nodes, accumulating the list of URIs and populating dragStruct->dragNodes
nodeInfoPtr = dragStruct->dragNodes;
for (selectionIter = g_list_first(selectedNodeList); selectionIter != NULL; selectionIter = g_list_next(selectionIter)) {
GtkTreePath *path = NULL;
gint nodeItemType;
GtkTreeIter nodeIter;
// Get the iter to the next selected node
path = (GtkTreePath *) selectionIter->data;
if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(dragStruct->treeStore), &nodeIter, path)) {
continue;
}
// Free up the storage from the last pass
if (nodeContentString) {
g_free(nodeContentString);
nodeContentString = NULL;
}
// Get the data from the selected node
gtk_tree_model_get(GTK_TREE_MODEL(dragStruct->treeStore), &nodeIter, COLUMN_ITEMTYPE, &nodeItemType, COLUMN_FILEPATH, &nodeContentString, -1);
// Keep the node type, path, and iterator so drag_data_received_cb() can use it later
nodeInfoPtr->nodeItemType = nodeItemType;
nodeInfoPtr->nodeIter = nodeIter;
nodeInfoPtr->nodePath = path;
dragStruct->numDragNodes++;
nodeInfoPtr++;
#ifdef DEBUG_DRAG_DROP
g_print("%s: selected node = '%s'\n", __func__, nodeContentString);
#endif
// Format the node content (i.e. filepath) as a URI and append it to the list
if (fileURI != NULL && !str_append(&fileURI, "\n", &err)) {
g_warning("%s: Could not format drag/drop data: %s\n", __func__, err->message);
goto EXITPOINT;
}
if (!str_append(&fileURI, "file://", &err) || !str_append(&fileURI, nodeContentString, &err)) {
g_warning("%s: Could not format drag/drop data: %s\n", __func__, err->message);
goto EXITPOINT;
}
}
// Note that this drag originates locally
dragStruct->isLocalDrag = TRUE;
#ifdef DEBUG_DRAG_DROP
g_print("%s: data = '%s'\n\n", __func__, fileURI);
#endif
// Format and set the selection data as the list of URIs
uriList = g_strsplit(fileURI, "\n", -1);
if (!uriList || !gtk_selection_data_set_uris(selection_data, uriList)) {
g_warning("%s: Could not set drag/drop data\n", __func__);
}
EXITPOINT:
if (selectedNodeList) {
// We're actually using the individual paths, so don't free them!
// g_list_foreach(selectedNodeList, (GFunc) gtk_tree_path_free, NULL);
g_list_free(selectedNodeList);
}
if (fileURI) g_free(fileURI);
if (err) g_error_free(err);
if (uriList) g_strfreev(uriList);
if (nodeContentString) g_free(nodeContentString);
}
/**
* Convert global coordinates to local coordinates for a GtkTreeView.
*
* @param treeView is the GtkTreeView
* @param x is the x coordinate to be shifted
* @param y is the y coordinate to be shifted
*/
static void global_coords_to_local(GtkTreeView* treeView, gint *x, gint *y)
{
g_assert(treeView != NULL);
g_assert(x != NULL);
g_assert(y != NULL);
gint wx, wy;
GdkWindow* window = gtk_tree_view_get_bin_window(treeView);
if (window) {
gdk_window_get_position(window, &wx, &wy);
*x -= wx;
*y -= wy;
}
}
/**
* Handle a drag-and-drop operation that was initiated locally. This involves checking that dragged
* groups are not being dropped inside themselves, and also correctly handling files that are part
* of a dragged group.
*
* @return FALSE if errors occur; TRUE otherwise
*
* @param dragStruct is a pointer to the TreeViewDragStruct for the drag operation
* @param dropPath is the GtkTreePath referring to the drop point; if NULL, then the drag list is added to the root of the tree
* @param position is the location to drop the data, relative to the dropPath
*/
static gboolean handle_local_drag_drop(TreeViewDragStruct *dragStruct, GtkTreePath *dropPath, enum NodePosition position)
{
#ifdef __DEBUG_FOLDERS_DRAG_AND_DROP_
debug_printf("handle_local_drag_drop\n");
#endif
g_assert(dragStruct != NULL);
g_assert(dragStruct->treeView != NULL);
g_assert(dragStruct->treeStore != NULL);
gboolean finalResult = FALSE;
GtkTreeIter dropIter;
GError *err = NULL;
int i=0,j=0;
// If the drag data did not originate locally, don't do anything
if (!dragStruct->isLocalDrag || !dragStruct->dragNodes || dragStruct->numDragNodes <= 0) {
finalResult = TRUE;
goto EXITPOINT;
}
// Check to see if the drop point is a child of one of the drag nodes, and bail if so
if (dropPath != NULL) {
for (i = 0 ; i < dragStruct->numDragNodes; ++i) {
if (gtk_tree_path_is_descendant(dropPath,dragStruct->dragNodes[i].nodePath)) {
g_set_error(&err, APP_SCITEPROJ_ERROR, -1, "%s: Cannot drop a group node into itself", __func__);
goto EXITPOINT;
}
}
for (i = 0; i < dragStruct->numDragNodes; ++i) {
if (gtk_tree_path_compare(dropPath,dragStruct->dragNodes[i].nodePath)==0) {
//g_set_error(&err, APP_SCITEPROJ_ERROR, -1, "%s: Cannot drop a group node into itself", __func__);
goto EXITPOINT;
}
}
}
#ifdef DEBUG_DRAG_DROP
g_print("\n%s: Initial drag list:\n", __func__);
for (i = 0 ; i < dragStruct->numDragNodes; ++i) {
gchar *nodeName = NULL;
gtk_tree_model_get(GTK_TREE_MODEL(dragStruct->treeStore), &(dragStruct->dragNodes[i].nodeIter), COLUMN_FILEPATH, &nodeName, -1);
g_print("%02d: %s\n", i, nodeName);
g_free(nodeName);
}
g_print("\n");
#endif
// Now remove all children whose parents are also part of the drag list
for (i = 0 ; i < dragStruct->numDragNodes - 1; ++i) {
GtkTreePath *parentPath = dragStruct->dragNodes[i].nodePath;
for (j = i+1; j < dragStruct->numDragNodes; ++j) {
GtkTreePath *childPath = dragStruct->dragNodes[j].nodePath;
if (!gtk_tree_path_is_ancestor(parentPath, childPath)) {
continue;
}
#ifdef DEBUG_DRAG_DROP
g_print("%s: Drag item %d is a child of item %d; removing redundant node reference\n", __func__, j, i);
#endif
// It's a child of the parent, so remove it from the list
gtk_tree_path_free(childPath);
size_t numBytes = (dragStruct->numDragNodes - j) * sizeof(TreeNodeStruct);
if (numBytes > 0) {
g_memmove(&(dragStruct->dragNodes[j]), &(dragStruct->dragNodes[j+1]), numBytes);
}
dragStruct->numDragNodes -= 1;
--j;
}
}
#ifdef DEBUG_DRAG_DROP
g_print("\n%s: Final drag list:\n", __func__);
for (i = 0 ; i < dragStruct->numDragNodes; ++i) {
gchar *nodeName = NULL;
if (nodeName) g_free(nodeName);
gtk_tree_model_get(GTK_TREE_MODEL(dragStruct->treeStore), &(dragStruct->dragNodes[i].nodeIter), COLUMN_FILEPATH, &nodeName, -1);
g_print("%02d: %s\n", i, nodeName);
g_free(nodeName);
}
g_print("\n");
#endif
// We'll need the iter for the drop point
if (dropPath && !gtk_tree_model_get_iter(GTK_TREE_MODEL(dragStruct->treeStore), &dropIter, dropPath)) {
goto EXITPOINT;
}
// Finally, move the selected nodes
for (i = 0 ; i < dragStruct->numDragNodes; ++i) {
#ifdef DEBUG_DRAG_DROP
g_print("%s: Moving node #%d\n", __func__, i);
#endif
// Drop to the root of the tree?
if (dropPath == NULL && i == 0) {
if (!copy_tree_node(&(dragStruct->dragNodes[i].nodeIter), NULL, position, &dropIter, &err)) {
goto EXITPOINT;
}
}
else {
if (!copy_tree_node(&(dragStruct->dragNodes[i].nodeIter), &dropIter, position, &dropIter, &err)) {
goto EXITPOINT;
}
}
if (!remove_tree_node(&(dragStruct->dragNodes[i].nodeIter), &err)) {
goto EXITPOINT;
}
// Everything after the first dropped item is added as a sibling to preserve the drop order!
position = ADD_AFTER;
}
finalResult = TRUE;
EXITPOINT:
if (err != NULL) {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "An error occurred while moving the node(s): \n\n%s", err->message);
gtk_dialog_run(GTK_DIALOG (errDialog));
gtk_widget_destroy(errDialog);
}
if (err) g_error_free(err);
return finalResult;
}
/*
// Do I need to worry about this stuff?
if (GTK_IS_VIEWPORT(widget)) {
gdk_window_get_position(GTK_VIEWPORT(widget)->bin_window, &wx, &wy);
x -= wx;
y -= wy;
}
if (GTK_IS_LAYOUT(widget)) {
gdk_window_get_position(GTK_LAYOUT(widget)->bin_window, &wx, &wy);
x -= wx;
y -= wy;
}
*/
// Useful during debugging....
//~ switch (dragStruct->dropPositionHint) {
//~ case GTK_TREE_VIEW_DROP_BEFORE: {
//~ g_print("%s: %s, hint = DROP_BEFORE\n", __func__, dropNodeName);
//~ break;
//~ }
//~ case GTK_TREE_VIEW_DROP_AFTER: {
//~ g_print("%s: %s, hint = DROP_AFTER\n", __func__, dropNodeName);
//~ break;
//~ }
//~ case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: {
//~ g_print("%s: %s, hint = DROP_INTO_OR_BEFORE\n", __func__, dropNodeName);
//~ break;
//~ }
//~ case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: {
//~ g_print("%s: %s, hint = DROP_INTO_OR_AFTER\n", __func__, dropNodeName);
//~ break;
//~ }
//~ default: {
//~ g_print("%s: %s, hint = \n", __func__, dropNodeName);
//~ break;
//~ }
//~ }
//~ g_print(", drag_context->actions: ");
//~ if (drag_context->actions & GDK_ACTION_DEFAULT) g_print(" GDK_ACTION_DEFAULT");
//~ if (drag_context->actions & GDK_ACTION_COPY) g_print(" GDK_ACTION_COPY");
//~ if (drag_context->actions & GDK_ACTION_MOVE) g_print(" GDK_ACTION_MOVE\n");
//~ if (drag_context->actions & GDK_ACTION_LINK) g_print(" GDK_ACTION_LINK");
//~ if (drag_context->actions & GDK_ACTION_PRIVATE) g_print(" GDK_ACTION_PRIVATE");
//~ if (drag_context->actions & GDK_ACTION_ASK) g_print(" GDK_ACTION_ASK");
sciteproj-0.7.08/src/rename.h 0000644 0001750 0001750 00000002061 12143703722 015367 0 ustar gusnan gusnan /**
* rename.h - code for renaming a group for SciteProj
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_RENAME_
#define __HEADER_RENAME_
/**
*
*/
void popup_rename_group_cb();
void do_rename_node(gboolean ignore_clicked_node);
void do_rename_iter(GtkTreeIter iter);
void rename_cb(gchar *new_text, gchar *path_string,gpointer user_data);
#endif /*__HEADER_RENAME_*/
sciteproj-0.7.08/src/statusbar.h 0000644 0001750 0001750 00000001761 12143703722 016136 0 ustar gusnan gusnan /**
* statusbar.h - statusbar for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_STATUSBAR_
#define __HEADER_STATUSBAR_
gboolean init_statusbar(GtkWidget *grid,GtkWidget *next_to,GError **err);
void set_statusbar_text(const gchar *text);
void done_statusbar();
#endif /*__HEADER_STATUSBAR_*/
sciteproj-0.7.08/src/xml_processing.h 0000644 0001750 0001750 00000002307 12143703722 017157 0 ustar gusnan gusnan /**
* xml_processing.h - XML processing support for SciteProj
*
* Copyright 2006 Roy Wood, 2008-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_XML_PROCESSING_
#define __HEADER_XML_PROCESSING_
// Save the contents of a GtkTreeModel into a file
extern gboolean save_tree_XML(GtkTreeModel *treeModel, const gchar *filepath, GError **err);
// Load and parse an XML file, populating a GtkTreeStore with the data
extern gboolean load_parse_XML(GtkTreeStore *treeStore, const char *filePath, GError **err);
#endif /*__HEADER_XML_PROCESSING_*/
sciteproj-0.7.08/src/remove.h 0000644 0001750 0001750 00000001705 12143703722 015421 0 ustar gusnan gusnan /**
* remove.h - code for removing nodes
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj
*
* SciteProj is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj.
* If not, see .
*/
#ifndef __HEADER_REMOVE_
#define __HEADER_REMOVE_
void do_remove_node(gboolean ignore_clicked_node);
void popup_remove_node_cb();
void removeitem_menu_cb();
#endif /*__HEADER_REMOVE_*/
sciteproj-0.7.08/src/main.c 0000644 0001750 0001750 00000015653 12143703722 015052 0 ustar gusnan gusnan /**
* main.c - main for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include "clicked_node.h"
#include "gui.h"
#include "tree_manipulation.h"
#include "prefs.h"
#include "folder_to_xml.h"
#include "graphics.h"
#include "scite_utils.h"
#include "about.h"
#include "file_utils.h"
#include "string_utils.h"
static struct CommandLineIndata {
const gchar *scite_filename;
gchar *file_to_load;
} cmd;
/*
* Program main entry
*/
int main(int argc, char *argv[])
{
int returnCode = EXIT_FAILURE;
GError *err = NULL;
gchar *file_to_load=NULL;
GOptionContext *context=NULL;
static gboolean version=FALSE;
static gchar *scite_instance=NULL;
//static gboolean gene
static gchar *generate_xml_file=NULL;
static int max_depth_generated=-1;
static const GOptionEntry options[]={
{ "version", 'v', 0, G_OPTION_ARG_NONE, &version,
N_("Show program version and quit")},
{ "scite", 's', 0, G_OPTION_ARG_STRING, &scite_instance,
N_("Set a filename for the instance of SciTE to open"), N_("SCITE_FILENAME")},
{ "generate", 'g', 0, G_OPTION_ARG_STRING, &generate_xml_file,
N_("Generate a sciteproj project file with name XML_FILENAME, recursively from current folder"),
N_("XML_FILENAME")},
{ "max_depth", 'm', 0, G_OPTION_ARG_INT, &max_depth_generated,
N_("Set maximum depth of folders to read through to MAX_DEPTH when generating project file"),
N_("MAX_DEPTH")},
{ NULL }
};
// Init gettext stuff
setlocale(LC_ALL,"");
bindtextdomain(PACKAGE,LOCALEDIR);
bind_textdomain_codeset(PACKAGE,"");
textdomain(PACKAGE);
gchar *sciteproj_description=NULL;
sciteproj_description=g_strdup_printf(_("SciTE Project Manager"));
gchar *full_desc_string=g_strdup_printf("- %s",sciteproj_description);
context=g_option_context_new(full_desc_string);
g_option_context_add_main_entries(context,options,NULL);
if (!g_option_context_parse(context, &argc, &argv, &err)) {
g_print(_("option parsing failed: %s"),err->message);
printf("\n");
exit(EXIT_FAILURE);
}
g_free(sciteproj_description);
g_free(full_desc_string);
/*
Interpret the options
*/
/*
set instance of SciTE to run
*/
if (scite_instance) {
cmd.scite_filename=scite_instance;
}
/*
Generate a project file going down at max max_depth levels in the folder
hierarchy
*/
if (generate_xml_file) {
int max_depth=4;
if (max_depth_generated!=-1) max_depth=max_depth_generated;
//gboolean result=folder_to_xml(folder,filename,max_depth);
gboolean result=folder_to_xml(".",generate_xml_file,max_depth);
if (result) {
printf(_("Generated '%s' successfully!"),generate_xml_file);
printf("\n\n");
} else {
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
init_version_string();
/*
Show SciteProj version
*/
if (version) {
show_version();
printf("\n");
done_version_string();
exit(EXIT_SUCCESS);
}
// If there is any indata left - load it as a sciteproj project
if (argc>1)
cmd.file_to_load=g_strdup_printf("%s",argv[1]);
// Init gtk
gtk_init(&argc, &argv);
g_type_init();
init_file_utils();
// Init preferences
if (!init_prefs(&err)) {
g_print(_("Error initing preferences: %s"), err->message);
done_version_string();
return EXIT_FAILURE;
}
// check environment variable
gchar *scite_path_env=getenv("SciTE_HOME");
gchar *env_filename=NULL;
// test for scite
if (scite_path_env!=NULL) {
env_filename=g_build_filename(scite_path_env,"scite",NULL);
if (g_file_test(env_filename,G_FILE_TEST_EXISTS)) {
if (cmd.scite_filename==NULL) {
cmd.scite_filename=g_strdup(env_filename);
}
} else {
g_warning(_("Environment variable exists, but doesn't point to a folder containing scite."));
}
if (env_filename!=NULL) g_free(env_filename);
env_filename=g_build_filename(scite_path_env,"SciTE",NULL);
if (g_file_test(env_filename,G_FILE_TEST_EXISTS)) {
if (cmd.scite_filename==NULL) {
cmd.scite_filename=g_strdup(env_filename);
}
} else {
g_warning(_("Environment variable exists, but doesn't point to a folder containing scite."));
}
}
// do we have a custom scite executable string as command line option?
if (cmd.scite_filename!=NULL) {
// Does SciTE exist at that location?
if (g_file_test(cmd.scite_filename,G_FILE_TEST_IS_REGULAR)) {
// If we have already allocated memory for scite path, free it
if (gPrefs.scite_path!=NULL) g_free(gPrefs.scite_path);
// Set the new one
gPrefs.scite_path=g_strdup(cmd.scite_filename);
} else {
g_print(_("Couldn't find a SciTE executable named '%s'!\n"),cmd.scite_filename);
g_print(_("Checking for SciTE in the standard locations instead.\n"));
}
}
//g_option_context_free(context);
/*
* Any "used" options has been removed from the argv/argc array here.
*/
// Check for SciTE
if (!check_if_scite_exists()) {
GtkWidget *warningDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
_("Warning! Couldn't locate SciTE!\n"
"Program will start, but you won't be able to open SciTE to edit files."));
gtk_dialog_run(GTK_DIALOG(warningDialog));
gtk_widget_destroy(warningDialog);
}
// Set up the GUI
if (!setup_gui(&err)) {
g_print("Could not setup the gui: %s", err->message);
g_print("\n");
goto EXITPOINT;
}
file_to_load=NULL;
if (cmd.file_to_load!=NULL) {
file_to_load=cmd.file_to_load;
} else {
if (gPrefs.file_to_load!=NULL) file_to_load=gPrefs.file_to_load;
}
// Was a project file specified on the command line?
if (file_to_load!=NULL) {
if (!load_project(file_to_load, &err)) {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,_("An error occurred while trying to load the specified project file: %s"), err->message);
gtk_dialog_run(GTK_DIALOG(errDialog));
gtk_widget_destroy(errDialog);
g_error_free(err);
err = NULL;
}
}
if (cmd.file_to_load!=NULL) {
g_free(cmd.file_to_load);
cmd.file_to_load=NULL;
}
init_scite_connection();
// Run the app
gtk_main();
returnCode = EXIT_SUCCESS;
EXITPOINT:
gui_close();
done_prefs();
done_version_string();
if (err) g_error_free(err);
return returnCode;
}
sciteproj-0.7.08/src/clipboard.c 0000644 0001750 0001750 00000004222 12143703722 016053 0 ustar gusnan gusnan /**
* clipboard.c - clipboard code for SciteProj
*
* Copyright 2010-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include "clicked_node.h"
#include "gui.h"
#include "tree_manipulation.h"
#include "file_utils.h"
#include "string_utils.h"
#include "clipboard.h"
/**
* Copies the filename including full folder to the clipboard
*/
void copy_filename_to_clipboard(GtkTreeModel *model, GtkTreeIter *iter)
{
GError *err=NULL;
gchar *nodename=NULL;
gchar *filePath=NULL;
int nodeType=-1;
GdkDisplay *display=NULL;
GtkClipboard *clipboard=NULL;
gtk_tree_model_get(model, iter, COLUMN_FILENAME, &nodename, COLUMN_ITEMTYPE, &nodeType, COLUMN_FILEPATH, &filePath, -1);
gchar *absFilePath = NULL; //g_strdup_printf("%s",filePath);
// filePath is NULL?
//if (!relative_path_to_abs_path(sClickedNodeName, &absFilePath, get_project_directory(), &err)) {
if (!relative_path_to_abs_path(filePath, &absFilePath, get_project_directory(), &err)) {
goto EXITPOINT;
}
display=gdk_display_get_default();
clipboard=gtk_clipboard_get_for_display(display,GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text(clipboard,absFilePath,-1);
EXITPOINT:
if (err) g_error_free(err);
}
/**
* Callback for the menu item
*/
void copy_filename_to_clipboard_cb()
{
if (!clicked_node.valid || clicked_node.type != ITEMTYPE_FILE) {
//goto EXITPOINT;
} else {
copy_filename_to_clipboard(gtk_tree_view_get_model(GTK_TREE_VIEW(projectTreeView)),&(clicked_node.iter));
}
}
sciteproj-0.7.08/src/properties_dialog.h 0000644 0001750 0001750 00000002114 12143703722 017632 0 ustar gusnan gusnan /**
* properties_dialog.h - Properties Dialogs code for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_PROPERTIES_DIALOG_
#define __HEADER_PROPERTIES_DIALOG_
void group_properties_gui(GtkTreeModel *model,GtkTreeIter *iter);
void file_properties_gui(GtkTreeModel *model,GtkTreeIter *iter);
void group_properties_cb();
void file_properties_cb();
#endif /*__HEADER_PROPERTIES_DIALOG_*/
sciteproj-0.7.08/src/tree_manipulation.c 0000644 0001750 0001750 00000100244 12143703722 017634 0 ustar gusnan gusnan /**
* tree_manipulation.c - GtkTreeView manipulation code for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include "tree_manipulation.h"
#include "xml_processing.h"
#include "string_utils.h"
#include "graphics.h"
#include "prefs.h"
#include "clicked_node.h"
#include "gui.h"
#include "filelist.h"
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_TREEMANIPULATION_ERROR")
GtkTreeStore *sTreeStore = NULL;
static gboolean sProjectIsDirty = FALSE;
static gchar *sProjectFilepath = NULL;
static gchar *sProjectDir = NULL;
gchar *saved_file_folder=NULL;
// Predeclare static functions
gboolean add_tree_filelist(GtkTreeIter *parentIter, GSList *fileList, GError **err);
static gboolean set_project_filepath(const gchar *filepath, GError **err);
static gboolean make_paths_relative(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);
/**
* Set the project filepath
*
* @param filepath is the new project filepath
* @param err returns any error information
*/
static gboolean set_project_filepath(const gchar *filepath, GError **err)
{
gboolean finalResult = FALSE;
gchar *windowTitle = NULL;
// Clear old data
if (sProjectFilepath) g_free(sProjectFilepath);
sProjectFilepath = NULL;
if (sProjectDir) g_free(sProjectDir);
sProjectDir = NULL;
// Copy the filepath
sProjectFilepath = g_strdup(filepath);
// Extract the project's base directory
if (sProjectFilepath) {
gchar *finalSlash = NULL;
// Check for absolut path
if (g_path_is_absolute(sProjectFilepath)==TRUE) {
sProjectDir = g_strdup(sProjectFilepath);
}
else {
if (!relative_path_to_abs_path(sProjectFilepath, &sProjectDir, NULL, err)) {
goto EXITPOINT;
}
}
finalSlash = strrchr(sProjectDir, G_DIR_SEPARATOR);
if (finalSlash != NULL) {
*finalSlash = '\0';
};
}
windowTitle=g_strdup_printf("%s",get_filename_from_full_path(sProjectFilepath));
set_window_title(windowTitle);
finalResult = TRUE;
goto EXITPOINT;
EXITPOINT:
if (windowTitle) g_free(windowTitle);
return finalResult;
}
/**
*
*/
gchar *get_project_filepath()
{
return sProjectFilepath;
}
/**
* Get the project file directory.
*
* @return the project file's directory (pointer to static global-- do not modify!)
*/
const gchar* get_project_directory()
{
return sProjectDir;
}
/**
* Get the GTKTreeStore (evil, but necessary for setup_gui).
*
* @return the GtkTreeStore* for the project or NULL if a GtkTreeStore could not be allocate
*
* @param err returns any error information
*/
GtkTreeStore* create_treestore(GError **err)
{
if (sTreeStore == NULL) {
sTreeStore = gtk_tree_store_new(COLUMN_EOL, TYPE_ITEMTYPE, TYPE_FILEPATH, TYPE_FILENAME, TYPE_FILESIZE, TYPE_FONTWEIGHT, TYPE_FONTWEIGHTSET, TYPE_ICON, TYPE_EXPANDED);
if (sTreeStore == NULL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not create GtkTreeStore, gtk_tree_store_new() = NULL", __func__);
}
}
return sTreeStore;
}
/**
* Clear the GtkTreeStore.
*
* @param treeStore is the GtkTreeStore to add to
*/
void empty_tree(GtkTreeStore *treeStore)
{
g_assert(treeStore != NULL);
gtk_tree_store_clear(treeStore);
}
/**
* Set the project "dirty" status and update the sensitivity of the "Save Project" button
*
* @param isDirty is the new "dirty" status for the project
*/
void set_project_dirty_status(gboolean isDirty)
{
// Save the status
sProjectIsDirty = isDirty;
update_project_is_dirty(isDirty);
// Enable/disable the "Save Project" button as appropriate
set_save_button_sensitivity(sProjectIsDirty);
}
/**
* Get the "dirty" status of the project.
*
* @return TRUE if the project has been modified since loading; FALSE otherwise
*/
gboolean project_is_dirty()
{
return sProjectIsDirty;
}
/**
* If the current project is dirty, Prompt the user for a decision on whether to save it.
* Note that if the user declines to save (i.e. chooses "No"), the project is marked as clean.
*/
void prompt_user_to_save_project()
{
GtkWidget *dialog = NULL;
gint tempResponseID = GTK_RESPONSE_CANCEL;
// If the project is clean, things are simple
if (!project_is_dirty()) {
goto EXITPOINT;
}
// Project is dirty, so ask the user what to do about it
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "Save project changes?");
gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_YES, GTK_RESPONSE_YES);
gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_NO, GTK_RESPONSE_NO);
gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
tempResponseID = gtk_dialog_run(GTK_DIALOG(dialog));
if (tempResponseID == GTK_RESPONSE_CANCEL) {
goto EXITPOINT;
}
else if (tempResponseID == GTK_RESPONSE_NO) {
// Yikes-- discard changes!
set_project_dirty_status(FALSE);
}
else if (tempResponseID == GTK_RESPONSE_YES) {
GError *err = NULL;
GtkWidget *errDialog = NULL;
if (!save_project(get_project_filepath(),&err)) {
errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "An error occurred while saving the project: %s", err->message);
gtk_dialog_run(GTK_DIALOG(errDialog));
}
if (err) g_error_free(err);
if (errDialog) gtk_widget_destroy(errDialog);
}
EXITPOINT:
if (dialog) gtk_widget_destroy(dialog);
}
/**
* Save the project.
*
* @return FALSE if errors occurred during saving of the project; TRUE otherwise
*
* @param err returns any errors
*/
gboolean save_project(gchar *proj_filepath,GError **err)
{
GtkWidget *dialog = NULL;
gboolean finalResult = FALSE;
// If the project does not have a name, pick one
if (proj_filepath == NULL) {
gchar *filename = NULL;
GError *pathProcessErr = NULL;
int resultID;
dialog = gtk_file_chooser_dialog_new(_("Save Project"), NULL, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "untitled.xml");
resultID = gtk_dialog_run(GTK_DIALOG(dialog));
if (resultID != GTK_RESPONSE_ACCEPT) {
finalResult = TRUE;
goto EXITPOINT;
}
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
if (!set_project_filepath(filename, err)) {
goto EXITPOINT;
}
g_free(filename);
// Now that the project has a name, we have to make all the paths relative to it
gtk_tree_model_foreach(GTK_TREE_MODEL(sTreeStore), make_paths_relative, &pathProcessErr);
if (pathProcessErr) {
GtkWidget *errDialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("An error occurred while making project file paths relative: %s"), pathProcessErr->message);
gtk_dialog_run(GTK_DIALOG(errDialog));
gtk_widget_destroy(errDialog);
g_error_free(pathProcessErr);
goto EXITPOINT;
}
}
// Try and save the project
if (!save_tree_XML(GTK_TREE_MODEL(sTreeStore), sProjectFilepath, err)) {
goto EXITPOINT;
}
set_project_dirty_status(FALSE);
finalResult = TRUE;
EXITPOINT:
if (dialog) gtk_widget_destroy(dialog);
return finalResult;
}
/**
* Make a node's path relative to the current sProjectDir (assumes the node's current path is relative
* to the current working dir)
*
* @param model is the GtkTreeModel
* @param path is not used
* @param iter is the GtkTreeIter to the node to process
* @param data is a pointer to a GError in which any errors are returned
*/
static gboolean make_paths_relative(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
gboolean finalResult = FALSE;
GError **err = (GError **) data;
gchar *absPath = NULL;
gchar *origRelPath = NULL;
gchar *finalRelPath = NULL;
gint itemType;
// Get the node type and content
gtk_tree_model_get(model, iter, COLUMN_ITEMTYPE, &itemType, COLUMN_FILEPATH, &origRelPath, -1);
if (itemType == ITEMTYPE_FILE && origRelPath && origRelPath[0] != '\0') {
// The path is relative to the current working dir, so make it absolute
if (!relative_path_to_abs_path(origRelPath, &absPath, NULL, err)) {
finalResult = TRUE;
goto EXITPOINT;
}
// Now make it relative to sProjectDir
if (!abs_path_to_relative_path(absPath, &finalRelPath, sProjectDir, err)) {
finalResult = TRUE;
goto EXITPOINT;
}
// And stuff it back into the tree
gtk_tree_store_set(GTK_TREE_STORE(model), iter, COLUMN_FILEPATH, finalRelPath, -1);
}
EXITPOINT:
if (origRelPath) g_free(origRelPath);
if (absPath) g_free(absPath);
if (finalRelPath) g_free(finalRelPath);
return finalResult;
}
/**
* Load a specified file or display a file selection dialog to allow a user to open a project.
* If a current project is open and dirty, then first prompt the user to save or discard changes.
*
* @return FALSE if errors occurred during loading of the project; TRUE otherwise
*
* @param projectPath is a path to a project to load; if NULL, then a file selection dialog is displayed
* @param err returns any errors
*/
gboolean load_project(gchar *projectPath, GError **err)
{
GtkWidget *dialog = NULL;
gboolean finalResult = FALSE;
gchar *filepath = NULL;
GtkFileFilter* fileFilter = NULL;
// Ensure the current project is saved
prompt_user_to_save_project();
// Check if the file exists...
// --------
// --------
if (project_is_dirty()) {
finalResult = TRUE;
goto EXITPOINT;
}
if (projectPath != NULL) {
if (!load_parse_XML(sTreeStore, projectPath, err)) {
goto EXITPOINT;
}
// Keep the project filepath for later reference when saving
if (!set_project_filepath(projectPath, err)) {
goto EXITPOINT;
}
}
else {
// Pop up a file selection dialog and let the user choose a project file
dialog = gtk_file_chooser_dialog_new(_("Open Project"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
fileFilter = gtk_file_filter_new();
gtk_file_filter_set_name(fileFilter, _("Project Files (*.xml)"));
gtk_file_filter_add_pattern(fileFilter, "*.xml");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), fileFilter);
fileFilter = gtk_file_filter_new();
gtk_file_filter_set_name(fileFilter, _("All Files"));
gtk_file_filter_add_pattern(fileFilter, "*");
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), fileFilter);
if (gtk_dialog_run(GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT) {
finalResult = TRUE;
goto EXITPOINT;
}
filepath = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
if (!load_parse_XML(sTreeStore, filepath, err)) {
goto EXITPOINT;
}
// Keep the project filepath for later reference when saving
if (!set_project_filepath(filepath, err)) {
goto EXITPOINT;
}
}
set_project_dirty_status(FALSE);
finalResult = TRUE;
EXITPOINT:
if (dialog) gtk_widget_destroy(dialog);
if (filepath) g_free(filepath);
return finalResult;
}
/*
*
*/
void build_file_filter(int n, GtkFileFilter* fileFilter ) {
switch(n) {
case 0 :
gtk_file_filter_set_name(fileFilter, _("C/C++ Files"));
gtk_file_filter_add_pattern(fileFilter, "*.c");
gtk_file_filter_add_pattern(fileFilter, "*.cc");
gtk_file_filter_add_pattern(fileFilter, "*.cpp");
gtk_file_filter_add_pattern(fileFilter, "*.cxx");
gtk_file_filter_add_pattern(fileFilter, "*.C");
gtk_file_filter_add_pattern(fileFilter, "*.CC");
gtk_file_filter_add_pattern(fileFilter, "*.CPP");
gtk_file_filter_add_pattern(fileFilter, "*.CXX");
break;
case 1 :
gtk_file_filter_set_name(fileFilter, _("LAMP Script Files"));
gtk_file_filter_add_pattern(fileFilter, "*.pm");
gtk_file_filter_add_pattern(fileFilter, "*.pl");
gtk_file_filter_add_pattern(fileFilter, "*.py");
gtk_file_filter_add_pattern(fileFilter, "*.php*");
break;
case 2 :
gtk_file_filter_set_name(fileFilter, _("Java Files"));
gtk_file_filter_add_pattern(fileFilter, "*.java");
break;
case 3 :
gtk_file_filter_set_name(fileFilter, _("JavaScript Files"));
gtk_file_filter_add_pattern(fileFilter, "*.js");
break;
case 4 :
gtk_file_filter_set_name(fileFilter, _("HTML Files"));
gtk_file_filter_add_pattern(fileFilter, "*.html");
gtk_file_filter_add_pattern(fileFilter, "*.htm");
gtk_file_filter_add_pattern(fileFilter, "*.txt");
break;
default :
gtk_file_filter_set_name(fileFilter, _("All Files"));
gtk_file_filter_add_pattern(fileFilter, "*");
break;
}
return;
}
/**
* Display a file selection dialog to allow a user to add files to the current project.
*
* @return FALSE if errors occurred during loading of the project; TRUE otherwise
*
* @param parentIter is a pointer to the parent GtkTreeIter to add to, or NULL to add to the root of the tree
* @param wrongFiles returns number of files that errored due to name duplicates
* @param err returns any errors
*/
gboolean add_files_to_project(GtkTreeIter *parentIter, GError **err)
{
gboolean finalResult = FALSE;
GtkWidget *dialog = NULL;
gchar *filepath = NULL;
GtkFileFilter* fileFilter = NULL;
GSList *fileList = NULL;
int i=0;
gchar *result_string=NULL;
GSList *non_added_files=NULL;
GSList *files_to_add=NULL;
// Check if we have saved before
if (get_project_directory()==NULL) {
result_string=g_strdup_printf(_("You need to save the project before adding files."));
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s", result_string);
finalResult=FALSE;
goto EXITPOINT;
}
// Create the file selection dialog and add filters
dialog = gtk_file_chooser_dialog_new (_("Add Files"), NULL, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
if (saved_file_folder!=NULL) {
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), saved_file_folder);
}
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
// Select the choice from last time
if(1) {
fileFilter = gtk_file_filter_new();
build_file_filter(gPrefs.last_file_filter, fileFilter);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), fileFilter);
}
for(i=0; i<6;i++) {
fileFilter = gtk_file_filter_new();
build_file_filter(i, fileFilter);
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), fileFilter);
}
// Select the files
if (gtk_dialog_run(GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT) {
finalResult = TRUE;
goto EXITPOINT;
}
// Remember the choice, so that we can select it again
saved_file_folder=gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog));
// Process the list of chosen files
fileList = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
// Check for duplicates
GSList *listIter;
gchar *absFilename;
gchar *newfilename;
gchar *shortFileName;
// go through the list of files, check if they are already in the tree
for (listIter = fileList; listIter != NULL; listIter = g_slist_next(listIter)) {
absFilename = (gchar *) (listIter->data);
newfilename=g_strdup_printf("%s",absFilename);
shortFileName=get_filename_from_full_path(absFilename);
if ((tree_contains(shortFileName)) && (!gPrefs.allow_duplicates)) {
non_added_files=g_slist_prepend(non_added_files,newfilename);
} else {
files_to_add=g_slist_prepend(files_to_add,newfilename);
}
}
if (fileList) {
g_slist_foreach(fileList, (GFunc) g_free, NULL);
g_slist_free(fileList);
}
// actually add the filelist
if (files_to_add) {
if (!add_tree_filelist(parentIter, files_to_add, err)) {
goto EXITPOINT;
}
}
finalResult = TRUE;
EXITPOINT:
if (dialog) gtk_widget_destroy(dialog);
if (filepath) g_free(filepath);
// non_added_files list not empty?
if (non_added_files!=NULL) {
gchar *temp=NULL;
result_string=g_strdup_printf(_("\nThe following files:\n\n"));
int q=0;
for (listIter = non_added_files; listIter != NULL; listIter = g_slist_next(listIter)) {
gchar *tempstring = (gchar *) (listIter->data);
if (q<=10) {
temp=g_strdup_printf("%s%s\n",result_string,get_filename_from_full_path(tempstring));
g_free(result_string);
result_string=temp;
}
q++;
}
if (q>=10) {
temp=g_strdup_printf("%s...\n",result_string);
g_free(result_string);
result_string=temp;
}
temp=g_strdup_printf(_("%s\ncouldn't be added, because they were already present in the project.\n"),result_string);
g_free(result_string);
result_string=temp;
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s", result_string);
finalResult=FALSE;
}
if (files_to_add) {
g_slist_foreach(files_to_add, (GFunc) g_free, NULL);
g_slist_free(files_to_add);
}
// fix an error message
if (non_added_files) {
g_slist_foreach(non_added_files, (GFunc) g_free, NULL);
g_slist_free(non_added_files);
}
return finalResult;
}
/**
* Add a list of files to a GtkTreeStore.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param parentIter is a pointer to the parent GtkTreeIter to add to, or NULL to add to the root of the tree
* @param fileList is the list of files to add to the tree
* @param number_of_errors returns the number of files that couldn't be added due to duplicates
* @param err returns any errors
*/
gboolean add_tree_filelist(GtkTreeIter *parentIter, GSList *fileList, GError **err)
{
debug_printf("%s\n",__func__);
g_assert(sTreeStore != NULL);
g_assert(fileList != NULL);
gboolean finalResult = FALSE;
GtkTreeIter newIter;
GSList *listIter;
// Reverse the list
fileList=g_slist_reverse(fileList);
listIter = fileList;
for (listIter = fileList; listIter != NULL; listIter = g_slist_next(listIter)) {
gchar *absFilename = (gchar *) (listIter->data);
if (!absFilename) {
continue;
}
if (listIter == fileList) {
add_tree_file(parentIter, ADD_CHILD, absFilename, &newIter, TRUE, err);
}
else {
add_tree_file(&newIter, ADD_AFTER, absFilename, &newIter, TRUE, err);
}
}
finalResult = TRUE;
return finalResult;
}
/**
* Add a group node to an existing parent node, or to the root of the GtkTreeStore.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param parentIter is a pointer to the parent GtkTreeIter to add to, or NULL to add to the root of the tree
* @param position indicates the relative position to add the file node
* @param newIter returns the new GtkTreeIter (pass NULL if this result is not needed)
* @param groupname is the name of the group to add to the tree
* @param err returns any errors
*/
gboolean add_tree_group(GtkTreeIter *parentIter, enum NodePosition position, const gchar* groupname, gboolean expanded,GtkTreeIter *newIter, GError **err)
{
g_assert(sTreeStore != NULL);
g_assert(groupname != NULL);
gboolean finalResult = FALSE;
GtkTreeIter iter;
// Append to root, or before/after/within an existing node?
// swap before and after
if (parentIter == NULL) {
gtk_tree_store_insert_before(sTreeStore, &iter, NULL, NULL);
}
else if (position == ADD_BEFORE) {
gtk_tree_store_insert_before(sTreeStore, &iter, NULL, parentIter);
}
else if (position == ADD_AFTER) {
gtk_tree_store_insert_after(sTreeStore, &iter, NULL, parentIter);
}
else if (position == ADD_CHILD) {
gtk_tree_store_insert(sTreeStore,&iter,parentIter,1000);
}
if (newIter) {
*newIter = iter;
}
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ITEMTYPE, ITEMTYPE_GROUP, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_FILENAME, groupname, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_FILEPATH, groupname, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_FONTWEIGHT, PANGO_WEIGHT_BOLD, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_FONTWEIGHTSET, TRUE, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ICON, directory_closed_pixbuf, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_EXPANDED, expanded, -1);
set_project_dirty_status(TRUE);
finalResult = TRUE;
return finalResult;
}
/**
* Add a file node to an existing parent node, or to the root of the GtkTreeStore.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param currentIter is a pointer to the parent GtkTreeIter to add to, or NULL to add to the root of the tree
* @param position indicates the relative position to add the file node
* @param filepath is the filepath to add to the tree
* @param newIter returns the GtkTreeIter that refers to the new node
* @param makeRelative indicates whether the filepath should be converted to a relative path before being added to the tree
* @param err returns any errors
*/
gboolean add_tree_file(GtkTreeIter *currentIter, enum NodePosition position, const gchar* filepath, GtkTreeIter *newIter, gboolean makeRelative, GError **err)
{
g_assert(sTreeStore != NULL);
g_assert(filepath != NULL);
g_assert(position == ADD_BEFORE || position == ADD_AFTER || position == ADD_CHILD);
gboolean finalResult = FALSE;
GtkTreeIter iter;
const gchar* fileName = NULL;
gchar *relFilename = NULL;
gchar *fileExt=NULL;
relFilename = NULL; //g_strdup(filepath);
if (!makeRelative) {
relFilename = g_strdup(filepath);
}
else if (!abs_path_to_relative_path(filepath, &relFilename, sProjectDir, err)) {
printf("abs_path_to_relative_path FAILED!\n");
goto EXITPOINT;
}
// Extract filename from filepath
fileName = get_filename_from_full_path((gchar*)filepath);
add_item((gchar*)fileName,(gchar*)relFilename);
// Append to root, or before/after/within an existing node?
if (currentIter == NULL) {
gtk_tree_store_insert_before(sTreeStore, &iter, NULL, NULL);
}
else if (position == ADD_BEFORE) {
gtk_tree_store_insert_before(sTreeStore, &iter, NULL, currentIter);
}
else if (position == ADD_AFTER) {
gtk_tree_store_insert_after(sTreeStore, &iter, NULL, currentIter);
}
else if (position == ADD_CHILD) {
gtk_tree_store_insert(sTreeStore,&iter,currentIter,1000);
}
fileExt=strrchr(fileName,'.');
if (fileExt!=NULL) {
++fileExt;
}
if (fileExt == NULL || strlen(fileExt) <= 0) {
fileExt=(gchar*)fileName;
}
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ITEMTYPE, ITEMTYPE_FILE, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_FILEPATH, relFilename, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_FILENAME, fileName, -1);
gtk_tree_store_set(sTreeStore, &iter, COLUMN_EXPANDED, FALSE, -1);
if (
(strcmp(fileExt,"cc")==0) ||
(strcmp(fileExt,"c++")==0) ||
(strcmp(fileExt,"c")==0) ||
(strcmp(fileExt,"cpp")==0)
) {
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ICON, cpp_file_pixbuf, -1);
} else if (
(strcmp(fileExt,"hh")==0) ||
(strcmp(fileExt,"h++")==0) ||
(strcmp(fileExt,"h")==0) ||
(strcmp(fileExt,"hpp")==0)
) {
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ICON, header_file_pixbuf, -1);
} else if (
(strcmp(fileExt,"lua")==0)
) {
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ICON, lua_file_pixbuf, -1);
} else if (
(strcmp(fileExt,"java")==0)
) {
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ICON, java_file_pixbuf, -1);
} else {
gtk_tree_store_set(sTreeStore, &iter, COLUMN_ICON, txt_file_pixbuf, -1);
}
if (newIter) {
*newIter = iter;
}
set_project_dirty_status(TRUE);
finalResult = TRUE;
EXITPOINT:
if (relFilename) g_free(relFilename);
return finalResult;
}
/**
*
*/
void helper_remove(GtkTreeIter *iter)
{
GtkTreeIter *tempIter=gtk_tree_iter_copy(iter);
GtkTreeIter newIter;
if (gtk_tree_model_iter_children(GTK_TREE_MODEL(sTreeStore),&newIter,tempIter)) {
gboolean next_valid=TRUE;
do {
if (next_valid) {
gchar *nodeContents;
int itemType;
gtk_tree_model_get(GTK_TREE_MODEL(sTreeStore), &newIter, COLUMN_ITEMTYPE, &itemType, COLUMN_FILEPATH, &nodeContents, -1);
gchar *fileName = get_filename_from_full_path((gchar*)nodeContents);
if (itemType==ITEMTYPE_GROUP) {
helper_remove(&newIter);
} else {
//printf("Removed: %s, %s\n",fileName,nodeContents);
remove_item(fileName,nodeContents);
}
}
next_valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(sTreeStore),&newIter);
} while(next_valid);
}
}
/**
* Remove a node from the GtkTreeStore.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param iter references the node to remove
* @param err returns any errors
*/
extern gboolean remove_tree_node(GtkTreeIter *iter, GError **err)
{
gchar *file_path;
int itemType;
// Get the node type and content
gtk_tree_model_get(GTK_TREE_MODEL(sTreeStore), iter, COLUMN_ITEMTYPE, &itemType, COLUMN_FILEPATH, &file_path, -1);
if (itemType==ITEMTYPE_GROUP) {
helper_remove(iter);
} else {
gchar *fileName = get_filename_from_full_path((gchar*)file_path);
remove_item(fileName,file_path);
}
gtk_tree_store_remove(sTreeStore, iter);
set_project_dirty_status(TRUE);
return TRUE;
}
/**
* Set the contents of a node. (Should only be used for directories, and not for
* adding files)
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param iter is a reference to the node to change
* @param newContents is the new content for the node
* @param err returns any errors
*/
gboolean set_tree_node_name(GtkTreeIter *iter, const gchar *newContents, GError **err)
{
g_assert(iter != NULL);
g_assert(newContents != NULL);
// What is saved on disk
gtk_tree_store_set(sTreeStore, iter, COLUMN_FILEPATH, newContents, -1);
// What is visible in gui
gtk_tree_store_set(sTreeStore, iter, COLUMN_FILENAME, newContents, -1);
set_project_dirty_status(TRUE);
return TRUE;
}
/**
* Set the icon of a node
*
* @return TRUE on success, FALSE on error
*
* @param iter is a reference to the node who's icon we want to change
* @param pixbuf is the pixbuf we want as icon
* @param err to return any error details
*
*/
gboolean set_tree_node_icon(GtkTreeIter *iter, GdkPixbuf *pixbuf, GError **err)
{
g_assert(iter != NULL);
g_assert(pixbuf != NULL);
/* What is saved on disk */
gtk_tree_store_set(sTreeStore, iter, COLUMN_ICON, pixbuf, -1);
g_object_ref(pixbuf);
return TRUE;
}
/**
* set_tree_node_expanded
*/
gboolean set_tree_node_expanded(GtkTreeIter *iter, gboolean expanded, GError **err)
{
g_assert(iter != NULL);
gtk_tree_store_set(sTreeStore, iter, COLUMN_EXPANDED, expanded, -1);
if (gPrefs.dirty_on_folder_change) {
set_project_dirty_status(TRUE);
}
return TRUE;
}
/**
* Copy a node (and children) within the tree.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param srcIter is a reference to the node to move
* @param dstIter is a reference to the destination node; NULL if the root of the tree
* @param newIter returns the iter of the copy
* @param position indicates where copy the node, relative to srcIter
* @param err returns any errors
*/
gboolean copy_tree_node(GtkTreeIter *srcIter, GtkTreeIter *dstIter, enum NodePosition position, GtkTreeIter *newIter, GError **err)
{
g_assert(srcIter != NULL);
g_assert(position == ADD_BEFORE || position == ADD_AFTER || position == ADD_CHILD);
gchar *nodeContents = NULL;
gboolean finalResult = FALSE;
gint itemType;
GtkTreeIter srcChildIter;
GtkTreeIter dstChildIter;
GtkTreePath *srcPath = NULL;
GtkTreePath *newPath = NULL;
gboolean groupIsExpanded = FALSE;
GtkTreeIter newGroupIter;
// Get the node type and content
gtk_tree_model_get(GTK_TREE_MODEL(sTreeStore), srcIter, COLUMN_ITEMTYPE, &itemType, COLUMN_FILEPATH, &nodeContents, -1);
// Add a file or group?
if (itemType == ITEMTYPE_FILE) {
if (!add_tree_file(dstIter, position, nodeContents, newIter, FALSE, err)) {
goto EXITPOINT;
}
}
else {
// Is the source group currently expanded?
srcPath = gtk_tree_model_get_path(GTK_TREE_MODEL(sTreeStore), srcIter);
groupIsExpanded = tree_row_is_expanded(srcPath);
// Add the copy of the group
if (!add_tree_group(dstIter, position, nodeContents, groupIsExpanded, &newGroupIter, err)) {
goto EXITPOINT;
}
if (newIter) {
*newIter = newGroupIter;
}
// Recursively copy the group's contents, too
if (gtk_tree_model_iter_children(GTK_TREE_MODEL(sTreeStore), &srcChildIter, srcIter)) {
// Copy the first child as ADD_CHILD
if (!copy_tree_node(&srcChildIter, &newGroupIter, ADD_CHILD, &dstChildIter, err)) {
goto EXITPOINT;
}
// Copy each subsequent child ADD_AFTER its prior sibling
while (gtk_tree_model_iter_next(GTK_TREE_MODEL(sTreeStore), &srcChildIter)) {
if (!copy_tree_node(&srcChildIter, &dstChildIter, ADD_AFTER, &dstChildIter, err)) {
goto EXITPOINT;
}
}
}
// Expand the new group?
if (groupIsExpanded) {
newPath = gtk_tree_model_get_path(GTK_TREE_MODEL(sTreeStore), &newGroupIter);
expand_tree_row(newPath, FALSE);
}
}
set_project_dirty_status(TRUE);
finalResult = TRUE;
EXITPOINT:
if (nodeContents) g_free(nodeContents);
if (srcPath) gtk_tree_path_free(srcPath);
if (newPath) gtk_tree_path_free(newPath);
return finalResult;
}
/**
*
*/
gchar *get_path_string(GtkTreeIter *iter)
{
GtkTreePath *treePath=gtk_tree_model_get_path(GTK_TREE_MODEL(sTreeStore),iter);
gchar *buf;
buf=g_strdup_printf("%s",gtk_tree_path_to_string(treePath));
return buf;
}
/**
*
*/
gint compare_strings_bigger(gconstpointer a,gconstpointer b)
{
const gchar *test1=get_filename_from_full_path((gchar*)a);
const gchar *test2=get_filename_from_full_path((gchar*)b);
return g_ascii_strcasecmp(test1,test2);
}
/**
*
*/
gint compare_strings_smaller(gconstpointer a,gconstpointer b)
{
const gchar *test1=get_filename_from_full_path((gchar*)a);
const gchar *test2=get_filename_from_full_path((gchar*)b);
return g_ascii_strcasecmp(test2,test1);
}
/**
*
*/
void sort_children(GtkTreeIter *node,GError **err,StringCompareFunction compare_func)
{
GtkTreeIter *saved_iter=node;
GtkTreeIter childIter;
GtkTreeModel *tree_model=GTK_TREE_MODEL(sTreeStore);
gint nodeType=-1;
GSList *itemList=NULL;
if (gtk_tree_model_iter_children(tree_model,&childIter,node)) {
int q=gtk_tree_model_iter_n_children(tree_model,node);
while (q>0) {
gchar *nodeContents;
gtk_tree_model_get(tree_model, &childIter, COLUMN_ITEMTYPE, &nodeType, COLUMN_FILEPATH, &nodeContents, -1);
if (nodeType==ITEMTYPE_FILE) {
gchar *newAbsPath=NULL;
relative_path_to_abs_path(nodeContents,&newAbsPath,get_project_directory(),err);
if (itemList==NULL) {
itemList=g_slist_append(itemList,newAbsPath);
} else {
itemList=g_slist_insert_sorted(itemList,newAbsPath,compare_func);
}
gtk_tree_store_remove(sTreeStore,&childIter);
} else {
gtk_tree_model_iter_next(tree_model,&childIter);
}
q--;
}
}
if (itemList!=NULL)
add_tree_filelist(saved_iter,itemList, err);
GtkTreePath *path=gtk_tree_model_get_path(tree_model,saved_iter);
expand_tree_row(path,TRUE);
}
/*
*
*/
struct TestStruct
{
gchar *string_to_check_for;
gboolean found;
};
typedef struct TestStruct TestStruct;
/**
*
*/
gboolean foreach_finder(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
gint nodeType=-1;
gchar *node_contents;
gtk_tree_model_get(model, iter, COLUMN_ITEMTYPE, &nodeType, COLUMN_FILENAME, &node_contents, -1);
TestStruct *test=(TestStruct*)(data);
gboolean res=FALSE;
if (g_ascii_strcasecmp(node_contents,test->string_to_check_for)==0) {
test->found=TRUE;
res=TRUE;
}
g_free(node_contents);
return res;
}
/**
*
*/
gboolean tree_contains(gchar *test_string)
{
TestStruct test;
test.string_to_check_for=test_string;
test.found=FALSE;
gtk_tree_model_foreach(GTK_TREE_MODEL(sTreeStore),foreach_finder,(gpointer)(&test));
return test.found;
}
sciteproj-0.7.08/src/xml_processing.c 0000644 0001750 0001750 00000036526 12143703722 017164 0 ustar gusnan gusnan /**
* xml_processing.c - XML processing support for SciteProj
*
* Copyright 2006 Roy Wood, 2008-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include "xml_processing.h"
#include "string_utils.h"
#include "tree_manipulation.h"
#include "clicked_node.h"
#include "gui.h"
#include "file_utils.h"
#include "prefs.h"
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_XML_ERROR")
/*
* This module loads or saves an xml file, marshalling or unmarshalling data to/from a GtkTreeStore,
* including adding nodes to the tree.
* The xml file is assumed to consist of elements and/or elements.
* The pathnames of the files are contained in the text of the elements, and the name of
* the group elements are contained in a "name" attribute of the element.
*/
/*
* Forward declare the static functions in the module
*/
static void start_element_cb(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error);
static void end_element_cb(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error);
static void text_cb(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error);
static void passthrough_cb(GMarkupParseContext *context, const gchar *passthrough_text, gsize text_len, gpointer user_data, GError **error);
static void error_cb(GMarkupParseContext *context, GError *error, gpointer user_data);
static gboolean marshal_subtree(GtkTreeModel *treeModel, GtkTreeIter *currentIter, gchar **xmlString, GError **err);
/*
* ParseStruct is used to store the state of a parsing operation
*/
struct ParseStruct {
GtkTreeIter currentIter; // reference to the current group node
int depth; // depth of parse
gboolean inFileElement; // flag indicating whether we are processing a file node
GtkTreeStore *treeStore; // pointer to the GtkTreeStore we are populating
gboolean valid_file;
};
typedef struct ParseStruct ParseStruct;
GtkTreeIter prevFileIterArray[100];
int currentPrevFileIter=0;
gboolean prevFileIterValid[100];
/**
* Handle the start of an element during parsing.
*
* @param context is the parse context
* @param element_name is the name of the node being closed
* @param attribute_names is the list of attribute names
* @param attribute_values is the list of attribute values
* @param user_data is a pointer to the ParseStruct struct used to store state info during parsing
* @param error is the error object
*/
static void start_element_cb(GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error)
{
ParseStruct *parseStruct = (ParseStruct *) user_data;
int i=0;
g_assert(parseStruct != NULL);
g_assert(parseStruct->treeStore != NULL);
gboolean expanded=FALSE;
if (strcmp(element_name,"root")==0) {
for (i=0;attribute_names[i]!=NULL;++i) {
if (strcmp(attribute_names[i],"identifier")==0) {
if (strcmp(attribute_values[i],"sciteproj project file")==0) {
parseStruct->valid_file=TRUE;
}
}
}
} else if (strcmp(element_name, "group") == 0) {
// Is it a "group" element?
// Extract the "name" or "is_expanded" attribute, if they exist
const gchar *groupname = "";
for (i = 0; attribute_names[i] != NULL; ++i) {
if (strcmp(attribute_names[i], "name") == 0) {
groupname = attribute_values[i];
}
else if (strcmp(attribute_names[i], "expanded") == 0) {
if (strcmp(attribute_values[i], "TRUE") == 0 || strcmp(attribute_values[i], "true") == 0) {
expanded = TRUE;
}
}
}
// Add to the root of the tree, or as a child of an existing group?
if (parseStruct->depth <= 0) {
add_tree_group(NULL, ADD_CHILD, groupname, expanded, &(parseStruct->currentIter), error);
set_tree_node_expanded(&(parseStruct->currentIter),expanded,error);
prevFileIterValid[currentPrevFileIter]=FALSE;
prevFileIterArray[currentPrevFileIter]=parseStruct->currentIter;
currentPrevFileIter++;
prevFileIterArray[currentPrevFileIter]=parseStruct->currentIter;
}
else {
add_tree_group(&(parseStruct->currentIter), ADD_CHILD, groupname, expanded, &(parseStruct->currentIter), error);
set_tree_node_expanded(&(parseStruct->currentIter),expanded,error);
prevFileIterValid[currentPrevFileIter]=FALSE;
prevFileIterArray[currentPrevFileIter]=parseStruct->currentIter;
currentPrevFileIter++;
prevFileIterValid[currentPrevFileIter]=prevFileIterValid[currentPrevFileIter];
}
// Increment the depth
parseStruct->depth++;
// Note that prevFileIter is not valid
prevFileIterValid[currentPrevFileIter]=FALSE;
}
else if (strcmp(element_name, "file") == 0) {
// Note that we're now in a file element, so text_cb() will extract and use subsequent text
parseStruct->inFileElement = TRUE;
}
}
/**
* Handle the end of an element during parsing.
*
* @param context is the parse context
* @param element_name is the name of the node being closed
* @param user_data is a pointer to the ParseStruct struct used to store state info during parsing
* @param error is the error object
*/
static void end_element_cb(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error)
{
ParseStruct *parseStruct = (ParseStruct *) user_data;
g_assert(parseStruct != NULL);
g_assert(parseStruct->treeStore != NULL);
if (strcmp(element_name, "group") == 0) {
// End of a group node, so decrement the depth and step back up the tree one level
if (currentPrevFileIter>0) currentPrevFileIter--;
if (parseStruct->depth > 0) {
GtkTreeIter parentIter;
GtkTreeIter tempIter=prevFileIterArray[currentPrevFileIter]; //parseStruct->currentIter;
// Sets parentIter to the parent of tempIter if it returns TRUE, otherwise
if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(parseStruct->treeStore), &parentIter, &(tempIter))) {
parseStruct->currentIter = parentIter;
if (parseStruct->depth>0) parseStruct->depth -= 1;
} else {
parseStruct->currentIter = tempIter;
if (parseStruct->depth>0) parseStruct->depth -= 1;
}
}
}
else if (strcmp(element_name, "file") == 0) {
parseStruct->inFileElement = FALSE;
}
}
/**
* Handle text of an element data during parsing.
*
* @param context is the parse context
* @param passthrough_text is the passthrough data (comments, etc.)
* @param text_len is the length of the passthrough data
* @param user_data is a pointer to the ParseStruct struct used to store state info during parsing
* @param error is the error object
*/
static void text_cb(GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error)
{
ParseStruct *parseStruct = (ParseStruct *) user_data;
g_assert(parseStruct != NULL);
g_assert(parseStruct->treeStore != NULL);
if (text == NULL || strlen(text) <= 0 || text[0] == '\n' || !parseStruct->inFileElement) {
return;
}
// Append to root or an existing node?
if (parseStruct->depth <= 0) {
if (prevFileIterValid[currentPrevFileIter]) {
add_tree_file(&(prevFileIterArray[currentPrevFileIter]), ADD_AFTER, text, &(prevFileIterArray[currentPrevFileIter]), FALSE, error);
} else {
add_tree_file(NULL, ADD_CHILD, text, &(prevFileIterArray[currentPrevFileIter]), FALSE, error);
}
} else {
if (prevFileIterValid[currentPrevFileIter]) {
add_tree_file(&(prevFileIterArray[currentPrevFileIter]), ADD_AFTER, text, &(prevFileIterArray[currentPrevFileIter]), FALSE, error);
} else {
add_tree_file(&(parseStruct->currentIter), ADD_CHILD,text, &(prevFileIterArray[currentPrevFileIter]), FALSE, error);
}
}
prevFileIterValid[currentPrevFileIter]=TRUE;
}
/**
* Handle passthrough data during parsing.
*
* @param context is the parse context
* @param passthrough_text is the passthrough data (comments, etc.)
* @param text_len is the length of the passthrough data
* @param user_data is a pointer to the ParseStruct struct used to store state info during parsing
* @param error is the error object
*/
static void passthrough_cb(GMarkupParseContext *context, const gchar *passthrough_text, gsize text_len, gpointer user_data, GError **error)
{
// Don't care right now....
}
/**
* Handle errors during parsing.
*
* @param context is the parse context
* @param error is the error object
* @param user_data is a pointer to the ParseStruct struct used to store state info during parsing
*/
static void error_cb(GMarkupParseContext *context, GError *error, gpointer user_data)
{
// Don't care right now....
}
/**
*
*/
gboolean for_each_open_close_function(GtkTreeModel *model,GtkTreePath *path,GtkTreeIter *iter,gpointer data)
{
gchar *filename=NULL;
gboolean expanded;
gtk_tree_model_get(model, iter, COLUMN_FILEPATH, &filename, COLUMN_EXPANDED, &expanded, -1);
if (path != NULL) {
if (expanded) {
expand_tree_row(path, TRUE);
} else {
collapse_tree_row(path);
}
}
if (filename!=NULL) g_free(filename);
return FALSE;
}
/**
* Parse an XML file and populate a GtkTreeStore with the extracted data.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param treeStore is the GtkTreeStore to populate
* @param filepath is the path to the file to read and parse
* @param err returns any errors
*/
gboolean load_parse_XML(GtkTreeStore *treeStore, const char *filepath, GError **err)
{
g_assert(treeStore != NULL);
g_assert(filepath != NULL);
gboolean finalResult = FALSE;
GMarkupParseContext *parseContext = NULL;
GMarkupParser parser = { start_element_cb, end_element_cb, text_cb, passthrough_cb, error_cb };
gsize xmlSize = 0;
gchar *xml = NULL;
ParseStruct parseStruct;
// Read in the file
if (!g_file_get_contents(filepath, &xml, &xmlSize, err)) {
goto EXITPOINT;
}
// Clear any data that might already be in the tree
gtk_tree_store_clear(treeStore);
// Create an XML parser
parseStruct.depth = 0;
parseStruct.inFileElement = FALSE;
parseStruct.treeStore = treeStore;
parseStruct.valid_file=FALSE;
parseContext = g_markup_parse_context_new(&parser, (GMarkupParseFlags) 0, &parseStruct, NULL);
// Parse the data....
if (!g_markup_parse_context_parse(parseContext, (char *) xml, xmlSize, err)) {
goto EXITPOINT;
}
if (!parseStruct.valid_file) {
if (gPrefs.identify_sciteproj_xml) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, _("%s: Not a valid sciteproj XML file!"), __func__);
goto EXITPOINT;
}
}
// Check Open/Closed?
gtk_tree_model_foreach(GTK_TREE_MODEL(treeStore),for_each_open_close_function,&parseStruct);
finalResult = TRUE;
EXITPOINT:
if (parseContext) g_markup_parse_context_free(parseContext);
if (xml) g_free(xml);
if (!finalResult) {
// A parsing error occurred, so junk it all
gtk_tree_store_clear(treeStore);
}
return finalResult;
}
/**
* Marshal a subtree of a GtkTreeModel by appending its textual representation to an input string.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param treeModel is the GtkTreeModel
* @param subtreeIter is the iterator reference to the subtree to process
* @param xmlString returns the marshaled output; the text is appended to this string
* @param err returns any errors
*/
static gboolean marshal_subtree(GtkTreeModel *treeModel, GtkTreeIter *subtreeIter, gchar **xmlString, GError **err)
{
g_assert(treeModel != NULL);
g_assert(subtreeIter != NULL);
g_assert(xmlString != NULL);
gboolean finalResult = FALSE;
gint itemType;
gchar *filepathString = NULL;
gchar *tmpXML = NULL;
gchar *indentString = NULL;
gint depth;
gboolean expanded=FALSE;
// Set up indent
depth = gtk_tree_store_iter_depth(GTK_TREE_STORE(treeModel), subtreeIter) + 1;
indentString = g_strnfill(depth, '\t');
// Get relevant data for current node
gchar *temp=NULL;
gtk_tree_model_get(treeModel, subtreeIter,
COLUMN_FILEPATH, &temp,
COLUMN_ITEMTYPE, &itemType,
-1);
filepathString=fix_separators(temp);
g_free(temp);
if (itemType == ITEMTYPE_FILE) {
// Write out a simple file node
tmpXML = g_markup_printf_escaped("%s%s\n", indentString, filepathString);
if (!str_append(xmlString, tmpXML, err)) {
goto EXITPOINT;
}
}
else if (itemType == ITEMTYPE_GROUP) {
GtkTreePath *path = gtk_tree_model_get_path(treeModel, subtreeIter);
if (path != NULL) {
expanded = tree_row_is_expanded(path);
gtk_tree_path_free(path);
}
gchar *exp_string=NULL;
if (expanded) {
exp_string=g_strdup_printf("TRUE");
} else {
exp_string=g_strdup_printf("FALSE");
}
tmpXML = g_markup_printf_escaped("%s\n", indentString, filepathString, exp_string);
if (!str_append(xmlString, tmpXML, err)) {
goto EXITPOINT;
}
GtkTreeIter childIter;
if (gtk_tree_model_iter_children(treeModel, &childIter, subtreeIter)) {
do {
if (!marshal_subtree(treeModel, &childIter, xmlString, err)) {
goto EXITPOINT;
}
} while (gtk_tree_model_iter_next(treeModel, &childIter));
}
// Don't forget to append the close tag
if (!str_append(xmlString, indentString, err) || !str_append(xmlString, "\n", err)) {
goto EXITPOINT;
}
}
finalResult = TRUE;
EXITPOINT:
if (filepathString) g_free(filepathString);
if (tmpXML) g_free(tmpXML);
if (indentString) g_free(indentString);
return finalResult;
}
/**
* Save the contents of a GtkTreeModel to a file.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param treeModel is the GtkTreeModel to save; the COLUMN_FILEPATH items are extracted and saved
* @param filepath is the pathname for the target file
* @param err returns any errors
*/
gboolean save_tree_XML(GtkTreeModel *treeModel, const gchar *filepath, GError **err)
{
g_assert(treeModel != NULL);
g_assert(filepath != NULL);
gboolean finalResult = FALSE;
GtkTreeIter iter;
gchar *xmlString = NULL;
// Add of document
if (!str_append(&xmlString, "\n", err)) {
goto EXITPOINT;
}
// Iterate over root level of tree
if (gtk_tree_model_get_iter_first(treeModel, &iter)) {
do {
if (!marshal_subtree(treeModel, &iter, &xmlString, err)) {
goto EXITPOINT;
}
} while (gtk_tree_model_iter_next(treeModel, &iter));
}
// Close
if (!str_append(&xmlString, "\n", err)) {
goto EXITPOINT;
}
// Write out file
if (!g_file_set_contents(filepath, xmlString, -1, err)) {
goto EXITPOINT;
}
finalResult = TRUE;
EXITPOINT:
if (xmlString) g_free(xmlString);
return finalResult;
}
sciteproj-0.7.08/src/recent_files.h 0000644 0001750 0001750 00000002310 12143703722 016557 0 ustar gusnan gusnan /**
* recent_files.h - list of recently opened files
*
* Copyright 2011-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_RECENT_FILES_
#define __HEADER_RECENT_FILES_
/**
*
*/
extern GtkWidget *recentTreeView;
extern GtkWidget *recentPopupMenu;
GtkWidget *init_recent_files(GError **err);
gboolean add_file_to_recent(gchar *filepath, GError **err);
void popup_open_recent_file_cb();
void popup_remove_recent_file_cb();
void copy_recent_filename_to_clipboard_cb();
void properties_recent_file_cb();
#endif /*__HEADER_RECENT_FILES_*/
sciteproj-0.7.08/src/folder_to_xml.c 0000644 0001750 0001750 00000012551 12143703722 016755 0 ustar gusnan gusnan /**
* folder_to_xml.c - file system to xml convertion for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include "folder_to_xml.h"
/*
*
*/
gchar *directory_string=0;
gchar *base_folder=0;
FILE *save_file=NULL;
gchar *stored_current_dir;
/**
*
*/
gchar *get_short_folder_name(gchar *base,gchar *current)
{
int co=0;
gchar *result=current+strlen(base);
// make sure the returned string don't start with a dir separator
co=0;
size_t len=strlen(base);
do {
if (result[0]==G_DIR_SEPARATOR) result++;
co++;
} while ((result[0]==G_DIR_SEPARATOR) && (co\n",trimmed);
}
g_free(trimmed);
while((file=(gchar*)g_dir_read_name(dir)))
{
if (file!=NULL) {
ignore_item=FALSE;
if (ignore_hidden) {
if (file[0]=='.') {
ignore_item=TRUE;
}
}
// Ignore hidden folders
if (!ignore_item) {
newfolder=g_strdup_printf("%s%c",file,G_DIR_SEPARATOR);
if (g_file_test(newfolder,G_FILE_TEST_IS_DIR)) {
// success, we can step into that folder
// check if we are below or equal to the max_depth
if ((*indent)<=max_depth) {
traverse_folder((char*)newfolder,indent,ignore_hidden,max_depth);
}
} else {
print_indent(*indent);
gchar *folder=get_short_folder_name(stored_current_dir,current_dir);
if ((folder!=NULL) && ((int)(strlen(folder))!=0)) {
if (save_file!=NULL) fprintf(save_file,"./%s/%s\n",folder,file);
} else {
if (save_file!=NULL) fprintf(save_file,"./%s\n",file);
}
}
g_free(newfolder);
}
} else {
break;
}
// end of while loop
}
g_free(current_dir);
g_dir_close(dir);
print_indent(newin);
//g_printf("\n");
if (save_file!=NULL) {
fprintf(save_file,"\n");
}
if (g_chdir("..")!=0) {
return FALSE;
}
(*indent)--;
// success
return TRUE;
}
/**
* folder_to_xml
*
* @param folder folder to begin traverse
* @param save_filename filename to save resulting XML in
*
* @return gboolean TRUE if success, otherwise FALSE
*/
gboolean folder_to_xml(gchar *folder,gchar *save_filename_in,int max_depth)
{
gboolean result=FALSE;
gchar *save_filename;
int temp_indent=0;
stored_current_dir=g_get_current_dir();
directory_string=(gchar*)folder;
save_filename=g_build_filename(stored_current_dir,save_filename_in,NULL);
if (!g_file_test(directory_string,G_FILE_TEST_IS_DIR)) {
g_error(_("Error: Invalid directory!"));
goto EXIT_POINT;
}
// Check if the directory is valid
if (g_chdir(directory_string)!=0) {
g_error(_("Error: Couldn't g_chdir to directory"));
goto EXIT_POINT;
}
if (save_filename!=NULL) {
if ((save_file=fopen(save_filename,"w"))==NULL) {
g_error(_("Couldn't create file with the name %s!"),save_filename);
goto EXIT_POINT;
}
} else {
save_file=stdout;
}
if (save_file!=NULL) fprintf(save_file,"\n");
base_folder=g_strdup(folder);
traverse_folder(folder,&temp_indent,TRUE,max_depth);
if (save_file!=NULL) {
fprintf(save_file,"\n");
}
if (save_filename!=NULL) {
fclose(save_file);
save_file=NULL;
}
// change back to the stored directory
if (g_chdir(stored_current_dir)!=0) {
goto EXIT_POINT;
}
// it worked fine
result=TRUE;
EXIT_POINT:
g_free(stored_current_dir);
g_free(base_folder);
g_free(save_filename);
return result;
}
sciteproj-0.7.08/src/clipboard.h 0000644 0001750 0001750 00000001744 12143703722 016066 0 ustar gusnan gusnan /**
* clipboard.h - clipboard support for SciteProj
*
* Copyright 2010-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_CLIPBOARD_
#define __HEADER_CLIPBOARD_
/**
*
*/
void copy_filename_to_clipboard(GtkTreeModel *model, GtkTreeIter *iter);
void copy_filename_to_clipboard_cb();
#endif /*__HEADER_CLIPBOARD_*/
sciteproj-0.7.08/src/tree_manipulation.h 0000644 0001750 0001750 00000010114 12143703722 017635 0 ustar gusnan gusnan /**
* tree_manipulation.h - GtkTreeView manipulation code for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj.
* If not, see .
*
*/
#ifndef __HEADER_TREE_MANIPULATION_
#define __HEADER_TREE_MANIPULATION_
// Node relative-position indicators
enum NodePosition {
ADD_BEFORE,
ADD_AFTER,
ADD_CHILD
};
// Mnemonic identifiers for the columns in the GtkTreeStore
enum {
COLUMN_ITEMTYPE = 0,
COLUMN_FILEPATH,
COLUMN_FILENAME,
COLUMN_FILESIZE,
COLUMN_FONTWEIGHT,
COLUMN_FONTWEIGHTSET,
COLUMN_ICON,
COLUMN_EXPANDED,
COLUMN_EOL
};
// The type of each row in the tree datamodel
enum {
ITEMTYPE_GROUP,
ITEMTYPE_FILE
};
// The types for each column in the tree datamodel
#define TYPE_ITEMTYPE G_TYPE_UINT
#define TYPE_FILEPATH G_TYPE_STRING
#define TYPE_FILENAME G_TYPE_STRING
#define TYPE_FILESIZE G_TYPE_STRING
#define TYPE_FONTWEIGHT G_TYPE_INT
#define TYPE_FONTWEIGHTSET G_TYPE_BOOLEAN
#define TYPE_ICON GDK_TYPE_PIXBUF
#define TYPE_EXPANDED G_TYPE_BOOLEAN
typedef gint(*StringCompareFunction)(gconstpointer,gconstpointer);
// Get the GTKTreeStore
GtkTreeStore* create_treestore(GError **err);
// Get the project file directory
const gchar* get_project_directory();
gchar* get_project_filepath();
// Clear the tree
void empty_tree(GtkTreeStore *treeStore);
// Mark the project as dirty or clean (i.e. modified and in need of saving)
void set_project_dirty_status(gboolean isDirty);
// Get the status of the project
gboolean project_is_dirty();
// Prompting the user to save the project if it is dirty
void prompt_user_to_save_project();
// Save the current project, or pop up an error dialog if something bad happened
gboolean save_project(gchar *proj_filepath,GError **err);
// Allow user to select a project file to load (save current project first, if appropriate)
gboolean load_project(gchar *projectPath, GError **err);
// Allow user to select and add files to the project
gboolean add_files_to_project(GtkTreeIter *parentIter, GError **err);
// Add a file node to a GtkTreeModel
gboolean add_tree_file(GtkTreeIter *currentIter, enum NodePosition position, const gchar* filepath, GtkTreeIter *newIter, gboolean makeRelative, GError **err);
//gboolean add_tree_filelist(GtkTreeIter *parentIter, GSList *fileList, GError **err);
gboolean add_tree_filelist(GtkTreeIter *parentIter, GSList *fileList, GError **err);
// Add a group node to a GtkTreeModel
gboolean add_tree_group(GtkTreeIter *parentIter, enum NodePosition position, const gchar* groupname, gboolean expanded, GtkTreeIter *newIter, GError **err);
// Remove a node from a GtkTreeModel
gboolean remove_tree_node(GtkTreeIter *iter, GError **err);
// Remove a node from a GtkTreeModel
gboolean set_tree_node_name(GtkTreeIter *iter, const gchar *newContents, GError **err);
gboolean set_tree_node_expanded(GtkTreeIter *iter, gboolean expanded, GError **err);
gboolean set_tree_node_icon(GtkTreeIter *iter, GdkPixbuf *pixbuf, GError **err);
// Copy a node in the tree (including children)
gboolean copy_tree_node(GtkTreeIter *srcIter, GtkTreeIter *dstIter, enum NodePosition position, GtkTreeIter *newIter, GError **err);
gchar *get_path_string(GtkTreeIter *iter);
gint compare_strings_smaller(gconstpointer a,gconstpointer b);
gint compare_strings_bigger(gconstpointer a,gconstpointer b);
void sort_children(GtkTreeIter *node,GError **err,StringCompareFunction compare_func);
gboolean tree_contains(gchar *value);
#endif /*__HEADER_TREE_MANIPULATION_*/
sciteproj-0.7.08/src/prefs.c 0000644 0001750 0001750 00000020340 12143703722 015232 0 ustar gusnan gusnan /**
* prefs.c - prefs for SciteProj
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include "prefs.h"
#include "string_utils.h"
sciteproj_prefs gPrefs;
gchar *prefs_filename;
gchar *default_config_string=(gchar*)"" \
"# ---------------------------\n"
"# Configuration for SciteProj\n"
"# ---------------------------\n"
"\n"
"# Window geometry:\n"
"xpos=40\n"
"ypos=40\n"
"width=200\n"
"height=400\n"
"\n"
"# Search window geometry (-1 on xpos and ypos means default center screen):\n"
"search_xpos=-1\n"
"search_ypos=-1\n"
"search_width=500\n"
"search_height=400\n"
"\n"
"search_alert_file_warnings=TRUE\n"
"search_match_case=FALSE\n"
"search_match_whole_words=FALSE\n"
"search_trim_results=TRUE\n"
"\n"
"#other:\n"
"give_scite_focus=FALSE\n"
"search_give_scite_focus=TRUE\n"
"dirty_on_folder_change=FALSE\n"
"\n"
"allow_duplicates=TRUE\n"
"\n"
"identify_sciteproj_xml=TRUE\n"
"\n"
"show_recent=FALSE\n"
"recent_add_to_bottom=FALSE\n"
"\n"
"hide_statusbar=FALSE\n"
"\n"
"\n";
/**
* Check config string - is it valid?
*/
gboolean check_config_string(gchar *in_config)
{
gboolean result=FALSE;
int co=0;
gdouble tempdouble;
gchar *tempstring=NULL;
int pos=-1;
gchar *value=in_config;
// clear scite Path
gPrefs.scite_path=NULL;
for (co=0;co<(int)strlen(in_config);co++) {
if (in_config[co]=='=') pos=co;
if (pos==-1) {
value++;
}
}
if (pos!=-1) {
tempstring=g_strndup(in_config,pos);
value++;
}
if ((tempstring!=NULL) && (value!=NULL)) {
tempstring=g_strchug(tempstring);
tempstring=g_strchomp(tempstring);
value=g_strchug(value);
value=g_strchomp(value);
if (g_ascii_strcasecmp(tempstring,"xpos")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.xpos=(int) tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"ypos")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.ypos=(int)tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"width")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.width=(int)tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"height")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.height=(int)tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"search_xpos")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.search_xpos=(int) tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"search_ypos")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.search_ypos=(int)tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"search_width")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.search_width=(int)tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"search_height")==0) {
tempdouble=g_ascii_strtod(value,NULL);
gPrefs.search_height=(int)tempdouble;
}
if (g_ascii_strcasecmp(tempstring,"give_scite_focus")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.give_scite_focus=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"search_give_scite_focus")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.search_give_scite_focus=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"search_alert_file_warnings")==0) {
if (g_ascii_strcasecmp(value,"FALSE")==0) {
gPrefs.search_alert_file_warnings=FALSE;
}
}
if (g_ascii_strcasecmp(tempstring,"search_match_case")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.search_match_case=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"search_match_whole_words")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.search_match_whole_words=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"dirty_on_folder_change")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.dirty_on_folder_change=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"allow_duplicates")==0) {
if (g_ascii_strcasecmp(value,"FALSE")==0) {
gPrefs.allow_duplicates=FALSE;
}
}
if (g_ascii_strcasecmp(tempstring,"scite_path")==0) {
gPrefs.scite_path=g_strdup_printf("%s",value);
}
if (g_ascii_strcasecmp(tempstring,"file_to_load")==0) {
gPrefs.file_to_load=g_strdup_printf("%s",value);
}
if (g_ascii_strcasecmp(tempstring,"identify_sciteproj_xml")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.identify_sciteproj_xml=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"show_recent")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.show_recent=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"recent_add_to_bottom")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.recent_add_to_bottom=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"search_trim_results")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.search_trim_results=TRUE;
}
}
if (g_ascii_strcasecmp(tempstring,"hide_statusbar")==0) {
if (g_ascii_strcasecmp(value,"TRUE")==0) {
gPrefs.hide_statusbar=TRUE;
}
}
}
if (tempstring!=NULL) g_free(tempstring);
return result;
}
/**
* init_prefs
*/
gboolean init_prefs(GError **err)
{
//FILE *fp;
//gchar buf[PREFS_BUFSIZE];
gchar *config_string=NULL;
gboolean result=TRUE;
// the list of strings
gchar **list=NULL;
gchar **savedlist=NULL;
gchar *temp=NULL;
// Set default values
gPrefs.lhs=1;
gPrefs.width=200;
gPrefs.height=600;
gPrefs.verbosity=0; // No informational messages
gPrefs.last_file_filter=-1; // All files (my choice)
gPrefs.search_xpos=-1;
gPrefs.search_ypos=-1;
gPrefs.search_width=500;
gPrefs.search_height=400;
gPrefs.give_scite_focus=FALSE;
gPrefs.search_give_scite_focus=TRUE;
gPrefs.dirty_on_folder_change=FALSE;
gPrefs.search_alert_file_warnings=TRUE;
gPrefs.search_match_case=FALSE;
gPrefs.search_match_whole_words=FALSE;
gPrefs.allow_duplicates=TRUE;
gPrefs.show_recent=FALSE;
gPrefs.recent_add_to_bottom=FALSE;
gPrefs.file_to_load=NULL;
gPrefs.scite_path=NULL;
gPrefs.search_trim_results=FALSE;
gPrefs.hide_statusbar=FALSE;
// the result of g_get_user_config_dir doesn't need to be freed, so we
// dont need to put it in a pointer of its own.
prefs_filename=g_build_filename(g_get_user_config_dir(),"sciteprojrc",NULL);
// Check if a config-file exists
if (!g_file_test(prefs_filename,G_FILE_TEST_IS_REGULAR)) {
// First, check if ~/.sciteproj exists.
gchar *old_configfilename=g_build_filename(g_get_home_dir(),".sciteproj",NULL);
if (g_file_test(old_configfilename,G_FILE_TEST_IS_REGULAR)) {
// config-file at the "old" position exists, copy its contents to the
// new file
gchar *old_buffer;
g_file_get_contents(old_configfilename,&old_buffer,NULL,err);
g_file_set_contents(prefs_filename,old_buffer,-1,err);
} else {
// No config-file exists, create a new one and write default values
g_file_set_contents(prefs_filename,default_config_string,-1,err);
}
}
// Load preferences from config dot-file
if (!g_file_get_contents(prefs_filename,&config_string,NULL,err)) {
result=FALSE;
goto ERROR;
}
// split out the lines, and add each to the list of strings
list=g_strsplit(config_string,"\n",-1);
savedlist=list;
do {
temp=*list;
if (temp!=NULL) {
if ((temp[0]!='#') && (strcmp(temp,"")!=0)) {
// We got a valid string:
// no starting #, and not an empty string.
check_config_string(temp);
}
list++;
}
} while (temp!=NULL);
g_strfreev(savedlist);
ERROR:
g_free(config_string);
return result;
}
/**
*
*/
void done_prefs()
{
g_free(prefs_filename);
}
sciteproj-0.7.08/src/menus.h 0000644 0001750 0001750 00000023631 12143703722 015255 0 ustar gusnan gusnan /**
* menus.h - Menus for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#ifndef __HEADER_MENUS_
#define __HEADER_MENUS_
/*
Menu definitions
*/
static gchar *sMenuDefXML = (gchar*)\
" \
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
";
/*
Contains the NC strings that ends up in the po-files
*/
static GtkActionEntry sMenuActions[] =
{
{ "FileMenuAction", NULL, NC_("Menu|","_File") },
{ "EditMenuAction", NULL, NC_("Menu|","_Edit") },
{ "ViewMenuAction", NULL, NC_("Menu|","_View") },
{ "HelpMenuAction", NULL, NC_("Menu|","_Help") },
{ "OpenProjectAction", GTK_STOCK_OPEN, NC_("Menu|File|","_Open project"), "O",
NULL, G_CALLBACK(openproject_menu_cb) },
{ "SaveProjectAction", GTK_STOCK_SAVE, NC_("Menu|File|","_Save project"), "S",
NULL, G_CALLBACK(saveproject_menu_cb) },
{ "SaveProjectAsAction", GTK_STOCK_SAVE_AS, NC_("Menu|File|","Save project as..."), "S",
NULL, G_CALLBACK(saveproject_as_menu_cb) },
{ "ExitAction", GTK_STOCK_QUIT, NC_("Menu|File|","_Exit"), "Q",
NULL, G_CALLBACK(quit_menu_cb) },
{ "CreateGroupAction", GTK_STOCK_DIRECTORY, NC_("Menu|Edit|","Create _group"), "",
NULL, G_CALLBACK(creategroup_menu_cb) },
{ "AddFileAction", GTK_STOCK_FILE, NC_("Menu|Edit|","Add _file"), "",
NULL, G_CALLBACK(addfile_menu_cb) },
{ "RemoveFileAction", GTK_STOCK_DELETE, NC_("Menu|Edit|","Remove file(s)"), "",
NULL, G_CALLBACK(removeitem_menu_cb) },
{ "ExpandAllGroupsAction", NULL, NC_("Menu|Edit|","Expand all groups"), "E",
NULL, G_CALLBACK(expand_all_items_cb) },
{ "CollapseAllGroupsAction", NULL, NC_("Menu|Edit|","Collapse all groups"), "C",
NULL, G_CALLBACK(collapse_all_items_cb) },
{ "SearchAction", GTK_STOCK_FIND, NC_("Menu|Edit|","Search"), "F",
NULL, G_CALLBACK(search_dialog_cb) },
{ "AboutAction", GTK_STOCK_ABOUT, NC_("Menu|Help|","_About"), "",
NULL, G_CALLBACK(about_menu_cb) },
{ "AddFilesPopupAction", GTK_STOCK_FILE, NC_("Menu|Edit|","Add files"), "",
NULL, G_CALLBACK(popup_add_files_cb) },
{ "AddGroupPopupAction", GTK_STOCK_DIRECTORY, NC_("Menu|Edit|","Create _group"), "",
NULL, G_CALLBACK(popup_add_group_cb) },
{ "AddFilestoGroupPopupAction", GTK_STOCK_FILE, NC_("Menu|Popup|Group","Add files to group"), "",
NULL, G_CALLBACK(popup_add_files_cb) },
{ "AddSubgroupPopupAction", GTK_STOCK_DIRECTORY, NC_("Menu|Popup|Group","Add subgroup to group"), "",
NULL, G_CALLBACK(popup_add_group_cb) },
{ "RenameGroupPopupAction", GTK_STOCK_EDIT, NC_("Menu|Popup|Group","Rename group"), "",
NULL, G_CALLBACK(popup_rename_group_cb) },
{ "RemoveGroupPopupAction", GTK_STOCK_DELETE, NC_("Menu|Popup|Group","Remove group from project"), "",
NULL, G_CALLBACK(popup_remove_node_cb) },
{ "SortAscendingAction", GTK_STOCK_SORT_ASCENDING, NC_("Menu|Edit|","Sort group ascending"),"",
NULL, G_CALLBACK(sort_ascending_cb) },
{ "SortDescendingAction", GTK_STOCK_SORT_DESCENDING, NC_("Menu|Edit","Sort group descending"),"",
NULL, G_CALLBACK(sort_descending_cb) },
{ "PropertiesGroupPopupAction", GTK_STOCK_PROPERTIES, NC_("Menu|Popup|Group","Properties"), "",
NULL, G_CALLBACK(group_properties_cb) },
{ "EditOptionsAction", GTK_STOCK_PROPERTIES, NC_("Menu|Edit|","Edit options"), "",
NULL, G_CALLBACK(edit_options_cb) },
{ "ViewRecentAction" , GTK_STOCK_PROPERTIES, NC_("Menu|View|","View recently opened files"), "R",
NULL, G_CALLBACK(recent_files_switch_visible) },
{ "OpenFilePopupAction", GTK_STOCK_OPEN, NC_("Menu|Popup|File","Open file in SciTE"), "",
NULL, G_CALLBACK(popup_open_file_cb) },
{ "RemoveFilePopupAction", GTK_STOCK_DELETE, NC_("Menu|Popup|File","Remove file From project"), "",
NULL, G_CALLBACK(popup_remove_node_cb) },
{ "CopyFilenameToClipBoardAction", GTK_STOCK_COPY, NC_("Menu|Popup|File","Copy filename to clipboard"), "",
NULL, G_CALLBACK(copy_filename_to_clipboard_cb) },
{ "PropertiesPopupAction", GTK_STOCK_PROPERTIES, NC_("Menu|Popup|File","Properties"), "",
NULL, G_CALLBACK(file_properties_cb) },
{ "OpenRecentFilePopupAction", GTK_STOCK_OPEN, NC_("Menu|Popup|RecentFile","Open file in SciTE"), "",
NULL, G_CALLBACK(popup_open_recent_file_cb) },
{ "RemoveRecentFilePopupAction", GTK_STOCK_DELETE, NC_("Menu|Popup|RecentFile","Remove file from this list"), "",
NULL, G_CALLBACK(popup_remove_recent_file_cb) },
{ "CopyRecentToClipboardAction", GTK_STOCK_COPY, NC_("Menu|Popup|RecentFile","Copy filename to clipboard"), "",
NULL, G_CALLBACK(copy_recent_filename_to_clipboard_cb) },
{ "PropertiesRecentPopupAction", GTK_STOCK_PROPERTIES, NC_("Menu|Popup|RecentFile","Properties"), "",
NULL, G_CALLBACK(properties_recent_file_cb) }
};
/*
struct for strings in the menu
*/
struct ContextString {
gchar *context;
gchar *string;
};
/*
The strings that are given to g_dpgettext2 - see gui.c:244
Should be same order as in sMenuActions, and of course the same strings so
that it get matched by gettext
*/
static struct ContextString menustrings[]= {
{ "Menu|","_File"},
{ "Menu|","_Edit"},
{ "Menu|","_View"},
{ "Menu|","_Help"},
{ "Menu|File|","_Open project"},
{ "Menu|File|","_Save project"},
{ "Menu|File|","Save project as..."},
{ "Menu|File|","_Exit"},
{ "Menu|Edit|","Create _group"},
{ "Menu|Edit|","Add _file"},
{ "Menu|Edit|","Remove file(s)"},
{ "Menu|Edit|","Expand all groups"},
{ "Menu|Edit|","Collapse all groups"},
{ "Menu|Edit|","Search" },
{ "Menu|Help|","_About"},
{ "Menu|Edit|","Add files"},
{ "Menu|Edit|","Create _group"},
{ "Menu|Popup|Group","Add files to group"},
{ "Menu|Popup|Group","Add subgroup to group"},
{ "Menu|Popup|Group","Rename group"},
{ "Menu|Popup|Group","Remove group from project" },
{ "Menu|Edit|","Sort group ascending" },
{ "Menu|Edit","Sort group descending" },
{ "Menu|Popup|Group","Properties" },
{ "Menu|Edit|","Edit options" },
{ "Menu|View|","View recently opened files"},
{ "Menu|Popup|File","Open file in SciTE"},
{ "Menu|Popup|File","Remove file from project"},
{ "Menu|Popup|File","Copy filename to clipboard"},
{ "Menu|Popup|File","Properties"},
{ "Menu|Popup|RecentFile","Open file in SciTE"},
{ "Menu|Popup|RecentFile","Remove file from this list"},
{ "Menu|Popup|RecentFile","Copy filename to clipboard"},
{ "Menu|Popup|RecentFile","Properties"},
{ NULL,NULL}
};
#endif /*__HEADER_MENUS_*/
sciteproj-0.7.08/src/scite_utils.c 0000644 0001750 0001750 00000054201 12143703722 016445 0 ustar gusnan gusnan /**
* scite_utils_linux.c - Code for working with Scite (Linux version)
*
* Copyright 2006 Roy Wood, 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "scite_utils.h"
// This is for SciteProj :
#include "prefs.h"
#include "clicked_node.h"
#include "gui.h"
#include "graphics.h"
#include "string_utils.h"
#include "statusbar.h"
#define APP_SCITEPROJ_ERROR g_quark_from_static_string("APP_SCITEUTILS_ERROR")
// Indicates whether Scite was successfully forked/executed
static gboolean sSciteLaunched = FALSE;
// File descriptor of the request pipe
static int sRequestPipeFD = 0;
// File descriptor of the response pipe
static int sResponsePipeFD = 0;
// GLib GIOChannel of the response pipe
static GIOChannel* sResponsePipeGIOChannel = NULL;
// Scite executable name
static gchar *sSciteExecName0 = (gchar*)"/usr/local/bin/SciTE";
static gchar *sSciteExecName1 = (gchar*)"/usr/local/bin/scite";
static gchar *sSciteExecName2 = (gchar*)"SciTE";
static gchar *sSciteExecName3 = (gchar*)"scite";
// -----------------
// X11 display
Display *sDisplay = NULL;
// Scite X11 window
Window sSciteWin = 0;
gboolean scite_exists=FALSE;
void set_scite_launched(gboolean launched);
/**
* Determine if Scite is open and ready for communication.
*
* @return TRUE if Scite has been forked/executed and we have an open pipe, FALSE otherwise
*/
gboolean scite_ready()
{
return (sSciteLaunched && sRequestPipeFD != 0);
}
/**
* Shut down all the Scite pipes and associated GIOChannels.
*/
void shutdown_pipes()
{
if (sRequestPipeFD) {
close(sRequestPipeFD);
sRequestPipeFD = 0;
}
if (sResponsePipeGIOChannel) {
g_io_channel_unref(sResponsePipeGIOChannel);
g_io_channel_shutdown(sResponsePipeGIOChannel, FALSE, NULL);
sResponsePipeGIOChannel = NULL;
}
if (sResponsePipeFD) {
close(sResponsePipeFD);
sResponsePipeFD = 0;
}
sSciteWin = 0;
}
/**
* Callback for data-ready on the pipe we use to read from Scite. We don't actually do anything with
* the messages from Scite right now, other than echo them to the console.
*
* @param source is the GIOChannel associated with the pipe Scite writes to
* @param condition is the GIOCondition for the event that triggered the callback
* @param data is the user data item (not used)
*/
gboolean scite_pipe_read_ready_cb(GIOChannel *source, GIOCondition condition, gpointer data)
{
g_assert(source == sResponsePipeGIOChannel);
static gchar buff[1024];
gboolean finalResult = TRUE;
gsize bytes_read;
GError *error = NULL;
#ifdef DEBUG_SCITE
debug_printf("scite_pipe_read_ready_cb\n");
#endif
if (condition & G_IO_IN) {
if (g_io_channel_read_chars(source, buff, sizeof(buff) - 1, &bytes_read, &error) != G_IO_STATUS_NORMAL) {
g_print("%s: %s = %s\n",
__func__,
"g_io_channel_read_chars failed",
(error != NULL) ? error->message : "");
}
else {
if ((bytes_read-1)!=0) {
buff[bytes_read] = '\0';
// This is for SciteProj :
//if(gPrefs.verbosity>50) {
#ifdef DEBUG_SCITE
debug_printf("%s: read data '%s'\n", __func__, buff);
#endif
//}
// Is it the response to an "askproperty" command? Dunno why they are prefixed with "macro:stringinfo:" though....
static char *askpropertyResponse = (char*)"macro:stringinfo:";
if (g_str_has_prefix(buff, askpropertyResponse)) {
char *windowIDStr = buff + strlen(askpropertyResponse);
sSciteWin = strtol(windowIDStr, NULL, 0);
}
if (g_str_has_prefix(buff, "closed:")) {
gchar *status_string=NULL;
gchar *file=get_filename_from_full_path(buff);
status_string=g_strdup_printf(_("Closed %s"),file);
set_statusbar_text(status_string);
g_free(status_string);
}
if (g_str_has_prefix(buff, "closing:")) {
set_statusbar_text(_("Closed SciTE"));
}
if (g_str_has_prefix(buff, "switched:")) {
gchar *status_string=NULL;
gchar *file=get_filename_from_full_path(buff);
status_string=g_strdup_printf(_("Switched to %s"),file);
set_statusbar_text(status_string);
g_free(status_string);
}
if (g_str_has_prefix(buff, "opened:")) {
gchar *status_string=NULL;
gchar *file=get_filename_from_full_path(buff);
status_string=g_strdup_printf(_("Opened %s"),file);
set_statusbar_text(status_string);
g_free(status_string);
}
}
}
}
if (condition & G_IO_ERR) {
g_print("%s: condition = G_IO_ERR\n", __func__);
finalResult = FALSE;
}
if (condition & G_IO_HUP) {
// This is for SciteProj :
if(gPrefs.verbosity>50) {
g_print("%s: condition = G_IO_HUP\n", __func__);
}
finalResult = FALSE;
}
if (!finalResult) {
// We want to stop monitoring this GIOChannel, so shut it all down
shutdown_pipes();
set_scite_launched(FALSE);
//~ GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Connection to current instance of Scite has been broken");
//~ gtk_dialog_run(GTK_DIALOG(dialog));
//~ gtk_widget_destroy(dialog);
}
if (error) g_error_free(error);
return finalResult;
}
/**
* Callback for the progress dialog shown when opening Scite. This callback simply sets a boolean
* pointed to by the userData paramater.
*
* @param dialog is the pointer to the dialog
* @param responseID is the responseID of the cancel button
* @param userData is a pointer to a boolean that we set to true
*/
static void cancel_button_cb(GtkDialog *dialog, gint responseID, gpointer userData)
{
if (userData) {
*((gboolean *) userData) = TRUE;
}
}
/**
* Fork and execute an instance of Scite, then connect to its "Director" pipe. This is uglier than
* I expected it to be, once I factored in the progress feedback, user cancellation, handling of
* failure of the fork/exec, etc.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param err returns any errors
*/
gboolean launch_scite(gchar *instring,GError **err)
{
debug_printf("launch_scite: %s\n",instring);
gboolean resultCode = FALSE;
gchar* ipcDirectorName = (gchar*)"ipc.director.name";
gchar* ipcSciteName = (gchar*)"ipc.scite.name";
GtkWidget* dialog = NULL;
int childPipePair[2] = { 0, 0 };
fd_set readFDS;
struct timeval timeVal;
gboolean userClickedCancel = FALSE;
gchar responsePipePath[256];
gchar requestPipePath[256];
gchar *scite_command;
char scite_arg1[256];
char scite_arg2[256];
char scite_arg3[256];
char scite_arg4[256];
static unsigned long usecsDelta = 100000;
static unsigned long usecsDialogDelay;
// Clean up anything open from previous attempts/activity
shutdown_pipes();
set_scite_launched(FALSE);
if (scite_exists) {
// We need our process id for use in forming the named pipe filenames
pid_t ourPID = 0;
pid_t childPID = 0;
gulong usecs=0;
int errCode;
ourPID = getpid();
// The response pipe will be used by Scite to send data to us
g_snprintf(responsePipePath, sizeof(responsePipePath), "/tmp/sciteproj.%ld", (unsigned long) ourPID);
if (setenv(ipcDirectorName, responsePipePath, TRUE)) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, setenv(\"%s\", \"%s\") failed, error = %s",
__func__, ipcDirectorName, responsePipePath, strerror(errCode));
goto EXITPOINT;
}
// The request pipe will be used to send data to Scite
g_snprintf(requestPipePath, sizeof(requestPipePath), "/tmp/scite.%ld", (unsigned long) ourPID);
if (setenv(ipcSciteName, requestPipePath, TRUE)) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, setenv(\"%s\", \"%s\") failed, error = %s",
__func__, ipcSciteName, requestPipePath, strerror(errCode));
goto EXITPOINT;
}
// Remove any existing files that conflict with the pipe names
if (remove(responsePipePath) && errno != ENOENT) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, remove(\"%s\") failed, error = %s",
__func__, responsePipePath, strerror(errCode));
goto EXITPOINT;
}
if (remove(requestPipePath) && errno != ENOENT) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, remove(\"%s\") failed, error = %s",
__func__, requestPipePath, strerror(errCode));
goto EXITPOINT;
}
// Now create our response pipe (Scite creates the request pipe, as long as it doesn't already exist)
if (mkfifo(responsePipePath, 0777)) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, mkfifo(\"%s\") failed, error = %s",
__func__, responsePipePath, strerror(errCode));
goto EXITPOINT;
}
// Open the Scite response pipe
if ((sResponsePipeFD = open(responsePipePath, O_RDONLY | O_NONBLOCK)) <= 0) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, open(\"%s\") failed, error = %s",
__func__, responsePipePath, strerror(errCode));
goto EXITPOINT;
}
// Hook up the Scite response pipe to our Gtk/GLib main loop
if ((sResponsePipeGIOChannel = g_io_channel_unix_new(sResponsePipeFD)) == NULL) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, g_io_channel_unix_new(\"%s\") failed, error = %s",
__func__, responsePipePath, strerror(errCode));
goto EXITPOINT;
}
if ((g_io_channel_set_encoding(sResponsePipeGIOChannel, NULL, err)) != G_IO_STATUS_NORMAL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, g_io_channel_set_encoding( ) failed, error = %s",
__func__, (err != NULL && *err != NULL) ? (*err)->message : "");
goto EXITPOINT;
}
g_io_add_watch(sResponsePipeGIOChannel, (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP), scite_pipe_read_ready_cb, NULL);
// Also create a pipe pair so our child process can alert us if it fails to execute Scite
if (pipe(childPipePair)) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, pipe( ) failed, errno = %d = %s",
__func__, errCode, strerror(errCode));
goto EXITPOINT;
}
// Fix the instring
gchar *opt1=NULL;
gchar *opt2=NULL;
if (instring!=NULL) {
int len=strlen(instring);
int split=-1;
gchar *tempstring=instring;
gchar *place=NULL;
int co;
for (co=0;co 0) {
// If the child sent *any* data, it failed to exec Scite
set_scite_launched(FALSE);
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not launch Scite, execlp( ) failed", __func__);
goto EXITPOINT;
}
// No luck yet, so display a progress dialog and wait a bit longer
if (usecs > usecsDialogDelay && !dialog) {
dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CANCEL, _("Connecting to Scite...."));
g_signal_connect(dialog, "response", G_CALLBACK(cancel_button_cb), (void *) &userClickedCancel);
gtk_widget_show_all(dialog);
}
while (gtk_events_pending()) {
gtk_main_iteration();
}
if (userClickedCancel) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not connect to Scite", __func__);
goto EXITPOINT;
}
g_usleep(usecsDelta);
}
// Try to open the request pipe
if ((sRequestPipeFD = open(requestPipePath, O_WRONLY | O_NONBLOCK)) <= 0) {
errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not launch Scite, open(\"%s\") failed, error = %s",
__func__, requestPipePath, strerror(errCode));
goto EXITPOINT;
}
// Ask SciTE for the x11 window ID
scite_command=(gchar*)"askproperty:x11.windowid\n";
if (!send_scite_command(scite_command, err)) {
goto EXITPOINT;
}
// g_print("%s: Problem sending message to parent: messageLength = %d, bytesWritten = %d\n", __func__, messageLength, bytesWritten);
// Now, let's resize the new window --
// if (!send_scite_command("property:position.left=300\n", err)) {
// goto EXITPOINT;
// }
// Wow-- it all actually worked!
resultCode = TRUE;
set_statusbar_text(_("Launched SciTE"));
}
debug_printf("All done launching SciTE...\n");
EXITPOINT:
if (dialog) gtk_widget_destroy(dialog);
if (childPipePair[0]) close(childPipePair[0]);
if (childPipePair[1]) close(childPipePair[1]);
if (!resultCode) {
shutdown_pipes();
set_scite_launched(FALSE);
}
return resultCode;
}
/**
* Send a command to Scite.
*
* @return TRUE on success, FALSE on failure (further details returned in err)
*
* @param command is the command to send to Scite
* @param err returns any errors
*/
gboolean send_scite_command(gchar *command, GError **err)
{
g_assert(command != NULL);
#ifdef DEBUG_SCITE
debug_printf("send_scite_command(%s)\n",command);
#endif
gboolean resultCode = FALSE;
int commandLength = strlen(command);
// Ensure we are connected to a running instance of Scite
if (!scite_ready() && !launch_scite(NULL,err)) {
goto EXITPOINT;
}
// Send the command over the request pipe....
if ((write(sRequestPipeFD, command, commandLength)) < commandLength) {
int errCode = errno;
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not send command to Scite, write(\"%s\") failed, errno = %d = %s",
__func__, command, errCode, strerror(errCode));
goto EXITPOINT;
}
resultCode = TRUE;
EXITPOINT:
return resultCode;
}
/**
* Activate our child SciTE instance (i.e. bring it to the front)
*
* @return TRUE if SciTE could be activated; FALSE otherwise (see err for more information)
*
* @param err returns any errors
*/
gboolean activate_scite(GError **err)
{
gboolean finalResult = FALSE;
XEvent event;
Window rootWindow;
long eventMask = SubstructureRedirectMask | SubstructureNotifyMask;
// Open the X11 display, if we haven't already done so
if (sDisplay == NULL) {
char *displayName = getenv("DISPLAY");
if (displayName == NULL || *displayName == '\0') {
displayName = (char*)":0.0";
}
sDisplay = XOpenDisplay(displayName);
if (sDisplay == NULL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not open X display, XOpenDisplay() = NULL", __func__);
goto EXITPOINT;
}
}
// Do we actually have a reference to the SciTE window?
if (sSciteWin == 0) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1,
"%s: Could not activate SciTE window, X11 window ID invalid", __func__);
goto EXITPOINT;
}
// Send the "_NET_ACTIVE_WINDOW" message to the ewmh-compliant window manager (we hope)
rootWindow = DefaultRootWindow(sDisplay);
event.xclient.type = ClientMessage;
event.xclient.window = sSciteWin;
event.xclient.message_type = XInternAtom(sDisplay, "_NET_ACTIVE_WINDOW", False);
event.xclient.format = 32;
event.xclient.data.l[0] = 1;
event.xclient.data.l[1] = 0;
event.xclient.data.l[2] = 0;
event.xclient.data.l[3] = 0;
event.xclient.data.l[4] = 0;
//~ g_print("%s: sDisplay = 0x%lX, message_type = 0x%lX, window = 0x%lX, rootWindow = 0x%lX\n", __func__, (long) sDisplay, (long) event.xclient.message_type, (long) event.xclient.window, (long) rootWindow);
if (!XSendEvent(sDisplay, rootWindow, False, eventMask, &event)) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Could not activate SciTE, XSendEvent() = FALSE", __func__);
}
XFlush(sDisplay);
XMapRaised(sDisplay, sSciteWin);
finalResult = TRUE;
EXITPOINT:
return finalResult;
}
/**
*
*/
void set_scite_launched(gboolean launched)
{
sSciteLaunched=launched;
}
/**
* scite_exists
*/
gboolean check_if_scite_exists()
{
// Check if a config-file exists
gboolean exists=FALSE;
#ifdef DEBUG_SCITE
debug_printf("gPrefs:%s\n",gPrefs.scite_path);
#endif
if (gPrefs.scite_path!=NULL) {
if (g_file_test(gPrefs.scite_path,G_FILE_TEST_EXISTS)) exists=TRUE;
} else {
if (g_file_test(sSciteExecName0,G_FILE_TEST_EXISTS)) exists=TRUE;
if (g_file_test(sSciteExecName1,G_FILE_TEST_EXISTS)) exists=TRUE;
// Check both
gchar *test_filename=NULL;
test_filename=g_build_filename("/bin",sSciteExecName2,NULL);
if (g_file_test(test_filename,G_FILE_TEST_EXISTS)) exists=TRUE;
if (test_filename!=NULL) g_free(test_filename);
test_filename=g_build_filename("/usr/bin",sSciteExecName2,NULL);
if (g_file_test(test_filename,G_FILE_TEST_EXISTS)) exists=TRUE;
if (test_filename!=NULL) g_free(test_filename);
test_filename=g_build_filename("/usr/local/bin",sSciteExecName2,NULL);
if (g_file_test(test_filename,G_FILE_TEST_EXISTS)) exists=TRUE;
if (test_filename!=NULL) g_free(test_filename);
test_filename=g_build_filename("/bin",sSciteExecName3,NULL);
if (g_file_test(test_filename,G_FILE_TEST_EXISTS)) exists=TRUE;
if (test_filename!=NULL) g_free(test_filename);
test_filename=g_build_filename("/usr/bin",sSciteExecName3,NULL);
if (g_file_test(test_filename,G_FILE_TEST_EXISTS)) exists=TRUE;
if (test_filename!=NULL) g_free(test_filename);
test_filename=g_build_filename("/usr/local/bin",sSciteExecName3,NULL);
if (g_file_test(test_filename,G_FILE_TEST_EXISTS)) exists=TRUE;
if (test_filename!=NULL) g_free(test_filename);
}
scite_exists=exists;
return exists;
}
/**
* init_scite_connection
* currently doesn't do anything on Linux
*/
void init_scite_connection()
{
}
/**
*
*/
gboolean open_filename(gchar *filename,gchar *project_directory,GError **err)
{
gchar *command=NULL;
if (!relative_path_to_abs_path(filename, &filename, project_directory, err)) {
return FALSE;
}
// It's a file, so try to open it
if ((command = g_strdup_printf("open:%s\n", filename)) == NULL) {
g_set_error(err, APP_SCITEPROJ_ERROR, -1, "%s: Error formatting Scite director command, g_strdup_printf() = NULL", __func__);
return FALSE;
}
else {
if (send_scite_command(command, err)) {
// Try to activate SciTE; ignore errors
activate_scite(NULL);
if (gPrefs.give_scite_focus==TRUE) {
send_scite_command((gchar*)"focus:0",NULL);
}
}
}
return TRUE;
}
sciteproj-0.7.08/src/about.c 0000644 0001750 0001750 00000025611 12143703722 015233 0 ustar gusnan gusnan /**
* about.c - about dialog for SciteProj
*
* Copyright 2008-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include "about.h"
#include "graphics.h"
#include "prefs.h"
gchar *homepage_string=(gchar*)"http://sciteproj.sourceforge.net";
gchar *sVersion = (gchar*)SCITEPROJ_VERSION;
static GtkWidget *window;
void create_about_dialog();
gboolean handle_about_close_event(GtkWidget *widget,GdkEvent *event,gpointer user_data);
void link_button_cb(GtkButton *button,gpointer user_data);
gchar *version_string=NULL;
/**
* show_about_dialog
* Shows the about dialog, and if it isnt already made, creates it
*/
void show_about_dialog()
{
if (!window)
create_about_dialog();
else
gtk_window_present(GTK_WINDOW(window));
}
/**
* creates a new dialog box, and fills it will all necessary information
*/
void create_about_dialog()
{
#if GTK_MAJOR_VERSION>=3
GtkWidget *grid;
#else
GtkWidget *vbox;
#endif
GtkWidget *textview_info;
GtkWidget *logo_image;
GtkWidget *linkbutton;
GtkWidget *ok_button;
GtkWidget *notebook;
GtkWidget *notebook_label1;
GtkWidget *notebook_label2;
GtkWidget *sciteproj_label;
GtkWidget *version_string_label;
GtkWidget *copyright_label;
GtkWidget *gtk_version_label;
GtkTextBuffer *textbuffer_info;
GtkTextBuffer *textbuffer_license;
GtkWidget *textview_license;
GtkTextIter iter;
gchar *copyrightstring;
// Make the dialog
window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width(GTK_CONTAINER(window), 8);
gtk_widget_set_size_request(window,500,400);
// Make a container
#if GTK_MAJOR_VERSION>=3
grid=gtk_grid_new();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_container_add(GTK_CONTAINER(window),grid);
#else
vbox=gtk_vbox_new(FALSE,5);
gtk_container_add(GTK_CONTAINER(window),vbox);
#endif
logo_image=gtk_image_new_from_pixbuf(program_icon_pixbuf);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach(GTK_GRID(grid),logo_image,0,0,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox), logo_image, FALSE, FALSE, 0);
#endif
sciteproj_label=gtk_label_new(NULL);
gtk_label_set_selectable(GTK_LABEL(sciteproj_label),FALSE);
gtk_label_set_markup(GTK_LABEL(sciteproj_label),"SciteProj");
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),sciteproj_label,logo_image,GTK_POS_BOTTOM,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox),sciteproj_label,FALSE,FALSE,0);
#endif
// Show version of SciteProj
gchar *about_dialog_version_string;
#ifdef _DEBUG
about_dialog_version_string=g_strdup_printf("%s DEBUG",version_string);
#else
about_dialog_version_string=g_strdup_printf("%s",version_string);
#endif
version_string_label=gtk_label_new(about_dialog_version_string);
gtk_label_set_selectable(GTK_LABEL(version_string_label),FALSE);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),version_string_label,sciteproj_label,GTK_POS_BOTTOM,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox),version_string_label,FALSE,FALSE,0);
#endif
// Show SciteProj copyrights
copyrightstring=g_strdup_printf("Copyright (C) 2008-2011 Andreas Rönnquist ");
copyright_label=gtk_label_new(copyrightstring);
gtk_label_set_selectable(GTK_LABEL(copyright_label),FALSE);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),copyright_label,version_string_label,GTK_POS_BOTTOM,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox),copyright_label,FALSE,FALSE,0);
#endif
// show GTK versions
gchar *gtk_string=g_strdup_printf("GTK+ %d.%d.%d / GLib %d.%d.%d",
//"Operating System: unknown",
gtk_major_version, gtk_minor_version, gtk_micro_version,
glib_major_version, glib_minor_version, glib_micro_version);
gtk_version_label=gtk_label_new(gtk_string);
gtk_label_set_selectable(GTK_LABEL(gtk_version_label),FALSE);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),gtk_version_label,copyright_label,GTK_POS_BOTTOM,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox),gtk_version_label,FALSE,FALSE,0);
GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
#endif
// Show a link to the SciteProj homepage
linkbutton=gtk_link_button_new_with_label(homepage_string,homepage_string);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),linkbutton,gtk_version_label,GTK_POS_BOTTOM,5,1);
#else
gtk_box_pack_start(GTK_BOX(hbox), linkbutton, TRUE, FALSE, 0);
#endif
// New notebook - we want tabs for different sets of text
notebook=gtk_notebook_new();
notebook_label1=gtk_label_new(_("Information"));
notebook_label2=gtk_label_new(_("License"));
// create a scrolled_window and a textview for the license
textbuffer_license=gtk_text_buffer_new(NULL);
gtk_text_buffer_get_start_iter(textbuffer_license,&iter);
gchar *sLicense = _("SciteProj is free software: you can redistribute it and/or modify "
"it under the terms of the GNU General Public License as published by "
"the Free Software Foundation, either version 3 of the License, or "
"(at your option) any later version.\n"
"\n"
"SciteProj is distributed in the hope that it will be useful, "
"but WITHOUT ANY WARRANTY; without even the implied warranty of "
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the "
"GNU General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU General Public License "
"along with SciteProj. If not, see .\n");
gtk_text_buffer_insert(textbuffer_license,&iter,sLicense,-1);
textview_license=gtk_text_view_new_with_buffer(textbuffer_license);
gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview_license),GTK_WRAP_WORD);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview_license),TRUE);
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview_license),FALSE);
GtkWidget *scrolled_window_license;
scrolled_window_license=gtk_scrolled_window_new(NULL,NULL);
// Never show horisontal scrollbar, always show vertical
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window_license),GTK_POLICY_NEVER,GTK_POLICY_ALWAYS);
gtk_container_add(GTK_CONTAINER(scrolled_window_license),textview_license);
// New textbuffer - and we get the beginning of the textbuffer
textbuffer_info=gtk_text_buffer_new(NULL);
gtk_text_buffer_get_start_iter(textbuffer_info,&iter);
gchar *about_text2=g_strdup_printf(""
"%s\n"
"Roy Wood and\n"
"Martin Andrews \n\n"
"%s\n"
"Mattias Wecksten \n"
"Frank Wunderlich\n\n"
"%s",
_("SciteProj is based on ScitePM by"),
_("Many thanks to"),
_("For more information about SciteProj, see the README file that\n"
"is provided with this package."));
gchar *text_to_add;
#ifdef _DEBUG
gchar *prefs_dir_string=g_strdup_printf("Preferences loaded from %s",prefs_filename);
text_to_add=g_strdup_printf("%s\n\n%s",about_text2,
prefs_dir_string);
#else
text_to_add=about_text2;
#endif
gtk_text_buffer_insert(textbuffer_info,&iter,text_to_add,-1);
gtk_text_buffer_get_end_iter(textbuffer_info,&iter);
// Setup the textview and windows
textview_info=gtk_text_view_new_with_buffer(textbuffer_info);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(textview_info),TRUE);
gtk_text_view_set_editable(GTK_TEXT_VIEW(textview_info),FALSE);
GtkWidget *scrolled_window_info;
scrolled_window_info=gtk_scrolled_window_new(NULL,NULL);
// Never show horisontal scrollbar, always show vertical
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window_info),GTK_POLICY_NEVER,GTK_POLICY_ALWAYS);
gtk_container_add(GTK_CONTAINER(scrolled_window_info),textview_info);
//gtk_box_pack_start(GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrolled_window_info,notebook_label1);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook),scrolled_window_license,notebook_label2);
#if GTK_MAJOR_VERSION>=3
gtk_widget_set_vexpand(notebook,TRUE);
gtk_widget_set_hexpand(notebook,TRUE);
gtk_grid_attach_next_to(GTK_GRID(grid),notebook,linkbutton/*gtk_version_label*/,GTK_POS_BOTTOM,5,1);
#else
gtk_box_pack_start(GTK_BOX(vbox), notebook,TRUE,TRUE,0);
#endif
gtk_text_buffer_place_cursor(textbuffer_info,&iter);
gtk_text_buffer_select_range (textbuffer_info,&iter,&iter);
// Create an ok button
ok_button=gtk_button_new_from_stock(GTK_STOCK_OK);
#if GTK_MAJOR_VERSION>=3
gtk_widget_set_halign(ok_button,GTK_ALIGN_END);
gtk_widget_set_hexpand(ok_button,FALSE);
#endif
//gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
// gtk_grid_attach_next_to(GTK_GRID(grid),hbox,notebook,GTK_POS_BOTTOM,5,1);
#if GTK_MAJOR_VERSION>=3
gtk_grid_attach_next_to(GTK_GRID(grid),ok_button,notebook,GTK_POS_BOTTOM,5,1);
#else
GtkWidget *ok_button_hbox=gtk_hbox_new(FALSE,0);
gtk_box_pack_end(GTK_BOX(ok_button_hbox),ok_button,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(vbox),ok_button_hbox,FALSE,FALSE,0);
#endif
gtk_widget_grab_focus(ok_button);
gtk_text_buffer_get_start_iter(textbuffer_info, &iter);
gtk_text_buffer_place_cursor(textbuffer_info, &iter);
g_signal_connect_closure
(G_OBJECT(ok_button), "clicked",
g_cclosure_new_swap(G_CALLBACK(gtk_widget_hide_on_delete),
window, NULL), FALSE);
g_signal_connect(G_OBJECT(window),"delete-event",G_CALLBACK(handle_about_close_event),window);
g_signal_connect(G_OBJECT(linkbutton),"released",G_CALLBACK(link_button_cb),linkbutton);
gtk_widget_show_all(window);
}
/**
* Show version
*/
void show_version()
{
g_print("SciteProj %s\n",version_string);
}
/**
*
*/
gboolean handle_about_close_event(GtkWidget *widget,GdkEvent *event,gpointer user_data)
{
gtk_widget_hide(window);
return TRUE;
}
/**
* Callback for the link button, Without this, it would color the text purple when the
* link is followed, which I found really ugly.
*/
void link_button_cb(GtkButton *button,gpointer user_data)
{
GtkWidget *linkbutton=(GtkWidget*)(user_data);
gtk_link_button_set_visited(GTK_LINK_BUTTON(linkbutton),FALSE);
}
/**
*
*/
void init_version_string()
{
version_string=g_strdup_printf(_("version %s"),SCITEPROJ_VERSION);
}
/**
*
*/
void done_version_string()
{
g_free(version_string);
}
sciteproj-0.7.08/src/file_utils.c 0000644 0001750 0001750 00000007052 12143703722 016257 0 ustar gusnan gusnan /**
* file_utils.c - file utilities for SciteProj
*
* Copyright 2009-2012 Andreas Rönnquist
*
* This file is part of SciteProj.
*
* SciteProj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SciteProj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SciteProj. If not, see .
*
*/
#include
#include
#include
#include
#include "file_utils.h"
/**
*
*/
gchar *current_directory=0;
/**
*
*/
gboolean is_separator(gchar ch)
{
gboolean result=FALSE;
if ((ch=='/') || (ch==G_DIR_SEPARATOR) || (ch=='\\')) {
result=TRUE;
}
return result;
}
/**
*
*/
gchar *path_up_string(gchar *instring)
{
int len=(int)strlen(instring);
int co;
int start=len--;
if (is_separator(instring[start])) {
start--;
}
int res=-1;
for (co=start;co>0;co--) {
if (is_separator(instring[co])) {
if (res==-1) res=co;
}
}
gchar *resstring=g_strdup_printf("%s",instring);
if (res!=-1) {
resstring[res]='\0';
}
return resstring;
}
/**
* fix_separators
*
* Replaces \\ and \ and // with /, and replaces stuff like /./ with just one separator
*/
gchar *fix_separators(gchar *source)
{
gchar *result=g_strdup(source);
gchar *pointer=result;
if (pointer) {
int co=0;
for (co=0;co