diff --git a/Makefile.in b/Makefile.in index 9bf6c6a..e6dc06b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -49,7 +49,8 @@ SOURCES= \ $(wildcard src/dialogs/print/*.c) \ $(wildcard src/dialogs/save/*.c) \ $(wildcard src/dialogs/font/*.c) \ - $(wildcard src/dialogs/settings/*.c) + $(wildcard src/dialogs/settings/*.c) \ + $(wildcard src/tools/*.c) TEST_SOURCES= \ $(wildcard src/testprogram/*.c) @@ -149,6 +150,11 @@ $(OBJDBG)/%.o: \ @$(CC) \ $(CFLAGS) \ + -DDEBUG=1 \ + -MM -MT $@ -MF $(patsubst %.o,%.d,$@) $< + + @$(CC) \ + $(CFLAGS) \ -Wall -Wextra -fstack-check \ -DDEBUG=1 \ -o $@ -c $< @@ -177,6 +183,13 @@ $(OBJRLS)/%.o: \ @echo $< ... @$(MKDIR) $(dir $@) + + @$(CC) \ + $(CFLAGS) \ + -DNDEBUG=1 \ + -MM -MT $@ -MF $(patsubst %.o,%.d,$@) $< + + @$(CC) \ $(CFLAGS) \ -DNDEBUG=1 \ @@ -564,4 +577,8 @@ clean: \ cleanDebug \ cleanRelease +-include $(foreach SRC, $(basename $(SOURCES)), $(OBJDBG)/$(SRC).d) +-include $(foreach SRC, $(basename $(SOURCES)), $(OBJRLS)/$(SRC).d) + + diff --git a/src/include/v3270/tools.h b/src/include/v3270/tools.h new file mode 100644 index 0000000..8f1cca8 --- /dev/null +++ b/src/include/v3270/tools.h @@ -0,0 +1,46 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como tools.h e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#ifndef V3270_TOOLS_H_INCLUDED + + #include + #include + + G_BEGIN_DECLS + + /// @brief Bind pointer to widget; release it when widget is destroyed. + LIB3270_EXPORT void gtk_widget_bind_ptr(GtkWidget *widget, gpointer ptr); + + /// @brief Bind file chooser with entry field. + LIB3270_EXPORT void gtk_entry_bind_to_filechooser(GtkWidget *widget, GtkFileChooserAction action, const gchar *title, const gchar *icon_name, const gchar *pattern, const gchar *name); + + G_END_DECLS + +#endif // V3270_TOOLS_H_INCLUDED + diff --git a/src/tools/entry.c b/src/tools/entry.c new file mode 100644 index 0000000..81a4275 --- /dev/null +++ b/src/tools/entry.c @@ -0,0 +1,177 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + + /** + * @brief Usefull extensions for GtkEntry. + * + */ + + #include + #include + #include + + struct FileEntry { + GtkFileChooserAction action; + const gchar * title; + const gchar * pattern; + const gchar * name; + const gchar * accept; + }; + + static void icon_response(GtkDialog *dialog, int response_id, GtkEntry *entry) { + + if(response_id == GTK_RESPONSE_ACCEPT) { + + g_autofree gchar * filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + + if(filename) { + + // https://github.com/PerryWerneck/pw3270/issues/9#issuecomment-708963229 + // + // Works here (openSUSE Tumbleweed), BUT: the "open session" dialog comes with a filter + // set to "TN3270 files" and that's good, but when you save a session pw3270 does NOT add + // the extension, so how do you know what file extension those "TN3270 files" are supposed to have? + // + // I tried .tn3270 but it did not work, so I had to look hard in the internet to find out this page + // ... + // + if(strchr(filename,'.')) { + + // Filename has extension, use it. + gtk_entry_set_text(entry,filename); + + } else { + + // No extension, add it from the standard. + const gchar *ext = (const gchar *) g_object_get_data(G_OBJECT(dialog),"default-file-extension"); + if(ext) { + g_autofree gchar * new_name = g_strconcat(filename,ext,NULL); + gtk_entry_set_text(entry,new_name); + } else { + g_warning("No default file extension set"); + gtk_entry_set_text(entry,filename); + } + + } + + } else { + gtk_entry_set_text(entry,""); + } + } + + gtk_widget_destroy(GTK_WIDGET(dialog)); + + } + + static void icon_press(GtkWidget *entry, G_GNUC_UNUSED GtkEntryIconPosition icon_pos, G_GNUC_UNUSED GdkEvent *event, const struct FileEntry *descr) { + + GtkWidget * dialog = + gtk_file_chooser_dialog_new( + gettext(descr->title), + GTK_WINDOW(gtk_widget_get_toplevel(entry)), + descr->action, + _("Cancel"), GTK_RESPONSE_CANCEL, + descr->accept, GTK_RESPONSE_ACCEPT, + NULL + ); + + { + GtkFileFilter *filter; + + // Standard filter + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern (filter, descr->pattern); + gtk_file_filter_set_name(filter, gettext(descr->name)); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter); + + const gchar *ext = strchr(descr->pattern,'.'); + if(ext) { + g_object_set_data_full(G_OBJECT(dialog),"default-file-extension",g_strdup(ext),g_free); + } + + // All files + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern (filter, "*.*"); + gtk_file_filter_set_name(filter, _("All files")); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter); + + } + + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); + gtk_window_set_deletable(GTK_WINDOW(dialog),FALSE); + + const gchar *filename = gtk_entry_get_text(GTK_ENTRY(entry)); + + if(filename && *filename) + gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),filename); + + g_signal_connect(dialog,"close",G_CALLBACK(gtk_widget_destroy),NULL); + g_signal_connect(dialog,"response",G_CALLBACK(icon_response),entry); + + gtk_widget_show_all(dialog); + + + } + + static void release_ptr(GtkWidget G_GNUC_UNUSED(*object), gpointer ptr) { + g_free(ptr); + } + + LIB3270_EXPORT void gtk_widget_bind_ptr(GtkWidget *widget, gpointer ptr) { + g_signal_connect(widget,"destroy",G_CALLBACK(release_ptr),ptr); + } + + LIB3270_EXPORT void gtk_entry_bind_to_filechooser(GtkWidget *widget, GtkFileChooserAction action, const gchar *title, const gchar *icon_name, const gchar *pattern, const gchar *name) { + + gtk_entry_set_icon_from_icon_name( + GTK_ENTRY(widget), + GTK_ENTRY_ICON_SECONDARY, + icon_name ? icon_name : "document-open" + ); + + // Store data + gsize szEntry = sizeof(struct FileEntry) + strlen(title) + strlen(pattern) + strlen(name) + 4; + struct FileEntry * entry = (struct FileEntry *) g_malloc0(szEntry); + gtk_widget_bind_ptr(widget,entry); + + entry->action = action; + entry->accept = _("Continue"); + + entry->title = (const char *) (entry+1); + strcpy((char *) entry->title,title); + + entry->pattern = entry->title + strlen(entry->title) +1; + strcpy((char *) entry->pattern,pattern); + + entry->name = entry->pattern + strlen(entry->pattern) + 1; + strcpy((char *) entry->name,name); + + g_signal_connect(widget,"icon_press",G_CALLBACK(icon_press),(gpointer) entry); + + } diff --git a/v3270.cbp b/v3270.cbp index d0b1f4c..65928bd 100644 --- a/v3270.cbp +++ b/v3270.cbp @@ -198,6 +198,7 @@ +