diff options
Diffstat (limited to 'app/wlib/gtklib')
28 files changed, 956 insertions, 607 deletions
diff --git a/app/wlib/gtklib/CMakeLists.txt b/app/wlib/gtklib/CMakeLists.txt index a8cae9f..bf20e91 100644 --- a/app/wlib/gtklib/CMakeLists.txt +++ b/app/wlib/gtklib/CMakeLists.txt @@ -1,9 +1,7 @@ +# Setup GTK UI library... +file(GLOB headers *.h) -FILE(GLOB HEADERS *.h) - -INCLUDE (FindGTKUnixPrint.cmake) - -SET(SOURCES +set(sources bitmap.c boxes.c button.c @@ -25,6 +23,7 @@ SET(SOURCES print.c single.c splash.c + statusbar.c text.c timer.c tooltip.c @@ -32,32 +31,43 @@ SET(SOURCES util.c window.c wpref.c -# cproto and cppcheck - # end of refactored sources gtkdraw-cairo.c ) -IF(APPLE) - SET(SOURCES - ${SOURCES} - osxhelp.c) - -ELSE(APPLE) - SET(SOURCES - ${SOURCES} - ixhelp.c) -ENDIF(APPLE) - -SET_SOURCE_FILES_PROPERTIES(wpref.c PROPERTIES COMPILE_FLAGS -DEXPORT=) - -INCLUDE_DIRECTORIES(${XTrkCAD_BINARY_DIR}) -INCLUDE_DIRECTORIES(${GTK_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${GTK_UNIX_PRINT_INCLUDE_DIRS}) -INCLUDE_DIRECTORIES(${GTK_WEBKIT_INCLUDE_DIRS}) - -ADD_LIBRARY(xtrkcad-wlib ${HEADERS} ${SOURCES}) -TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_LIBRARIES}) -TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_UNIX_PRINT_LIBRARIES}) -TARGET_LINK_LIBRARIES(xtrkcad-wlib ${GTK_WEBKIT_LIBRARIES}) +# help system is OS and build specific, add appropriate source files +if(APPLE) + set(sources + ${sources} + osxhelp.c) +else() + if(XTRKCAD_USE_BROWSER) + set(sources + ${sources} + browserhelp.c) + else() + set(sources + ${sources} + ixhelp.c) + endif() +endif() + +include_directories(${XTrkCAD_BINARY_DIR}) + +add_library(xtrkcad-wlib ${headers} ${sources}) + +# GTK +include_directories(${GTK_INCLUDE_DIRS}) +target_link_libraries(xtrkcad-wlib ${GTK_LIBRARIES}) + +# configure for GTK's native Unix print +find_package (GTKUnixPrint) +include_directories(${GTK_UNIX_PRINT_INCLUDE_DIRS}) +target_link_libraries(xtrkcad-wlib ${GTK_UNIX_PRINT_LIBRARIES}) + +# add dependency to webkit if configured +if(NOT XTRKCAD_USE_BROWSER) + include_directories(${GTK_WEBKIT_INCLUDE_DIRS}) + target_link_libraries(xtrkcad-wlib ${GTK_WEBKIT_LIBRARIES}) +endif() diff --git a/app/wlib/gtklib/ChangeLog b/app/wlib/gtklib/ChangeLog deleted file mode 100644 index ef2bd09..0000000 --- a/app/wlib/gtklib/ChangeLog +++ /dev/null @@ -1,250 +0,0 @@ -Apr 28, 2010 - FIX: Daniel Spagnol - gtkwindow.c, wpref.c: now, wGetAppLibDir can be called before - wWinMainCreate is called. - -Dec 12, 2009 - FIX: Martin Fischer - gtkint.h, gtkwindow.c: refactoring, remove unused globals and - added some comments. - -Dec 07, 2010 - FIX: Martin Fischer / Robert Heller - gtkfont.c: use newer Pango functions only after checking for correct - version at compile time. - -Oct 03, 2009 - FIX: Daniel Spagnol - gtkdraw-cairo.c: linux still crashed due to a cairo context access - after its drawable destruction - -Oct 03, 2009 - FIX: Daniel Spagnol - gtkbutton.c gtkint.h gtkmenu.c gtkmisc.c: workaround for OSX with - GTK-Quartz -> pixmaps are not rendered when using the mask; - and replaced gtk_pixmap_new deprecated function with - gtk_image_new_from_pixmap - -Oct 02, 2009 - FIX: Daniel Spagnol - gtkdraw-cairo.c: linux crashed due to a cairo context access after its - drawable destruction - -Sep 27, 2009 - FIX: Daniel Spagnol - gtkbitmap.c: image in about dialog box was not being displayed - -Sep 26, 2009 - FIX: Daniel Spagnol - gtkfont: deallocate PangoFontDescription using the right function - -Sep 25, 2009 - FIX: Daniel Spagnol - gtkbitmap.c: EXC_BAD_ACCESS when displaying about dialog - -Sep 25, 2009 - ENH: Daniel Spagnol - gtkdraw-cairo.c gtkdraw.c gtkfont.c gtkint.h gtksimple.c wlib.h: - replace the old font select dialog with the GTK standard one, and some - code cleanup - -Sep 23, 2009 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkbitmap.c gtkmisc.c: implement wCreateBitmap - -Sep 22, 2009 - FIX: Daniel Spagnol - gtkdraw-cairo.c: text in layout and selection were not aligned - -Sep 22, 2009 - FIX: Daniel Spagnol - CMakeLists.txt gtkbitmap.c gtkint.h: file created as a workaround to - get the source compiled under POSIX and OSX after wCreateBitmap - feature - -Aug 12, 2009 - ENH: Matthew Sheets - wpref.c: initialize with system default config from /etc - -Jul 29, 2009 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - wpref.c: Create directory .xtrkcad silently - -Jun 24, 2009 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - gtkwindow.c gtkmisc.c gtkint.h wpref.c: add option - to select configuration file - -Version 4.0.3a -============== - - -Jun 09, 2009 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkdraw.c: Fix compiler warning -May 31, 2009 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtksplash.c: popups during startup are now shown above - splash screen - -May 31, 2009 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkmisc.c: fixed problem with some icons - -May 30, 2009 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtklist.c: fixed the 'missing scrollbar' bug - finally! - -May 29, 2008 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkmisc.c: bug fix in wNoticeEx - -May 21, 2009 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - gtkhelp.c: better error message - -May 15, 2009 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - gtkwindow.c, gtkmisc.c, psprint.c, gtktext.c - gtkfilsel.c, gtksingle.c: new message box with icon - -Jul 11, 2008 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - gtkwindow.c: closing app can now be canceled by the user - -Jul 11, 2008 - ENH: Steve DeCaux - gtdraw-cairo.c: convert strings to UTF8 - -Jul 01, 2008 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - gtksplash.c: added #ifdef's for backward compatibility to GTK 2.4 - -Feb 01. 2008 - ENH: Martin Fischer <m_fischer@users.sourceforge.net> - psprint.c, gtkint.h: added file selector for print to file, made - Postscript digit representation independent of current locale - -Jan 28, 2008 - ENH: Mikko Nissinen <mni77@users.sourceforge.net> - gtkfilsel.c: Gettext support added. - -Jan 28, 2008 - FIX: Mikko Nissinen <mni77@users.sourceforge.net> - gtkwindow.c: Dynamically allocate and form some global translatable - strings. - -Jan 27, 2008 - FIX: Mikko Nissinen <mni77@users.sourceforge.net> - gtkhelp.c: String XTrkCad changed to XTrackCAD. - -Jan, 27, 2008 - FIX: Mikko Nissinen <mni77@users.sourceforge.net> - gtkwindows.c: fixed problem with missing scroll bars - -Jan 24,2008 - IMPROVMENT: Martin Fischer <m_fischer@users.sourceforge.net> - wpref.c: increase floting point precision when storing floats in rc - file - -Jan 22, 2008 - ENH: Mikko Nissinen <mni77@users.sourceforge.net> - gtkwindow.c: wExit(): Free user locale before exit. - -Jan 21, 2008 - ENH: Gettext support added. Modified files: - gtkbutton.c - gtkfont.c - gtkhelp.c - gtklist.c - psprint.c - wpref.c - -Jan 20, 2008 - FIX: Mikko Nissinen <mni77@users.sourceforge.net> - gtkdraw.c/gtkdraw-cairo.c: wDrawSetSize(): Return immediately, - if given width or height is negative. Negative values crashed - the program. This can be seen at least in Add Turnout and Add - Structure dialogs by resizing the dialog vertically smaller. - -Jan 16, 2008 - FIX: Mikko Nissinen <mni77@users.sourceforge.net> - gtkmisc.c: gtkConvertInput(): If the input string is already - UTF-8 encoded, then return it untouched. - -Jan 15, 2008 - IMPROVEMENT: Mikko Nissinen <mni77@users.sourceforge.net> - Basic gettext support added. - CMakeLists.txt - -Nov 30, 2007 - FIX: Timothy M. Shead - gtkfont.c: make sure that font initialization is run first - -Nov 29, 2007 - FIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkhelp.c: an existing help window is now brought to the foreground - if the user selects Help - -Nov 12, 2007 - FIX: Mikko Nissinen <mni77@users.sourceforge.net> - gtksimple.c: wMessageCreateEx -> Reset the pango font size back - to normal before returning the function. All dialogs created after - the tip of the day dialog had incorrectly positioned labels, - because the width of the text was calculated with the large font. - -Nov 12, 2007 - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - gtkhelp.c: Converted help system to gtkhtml-2. This allows to - us standard HTML files to be used for help documentation. - -Oct 28, 2007 - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - gtkmenu.c: Help drop-down is no longer right aligned. - -Sep 28, 2007 - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - gtksimple.c: wMessageCreate has been extended to - wMessageCreateEx. New function allows adding flags. Setting - a large or a small font are first uses. Added a compatibility - macro wMessageCreate for older code. - -Sep 15, 2007 - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - gtksplash.c: added splash window for program startup - -Jul 24, 2007 - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - gtkdraw.c: added support for wheel mouse - -Jun 16, 2007 - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - wpref.c: added wGetUserHomeDir() - -Feb 25, 2007 - BUGFIX: Martin Fischer <m_fischer@users.sourceforge.net> - wpref.c: Rephrased error message for lib-directory not found - -Feb 23, 2007 - BUGFIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkfont.c: Typo in window title corrected - -Version 4.0.1 -============= - -Mar, 30th 2006 - BUGFIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkmisc.c: changed wPause to use SYSV signal handling funtions - -Mar, 29th 2006 - BUGFIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkmisc.c, gtkbutton.c, gtksimple.c: small changes to help Solaris port - - IMPROVEMENT: Martin Fischer <m_fischer@users.sourceforge.net> - wpref.c: Optimized the checking for directories in wGetAppLibDir and - rephrased the error message if initialization files cannot be found - - BUGFIX: Martin Fischer <m_fischer@users.sourceforge.net> - gtkwindow.c: Fixed resizing problems when enlarging dialog boxes - - BUGFIX: diff --git a/app/wlib/gtklib/FindGTKUnixPrint.cmake b/app/wlib/gtklib/FindGTKUnixPrint.cmake deleted file mode 100644 index 06bc548..0000000 --- a/app/wlib/gtklib/FindGTKUnixPrint.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# - Try to find gtk-unix-print -# Once done, this will define -# -# GTK_UNIX_PRINT_FOUND - system has gtk-unix-print -# GTK_UNIX_PRINT_INCLUDE_DIRS - the gtk-unix-print include directories -# GTK_UNIX_PRINT_LIBRARIES - link these to use gtk-unix-print -# -# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org> -# Copyright (C) 2014 Igalia S.L. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS -# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -find_package(PkgConfig) -pkg_check_modules(GTK_UNIX_PRINT gtk+-unix-print-2.0) -set(VERSION_OK TRUE) - -if (GTK_UNIX_PRINT_VERSION) - if (GTK_UNIX_PRINT_FIND_VERSION_EXACT) - if (NOT("${GTK_UNIX_PRINT_FIND_VERSION}" VERSION_EQUAL "${GTK_UNIX_PRINT_VERSION}")) - set(VERSION_OK FALSE) - endif () - else () - if ("${GTK_UNIX_PRINT_VERSION}" VERSION_LESS "${GTK_UNIX_PRINT_FIND_VERSION}") - set(VERSION_OK FALSE) - endif () - endif () -endif () - -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK_UNIX_PRINT DEFAULT_MSG GTK_UNIX_PRINT_INCLUDE_DIRS GTK_UNIX_PRINT_LIBRARIES VERSION_OK) diff --git a/app/wlib/gtklib/bitmap.c b/app/wlib/gtklib/bitmap.c index dc7236b..eb5ef94 100644 --- a/app/wlib/gtklib/bitmap.c +++ b/app/wlib/gtklib/bitmap.c @@ -67,6 +67,7 @@ wBitmapCreate( wWin_p parent, wPos_t x, wPos_t y, long options, wIcon_p iconP ) /* create the bitmap from supplied xpm data */ pixbuf = gdk_pixbuf_new_from_xpm_data( (const char **)iconP->bits ); + g_object_ref_sink(pixbuf); image = gtk_image_new_from_pixbuf( pixbuf ); gtk_widget_show( image ); g_object_unref( (gpointer)pixbuf ); diff --git a/app/wlib/gtklib/boxes.c b/app/wlib/gtklib/boxes.c index cce6649..cf419e6 100644 --- a/app/wlib/gtklib/boxes.c +++ b/app/wlib/gtklib/boxes.c @@ -129,6 +129,7 @@ void wlibDrawBox( cairo_stroke_preserve(cr); if (style < wBoxThickB) { + cairo_destroy(cr); return; } diff --git a/app/wlib/gtklib/browserhelp.c b/app/wlib/gtklib/browserhelp.c new file mode 100644 index 0000000..9351e86 --- /dev/null +++ b/app/wlib/gtklib/browserhelp.c @@ -0,0 +1,137 @@ +/** \file browserhelp.c + * use the default browser based help + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2015 Martin Fischer + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <stdlib.h> +#include <assert.h> + +#include "gtkint.h" +#include "i18n.h" + +#include "dynstring.h" + +#define DEFAULTBROWSERCOMMAND "xdg-open" + +#define HELPERRORTEXT "Help Error - help information can not be found.\n" \ + "The help information you requested cannot be shown.\n" \ + "Usually this is an installation problem, Make sure that a default browser" \ + " is configured and that XTrackCAD and the included " \ + "HTML files are installed properly and can be found via the XTRKCADLIB environment " \ + "variable.\n Also make sure that the user has sufficient access rights to read these" \ + "files." +/** + * Create a fully qualified url froma topic + * + * \param helpUrl OUT pointer to url, free by caller + * \param topic IN the help topic + */ + +static void +TopicToUrl(char **helpUrl, const char *topic) +{ + DynString url; + DynStringMalloc(&url, 16); + + // build up the url line + DynStringCatCStrs(&url, + "file://", + wGetAppLibDir(), + "/html/", + topic, + ".html", + NULL); + + *helpUrl = strdup(DynStringToCStr(&url)); + DynStringFree(&url); +} +/** + * Extend the PATH variable inthe environment to include XTrackCAD's + * script directory. + * + * \return pointer to old path + */ + +static char * +ExtendPath(void) +{ + char *path = getenv("PATH"); + DynString newPath; + DynStringMalloc(&newPath, 16); + + // append XTrackCAD's directory to the path as a fallback + DynStringCatCStrs(&newPath, + path, + ":", + wGetAppLibDir(), + NULL); + + setenv("PATH", + DynStringToCStr(&newPath), + TRUE); + + DynStringFree(&newPath); + + return (path); +} + +/** + * Invoke the system's default browser to display help for <topic>. First the + * system's standard xdg-open command is attempted. If that is not available, the + * version included with the XTrackCAD installation is executed. + * + * \param topic IN topic string + */ + +void wHelp(const char * topic) +{ + int rc; + char *url; + DynString commandLine; + char *currentPath; + + assert(topic != NULL); + assert(strlen(topic)); + + currentPath = ExtendPath(); + TopicToUrl(&url, topic); + + DynStringMalloc(&commandLine, 16); + DynStringCatCStrs(&commandLine, + DEFAULTBROWSERCOMMAND, + " ", + url, + NULL); + + // the command should be found via the PATH + rc = system(DynStringToCStr(&commandLine)); + + if (rc) { + wNotice(HELPERRORTEXT, _("Cancel"), NULL); + } + + // restore the PATH + setenv("PATH", + currentPath, + TRUE); + + free(url); + DynStringFree(&commandLine); +} diff --git a/app/wlib/gtklib/button.c b/app/wlib/gtklib/button.c index d9f4880..b5fabe8 100644 --- a/app/wlib/gtklib/button.c +++ b/app/wlib/gtklib/button.c @@ -101,8 +101,8 @@ void wlibSetLabel( } else { gtk_image_set_from_pixbuf(GTK_IMAGE(*imageG), pixbuf); } - - g_object_unref(pixbuf); + g_object_ref_sink(pixbuf); + g_object_unref((gpointer)pixbuf); } else { if (*labelG==NULL) { *labelG = (GtkLabel*)gtk_label_new(wlibConvertInput(labelStr)); diff --git a/app/wlib/gtklib/control.c b/app/wlib/gtklib/control.c index e824c94..c891924 100644 --- a/app/wlib/gtklib/control.c +++ b/app/wlib/gtklib/control.c @@ -109,7 +109,9 @@ wPos_t wLabelWidth( GtkRequisition requisition; widget = gtk_label_new(wlibConvertInput(label)); gtk_widget_size_request(widget, &requisition); + g_object_ref_sink (widget); gtk_widget_destroy(widget); + g_object_unref(widget); return requisition.width+8; } @@ -162,7 +164,7 @@ wPos_t wControlGetPosX( wPos_t wControlGetPosY( wControl_p b) /* Control */ { - return b->realY - BORDERSIZE - ((b->parent->option&F_MENUBAR)?MENUH:0); + return b->realY - BORDERSIZE - ((b->parent->option&F_MENUBAR)?b->parent->menu_height:0); } /** @@ -179,15 +181,21 @@ void wControlSetPos( wPos_t y) { b->realX = x; - b->realY = y + BORDERSIZE + ((b->parent->option&F_MENUBAR)?MENUH:0); + b->realY = y + BORDERSIZE + ((b->parent->option&F_MENUBAR)?b->parent->menu_height:0); if (b->widget) { gtk_fixed_move(GTK_FIXED(b->parent->widget), b->widget, b->realX, b->realY); } if (b->label) { + GtkRequisition requisition, reqwidget; + gtk_widget_size_request(b->label, &requisition); + if (b->widget) + gtk_widget_size_request(b->widget, &reqwidget); + else + reqwidget.height = requisition.height; gtk_fixed_move(GTK_FIXED(b->parent->widget), b->label, b->realX-b->labelW, - b->realY+LABEL_OFFSET); + b->realY+(reqwidget.height/2 - requisition.height/2)); } } @@ -202,14 +210,18 @@ void wControlSetLabel( wControl_p b, const char * labelStr) { - GtkRequisition requisition; + GtkRequisition requisition,reqwidget; if (b->label) { gtk_label_set_text(GTK_LABEL(b->label), wlibConvertInput(labelStr)); gtk_widget_size_request(b->label, &requisition); + if (b->widget) + gtk_widget_size_request(b->widget, &reqwidget); + else + reqwidget.height = requisition.height; b->labelW = requisition.width+8; gtk_fixed_move(GTK_FIXED(b->parent->widget), b->label, b->realX-b->labelW, - b->realY+LABEL_OFFSET); + b->realY+(reqwidget.height/2 - requisition.height/2)); } else { b->labelW = wlibAddLabel(b, labelStr); } diff --git a/app/wlib/gtklib/droplist.c b/app/wlib/gtklib/droplist.c index 3252905..5fbdd17 100644 --- a/app/wlib/gtklib/droplist.c +++ b/app/wlib/gtklib/droplist.c @@ -416,7 +416,7 @@ wList_p wDropListCreate( if (b->widget == 0) { abort(); } - + g_object_ref_sink(b->listStore); g_object_unref(G_OBJECT(b->listStore)); wlibDropListAddColumns(b->widget, DROPLIST_TEXTCOLUMNS); diff --git a/app/wlib/gtklib/font.c b/app/wlib/gtklib/font.c index c54f7de..68ba87b 100644 --- a/app/wlib/gtklib/font.c +++ b/app/wlib/gtklib/font.c @@ -86,7 +86,7 @@ static void fontSelectionDialogCallback(GtkFontSelectionDialog *fontSelectionDialog, gint response, gpointer data) { if (response == GTK_RESPONSE_APPLY || response == GTK_RESPONSE_OK) { - gchar *fontName; + gchar *fontName; fontName = gtk_font_selection_dialog_get_font_name(fontSelectionDialog); wPrefSetString("font", "name", fontName); @@ -215,12 +215,14 @@ PangoLayout *wlibFontCreatePangoLayout(GtkWidget *widget, pango_layout_set_font_description(layout, fontDescription); /* get layout measures */ pango_layout_get_pixel_size(layout, width_p, height_p); - context = gtk_widget_get_pango_context(widget); + context = gtk_widget_create_pango_context(widget); metrics = pango_context_get_metrics(context, fontDescription, pango_context_get_language(context)); *ascent_p = PANGO_PIXELS(pango_font_metrics_get_ascent(metrics)); *descent_p = PANGO_PIXELS(pango_font_metrics_get_descent(metrics)); pango_font_metrics_unref(metrics); + g_object_ref_sink(context); + g_object_unref(context); #if WLIB_FONT_DEBUG >= 3 fprintf(stderr, "font layout created:\n"); fprintf(stderr, " widget: %p\n", widget); @@ -242,7 +244,8 @@ PangoLayout *wlibFontCreatePangoLayout(GtkWidget *widget, void wlibFontDestroyPangoLayout(PangoLayout *layout) { - g_object_unref(G_OBJECT(layout)); + g_object_ref_sink(layout); + g_object_unref(layout); } /** @@ -286,7 +289,7 @@ void wSelectFont( gtk_window_set_title(GTK_WINDOW(fontSelectionDialog), title); if (curFont != NULL) { - gchar *fontName; + gchar *fontName; /* the curFont description contains the latest font info * which is depended on the current scale diff --git a/app/wlib/gtklib/gtkdraw-cairo.c b/app/wlib/gtklib/gtkdraw-cairo.c index a19eb2b..4f3b1d2 100644 --- a/app/wlib/gtklib/gtkdraw-cairo.c +++ b/app/wlib/gtklib/gtkdraw-cairo.c @@ -174,8 +174,9 @@ static cairo_t* gtkDrawCreateCairoContext( } case wDrawLineDash: { - double dashes[] = { 5, 5 }; - cairo_set_dash(cairo, dashes, 2, 0); + double dashes[] = { 5, 3 }; + static int len_dashes = sizeof(dashes) / sizeof(dashes[0]); + cairo_set_dash(cairo, dashes, len_dashes, 0); break; } } @@ -183,13 +184,14 @@ static cairo_t* gtkDrawCreateCairoContext( if(opts & wDrawOptTemp) { cairo_set_source_rgba(cairo, 0, 0, 0, 0); + cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); } else { GdkColor* const gcolor = wlibGetColor(color, TRUE); cairo_set_source_rgb(cairo, gcolor->red / 65535.0, gcolor->green / 65535.0, gcolor->blue / 65535.0); - cairo_set_operator(cairo, CAIRO_OPERATOR_OVER); + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); } return cairo; @@ -197,6 +199,7 @@ static cairo_t* gtkDrawCreateCairoContext( static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { cairo_destroy(cairo); + return NULL; } void wDrawDelayUpdate( @@ -442,7 +445,7 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { update_rect.x = (gint) x - ascent - descent - 1; update_rect.y = (gint) y - (gint) ascent - 1; update_rect.width = (gint) (w * cos( angle ) + 2 + ascent + descent); - update_rect.height = (gint) (w * sin( angle ) + ascent + descent + 2 ); + update_rect.height = (gint) (h * sin( angle ) + ascent + descent + 2 ); gtk_widget_draw(bd->widget, &update_rect); } @@ -469,8 +472,8 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { (int *) &ascent, (int *) &descent)); *w = (wPos_t) textWidth; - *h = (wPos_t) ascent; - *d = (wPos_t) descent; + *h = (wPos_t) textHeight; + *d = (wPos_t) textHeight-ascent; if (debugWindow >= 3) fprintf(stderr, "text metrics: w=%d, h=%d, d=%d\n", *w, *h, *d); @@ -693,7 +696,7 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { wDrawColor color, wDrawOpts opts ) { - GdkGC * gc; + //GdkGC * gc; GdkRectangle update_rect; int i, j, wb; wPos_t xx, yy; @@ -703,7 +706,8 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { x = INMAPX( bd, x-bm->x ); y = INMAPY( bd, y-bm->y )-bm->h; wb = (bm->w+7)/8; - gc = selectGC( bd, 0, wDrawLineSolid, color, opts ); + //gc = selectGC( bd, 0, wDrawLineSolid, color, opts ); + cairo_t* cairo = gtkDrawCreateCairoContext(bd, 0, wDrawLineSolid, color, opts); for ( i=0; i<bm->w; i++ ) for ( j=0; j<bm->h; j++ ) @@ -732,7 +736,9 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { continue; } /*printf( "gdk_draw_point( %ld, gc, %d, %d )\n", (long)gdk_window, xx, yy );*/ - gdk_draw_point( gdk_window, gc, xx, yy ); + //gdk_draw_point( gdk_window, gc, xx, yy ); + cairo_rectangle(cairo, xx-0.5, yy-0.5, 1, 1); + cairo_fill(cairo); if ( b && b->type == B_DRAW ) { update_rect.x = xx-1; update_rect.y = yy-1; @@ -741,6 +747,7 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { gtk_widget_draw( b->widget, &update_rect ); } } + gtkDrawDestroyCairoContext(cairo); #ifdef LATER gdk_draw_pixmap(bd->pixmap, gc, bm->pixmap, @@ -836,9 +843,9 @@ static cairo_t* gtkDrawDestroyCairoContext(cairo_t *cairo) { bd->pixmap = gdk_pixmap_new( bd->widget->window, w, h, -1 ); wDrawClear( bd ); - /*bd->redraw( bd, bd->context, w, h );*/ + bd->redraw( bd, bd->context, w, h ); } - /*wRedraw( bd );*/ + /*wRedraw( bd )*/; } @@ -996,7 +1003,8 @@ static gint draw_button_event( printf( "%s[%dx%d]\n", actionNames[action], bd->lastX, bd->lastY ); bd->action( bd, bd->context, action, bd->lastX, bd->lastY ); } - gtk_widget_grab_focus( bd->widget ); + if (!(bd->option & BD_NOFOCUS)) + gtk_widget_grab_focus( bd->widget ); return TRUE; } @@ -1032,7 +1040,8 @@ static gint draw_motion_event( if (drawVerbose >= 2) printf( "%lx: %s[%dx%d] %s\n", (long)bd, actionNames[action], bd->lastX, bd->lastY, event->is_hint?"<Hint>":"<>" ); bd->action( bd, bd->context, action, bd->lastX, bd->lastY ); - gtk_widget_grab_focus( bd->widget ); + if (!(bd->option & BD_NOFOCUS)) + gtk_widget_grab_focus( bd->widget ); return TRUE; } @@ -1042,11 +1051,17 @@ static gint draw_char_event( GdkEventKey *event, wDraw_p bd ) { + GdkModifierType modifiers; guint key = event->keyval; wAccelKey_e extKey = wAccelKey_None; switch (key) { case GDK_KEY_Escape: key = 0x1B; break; - case GDK_KEY_Return: key = 0x0D; break; + case GDK_KEY_Return: + modifiers = gtk_accelerator_get_default_mod_mask(); + if (((event->state & modifiers)==GDK_CONTROL_MASK) || ((event->state & modifiers)==GDK_MOD1_MASK)) + extKey = wAccelKey_LineFeed; //If Return plus Control or Alt send in LineFeed + key = 0x0D; + break; case GDK_KEY_Linefeed: key = 0x0A; break; case GDK_KEY_Tab: key = 0x09; break; case GDK_KEY_BackSpace: key = 0x08; break; @@ -1141,7 +1156,9 @@ int xw, xh, cw, ch; (GtkSignalFunc) draw_char_event, bd); gtk_signal_connect (GTK_OBJECT (bd->widget), "leave_notify_event", (GtkSignalFunc) draw_leave_event, bd); - GTK_WIDGET_SET_FLAGS(GTK_WIDGET(bd->widget), GTK_CAN_FOCUS); + gtk_widget_set_can_focus(bd->widget,!(option & BD_NOFOCUS)); + //if (!(option & BD_NOFOCUS)) + // GTK_WIDGET_SET_FLAGS(GTK_WIDGET(bd->widget), GTK_CAN_FOCUS); gtk_widget_set_events (bd->widget, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK diff --git a/app/wlib/gtklib/gtkint.h b/app/wlib/gtklib/gtkint.h index da0d9ae..9f6be72 100644 --- a/app/wlib/gtklib/gtkint.h +++ b/app/wlib/gtklib/gtkint.h @@ -47,7 +47,7 @@ typedef enum { B_RADIO, B_TOGGLE, B_DRAW, B_MENU, B_MULTITEXT, B_MESSAGE, B_LINES, B_MENUITEM, B_BOX, - B_BITMAP } wType_e; + B_BITMAP, B_STATUS } wType_e; typedef void (*repaintProcCallback_p)( wControl_p ); typedef void (*doneProcCallback_p)( wControl_p b ); @@ -61,6 +61,7 @@ typedef void (*setTriggerCallback_p)( wControl_p b ); wPos_t realX, realY; \ wPos_t labelW; \ wPos_t w, h; \ + int maximize_initially; \ long option; \ const char * labelStr; \ repaintProcCallback_p repaintProc; \ @@ -78,9 +79,12 @@ struct wWin_t { wBool_t shown; /**< visibility state */ const char * nameStr; /**< window name (not title) */ GtkWidget * menubar; /**< menubar handle (if exists) */ + int menu_height; GdkGC * gc; /**< graphics context */ int gc_linewidth; /**< ??? */ wBool_t busy; + int resizeTimer; /** resizing **/ + int resizeW,resizeH; int modalLevel; }; @@ -113,7 +117,7 @@ struct wList_t { struct wListItem_t { wBool_t active; void * itemData; - const char * label; + char * label; GtkLabel * labelG; wBool_t selected; wList_p listP; diff --git a/app/wlib/gtklib/ixhelp.c b/app/wlib/gtklib/ixhelp.c index 6d85b2b..f1e3983 100644 --- a/app/wlib/gtklib/ixhelp.c +++ b/app/wlib/gtklib/ixhelp.c @@ -20,28 +20,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> #include <stdlib.h> -#include <dirent.h> -#include <sys/time.h> -#include <signal.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> #include <assert.h> -#include <errno.h> -#include <fcntl.h> - -#include <stdint.h> #include "gtkint.h" #include "i18n.h" #include <webkit/webkit.h> -#include "gtkint.h" -#include "i18n.h" - void load_into_view(char *file, int requested_view); // Prototype to please clang. diff --git a/app/wlib/gtklib/list.c b/app/wlib/gtklib/list.c index bf3a56e..8e99efe 100644 --- a/app/wlib/gtklib/list.c +++ b/app/wlib/gtklib/list.c @@ -486,6 +486,8 @@ wIndex_t wListAddValue( wlibTreeViewAddRow(b, (char *)labelStr, bm, id_p); } + free(id_p->label); + b->count++; b->recursion--; diff --git a/app/wlib/gtklib/liststore.c b/app/wlib/gtklib/liststore.c index eb53ea7..820366a 100644 --- a/app/wlib/gtklib/liststore.c +++ b/app/wlib/gtklib/liststore.c @@ -110,7 +110,8 @@ wlibListStoreGetContext(GtkListStore *ls, int inx) /** - * Clear the list store + * Clear the list store. All data in the list store will be automatically + * free'd when the list store is cleared. * * \param listStore IN */ @@ -118,9 +119,18 @@ wlibListStoreGetContext(GtkListStore *ls, int inx) void wlibListStoreClear(GtkListStore *listStore) { + wListItem_p id_p; + int i = 0; + assert(listStore != NULL); - /** \todo this looks like a memory leak. should probably free the id's */ + id_p = wlibListStoreGetContext(listStore, i++); + + while (id_p) { + g_free(id_p); + id_p = wlibListStoreGetContext(listStore, i++); + } + gtk_list_store_clear(listStore); } @@ -190,7 +200,9 @@ wlibListStoreUpdateIter(GtkListStore *ls, GtkTreeIter *iter, char *labels) } /** - * Add a pixbuf to the list store + * Add a pixbuf to the list store. So pixbuf is unref'ed so it will be freed + * with the list store. + * * \param ls IN list store * \param iter IN position * \param pixbuf IN pixbuf to add @@ -200,6 +212,8 @@ void wlibListStoreSetPixbuf(GtkListStore *ls, GtkTreeIter *iter, GdkPixbuf *pixbuf) { gtk_list_store_set(ls, iter, LISTCOL_BITMAP, pixbuf, -1); + g_object_ref_sink(pixbuf); + g_object_unref(pixbuf); } /** * Add a row to the list store diff --git a/app/wlib/gtklib/main.c b/app/wlib/gtklib/main.c index 9075687..470f17b 100644 --- a/app/wlib/gtklib/main.c +++ b/app/wlib/gtklib/main.c @@ -24,6 +24,7 @@ #include <stdio.h>
#include <stdlib.h>
#include <locale.h>
+#include <string.h>
#define GTK_DISABLE_SINGLE_INCLUDES
#define GDK_DISABLE_DEPRECATED
diff --git a/app/wlib/gtklib/menu.c b/app/wlib/gtklib/menu.c index fb115a3..d19805a 100644 --- a/app/wlib/gtklib/menu.c +++ b/app/wlib/gtklib/menu.c @@ -32,6 +32,7 @@ #include <gtk/gtk.h> #include <gdk/gdk.h> +#include <gdk/gdkkeysyms.h> #include "gtkint.h" #include "i18n.h" @@ -237,7 +238,14 @@ static wMenuItem_p createMenuItem( return mi; } - +/** + * Add a accelerator key to a widget + * + * @param w IN unused(?) + * @param menu IN unused(?) + * @param menu_item IN owning widget + * @param acclKey IN the accelerator key + */ static void setAcclKey( wWin_p w, GtkWidget * menu, GtkWidget * menu_item, int acclKey ) { int mask; @@ -262,19 +270,12 @@ static void setAcclKey( wWin_p w, GtkWidget * menu, GtkWidget * menu_item, int a mask = 0; if (acclKey) { - int len; - char acclStr[40]; - len = 0; if (acclKey&WALT) { mask |= GDK_MOD1_MASK; - strcpy( acclStr+len, "Meta+" ); - len += 5; } if (acclKey&WSHIFT) { mask |= GDK_SHIFT_MASK; - strcpy( acclStr+len, "Shift+" ); - len += 6; switch ( (acclKey&0xFF) ) { case '0': acclKey += ')'-'0'; break; case '1': acclKey += '!'-'1'; break; @@ -302,11 +303,7 @@ static void setAcclKey( wWin_p w, GtkWidget * menu, GtkWidget * menu_item, int a } if (acclKey&WCTL) { mask |= GDK_CONTROL_MASK; - strcpy( acclStr+len, "Ctrl+" ); - len += 5; } - acclStr[len++] = (acclKey & 0xFF); - acclStr[len++] = '\0'; gtk_widget_add_accelerator( menu_item, "activate", (isalpha(acclKey&0xFF)?accel_alpha_group:accel_nonalpha_group), toupper(acclKey&0xFF), mask, GTK_ACCEL_VISIBLE|GTK_ACCEL_LOCKED ); diff --git a/app/wlib/gtklib/message.c b/app/wlib/gtklib/message.c index 396b696..af37d22 100644 --- a/app/wlib/gtklib/message.c +++ b/app/wlib/gtklib/message.c @@ -21,6 +21,7 @@ */ #include <stdlib.h> +#include <string.h> #define GTK_DISABLE_SINGLE_INCLUDES #define GDK_DISABLE_DEPRECATED @@ -84,7 +85,6 @@ void wMessageSetWidth( /** * Get height of message text - * \todo Constant height doesn't make sense, change to use the window's properties and retrieve the real font size * * \param flags IN text properties (large or small size) * \return text height @@ -93,7 +93,45 @@ void wMessageSetWidth( wPos_t wMessageGetHeight( long flags) { - return 14; + GtkWidget * temp; + + if (!(flags&COMBOBOX)) { + temp = gtk_label_new("Test"); //To get size of text itself + } else { + temp = gtk_combo_box_text_new(); //to get max size of an object in infoBar + } + + if (wMessageSetFont(flags)) { + GtkStyle *style; + PangoFontDescription *fontDesc; + int fontSize; + /* get the current font descriptor */ + style = gtk_widget_get_style(temp); + fontDesc = style->font_desc; + /* get the current font size */ + fontSize = PANGO_PIXELS(pango_font_description_get_size(fontDesc)); + + /* calculate the new font size */ + if (flags & BM_LARGE) { + pango_font_description_set_size(fontDesc, fontSize * 1.4 * PANGO_SCALE); + } else { + pango_font_description_set_size(fontDesc, fontSize * 0.7 * PANGO_SCALE); + } + + /* set the new font size */ + gtk_widget_modify_font(temp, fontDesc); + } + + if (flags&1L) { + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(temp),"Test"); + } + + GtkRequisition temp_requisition; + gtk_widget_size_request(temp,&temp_requisition); + g_object_ref_sink(temp); + gtk_widget_destroy(temp); + g_object_unref(temp); + return temp_requisition.height; } /** @@ -109,7 +147,7 @@ wPos_t wMessageGetHeight( * \return handle for created window */ - wMessage_p wMessageCreateEx( +wMessage_p wMessageCreateEx( wWin_p parent, wPos_t x, wPos_t y, @@ -147,7 +185,7 @@ wPos_t wMessageGetHeight( /* set the new font size */ gtk_widget_modify_font((GtkWidget *)b->labelWidget, fontDesc); } - + b->widget = gtk_fixed_new(); gtk_widget_size_request(GTK_WIDGET(b->labelWidget), &requisition); gtk_container_add(GTK_CONTAINER(b->widget), b->labelWidget); @@ -166,3 +204,33 @@ wPos_t wMessageGetHeight( return b; } + +/** + * Get the anticipated length of a message field + * + * \param testString IN string that should fit into the message box + * \return expected width of message box + */ + +wPos_t +wMessageGetWidth(const char *testString) +{ + GtkWidget *entry; + GtkRequisition requisition; + + return( wLabelWidth(testString)); +// entry = gtk_entry_new(); +// g_object_ref_sink(entry); +// +// gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE); +// gtk_entry_set_width_chars(GTK_ENTRY(entry), strlen(testString)); +// gtk_entry_set_max_length(GTK_ENTRY(entry), strlen(testString)); +// +// gtk_widget_size_request(entry, &requisition); +// +// gtk_widget_destroy(entry); +// g_object_unref(entry); +// +// return (requisition.width+8); +} + diff --git a/app/wlib/gtklib/notice.c b/app/wlib/gtklib/notice.c index cf4b59f..b72afd6 100644 --- a/app/wlib/gtklib/notice.c +++ b/app/wlib/gtklib/notice.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <sys/time.h> #include <signal.h> +#include <string.h> #define GTK_DISABLE_SINGLE_INCLUDES #define GDK_DISABLE_DEPRECATED @@ -82,7 +83,7 @@ int wNoticeEx(int type, unsigned flag; char *headline; GtkWidget *dialog; - GtkWindow *parent = GTK_WINDOW_TOPLEVEL; + GtkWindow *parent = NULL; switch (type) { case NT_INFORMATION: diff --git a/app/wlib/gtklib/png.c b/app/wlib/gtklib/png.c index e11869e..809de6a 100644 --- a/app/wlib/gtklib/png.c +++ b/app/wlib/gtklib/png.c @@ -59,6 +59,7 @@ wBool_t wBitMapWriteFile(wDraw_p d, const char * fileName) return FALSE; } + g_object_ref_sink(pixbuf); g_object_unref(pixbuf); return TRUE; } diff --git a/app/wlib/gtklib/print.c b/app/wlib/gtklib/print.c index c0993f4..cad7e57 100644 --- a/app/wlib/gtklib/print.c +++ b/app/wlib/gtklib/print.c @@ -86,6 +86,8 @@ static double rBorder; /**< right margin */ static double lBorder; /**< left margin */ static double bBorder; /**< bottom margin */ +static double scale_adjust = 1.0; + static long printFormat = PRINT_LANDSCAPE; /***************************************************************************** @@ -118,7 +120,7 @@ WlibApplySettings(GtkPrintOperation *op) dialog = gtk_message_dialog_new(GTK_WINDOW(gtkMainW->gtkwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - err->message); + "%s",err->message); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { @@ -144,7 +146,7 @@ WlibApplySettings(GtkPrintOperation *op) dialog = gtk_message_dialog_new(GTK_WINDOW(gtkMainW->gtkwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - err->message); + "%s",err->message); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { @@ -193,7 +195,7 @@ WlibSaveSettings(GtkPrintOperation *op) dialog = gtk_message_dialog_new(GTK_WINDOW(gtkMainW->gtkwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - err->message); + "%s",err->message); g_error_free(err); gtk_dialog_run(GTK_DIALOG(dialog)); @@ -216,7 +218,7 @@ WlibSaveSettings(GtkPrintOperation *op) dialog = gtk_message_dialog_new(GTK_WINDOW(gtkMainW->gtkwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - err->message); + "%s",err->message); g_error_free(err); gtk_dialog_run(GTK_DIALOG(dialog)); @@ -279,21 +281,23 @@ static void setLineType( wDrawOpts opts) { cairo_t *cr = psPrint_d.printContext; - double dashLength = DASH_LENGTH; + + double dashes[] = { DASH_LENGTH, 3 }; //Reduce gap in between dashes + static int len_dashes = sizeof(dashes) / sizeof(dashes[0]); if (lineWidth < 0.0) { - lineWidth = P2I(-lineWidth)*2.0; + lineWidth = P2I(-lineWidth)*2.0/scale_adjust; } // make sure that there is a minimum line width used - if (lineWidth == 0.0) { - lineWidth = 0.1; + if (lineWidth <= 0.09) { + lineWidth = 0.1/scale_adjust; } cairo_set_line_width(cr, lineWidth); if (lineType == wDrawLineDash) { - cairo_set_dash(cr, &dashLength, 1, 0.0); + cairo_set_dash(cr, dashes, len_dashes, 0.0); } else { cairo_set_dash(cr, NULL, 0, 0.0); } @@ -537,7 +541,7 @@ void psPrintFillCircle( /** * Print a string at the given position using specified font and text size. - * The orientatoion of the y-axis in XTrackCAD is wrong for cairo. So for + * The orientation of the y-axis in XTrackCAD is wrong for cairo. So for * all other print primitives a flip operation is done. As this would * also affect the string orientation, printing a string has to be * treated differently. The starting point is transformed, then the @@ -568,7 +572,8 @@ void psPrintString( { char * cp; double x0 = (double)x, y0 = (double)y; - double text_height; + int text_height, text_width; + double ascent; cairo_t *cr; cairo_matrix_t matrix; @@ -586,10 +591,13 @@ void psPrintString( // get the current transformation matrix and transform the starting // point of the string + + cairo_save(cr); + cairo_get_matrix(cr, &matrix); + cairo_matrix_transform_point(&matrix, &x0, &y0); - cairo_save(cr); layout = pango_cairo_create_layout(cr); @@ -597,26 +605,27 @@ void psPrintString( /** \todo use a getter function instead of double conversion */ desc = pango_font_description_from_string(wlibFontTranslate(fp)); - //don't know why the size has to be reduced to 75% :-( - pango_font_description_set_size(desc, fs * PANGO_SCALE *0.75); + pango_font_description_set_size(desc, fs * PANGO_SCALE ); // render the string to a Pango layout pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, s, -1); pango_layout_set_width(layout, -1); pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT); + pango_layout_get_pixel_size(layout, &text_width, &text_height); // get the height of the string pcontext = pango_cairo_create_context(cr); metrics = pango_context_get_metrics(pcontext, desc, pango_context_get_language(pcontext)); - text_height = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE; - // transform the string to the correct position + ascent = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE * scale_adjust ; + cairo_identity_matrix(cr); - cairo_translate(cr, x0 + text_height * sin(-a * M_PI / 180.0) , - y0 - text_height * cos(a * M_PI / 180.0)); + cairo_translate(cr, x0 + ((ascent + (bBorder*scale_adjust)) * sin(-a * M_PI / 180.0))+((lBorder*scale_adjust)* cos(a * M_PI / 180.0)), + y0 - ((ascent + (bBorder*scale_adjust)) * cos( a * M_PI / 180.0))+((lBorder*scale_adjust)* sin(a * M_PI / 180.0))); + cairo_rotate(cr, -a * M_PI / 180.0); // set the color @@ -633,7 +642,7 @@ void psPrintString( } /** - * Create clipping retangle. + * Create clipping rectangle. * * \param x, y IN starting position * \param w, h IN width and height of rectangle @@ -800,6 +809,7 @@ wBool_t wPrintDocStart(const char * title, int fTotalPageCount, int * copiesP) cairo_surface_type_t surface_type; cairo_matrix_t matrix; + printDialog = gtk_print_unix_dialog_new(title, GTK_WINDOW(gtkMainW->gtkwin)); // load the settings @@ -848,7 +858,10 @@ wBool_t wPrintDocStart(const char * title, int fTotalPageCount, int * copiesP) if (surface_type == CAIRO_SURFACE_TYPE_PDF || surface_type == CAIRO_SURFACE_TYPE_PS || surface_type == CAIRO_SURFACE_TYPE_SVG) { - psPrint_d.dpi = 72; + double p_def=600; + cairo_surface_set_fallback_resolution (psPrint_d.curPrintSurface, p_def, p_def); + psPrint_d.dpi = p_def; + scale_adjust = 72/p_def; } else { psPrint_d.dpi = (double)gtk_print_settings_get_resolution(settings); } @@ -856,11 +869,13 @@ wBool_t wPrintDocStart(const char * title, int fTotalPageCount, int * copiesP) // in XTrackCAD 0,0 is top left, in cairo bottom left. This is // corrected via the following transformations. // also the translate makes sure that the drawing is rendered - // within the paper margins + // within the paper margin + + cairo_translate(psPrint_d.printContext, lBorder*72, (paperHeight-bBorder)*72 ); + + cairo_scale(psPrint_d.printContext, 1.0 * scale_adjust, -1.0 * scale_adjust); - cairo_scale(psPrint_d.printContext, 1.0, -1.0); - cairo_translate(psPrint_d.printContext, lBorder * psPrint_d.dpi, - -(paperHeight-bBorder) *psPrint_d.dpi); + //cairo_translate(psPrint_d.printContext, 0, -paperHeight* psPrint_d.dpi); WlibSaveSettings(NULL); } @@ -900,7 +915,7 @@ doPrintJobFinished(GtkPrintJob *job, void *data, GError *err) dialog = gtk_message_dialog_new(GTK_WINDOW(gtkMainW->gtkwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - err->message); + "%s",err->message); } } diff --git a/app/wlib/gtklib/statusbar.c b/app/wlib/gtklib/statusbar.c new file mode 100644 index 0000000..3730eab --- /dev/null +++ b/app/wlib/gtklib/statusbar.c @@ -0,0 +1,211 @@ +/** \file statusbar.c + * Status bar + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis, + * 2017 Martin Fischer <m_fischer@sf.net> + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + * + */ + + +#include <stdlib.h> +#include <string.h> + +#define GTK_DISABLE_SINGLE_INCLUDES +#define GDK_DISABLE_DEPRECATED +#define GTK_DISABLE_DEPRECATED +#define GSEAL_ENABLE + +#include <gtk/gtk.h> +#include <gdk/gdk.h> + +#include "gtkint.h" + +struct wStatus_t { + WOBJ_COMMON + GtkWidget * labelWidget; + const char * message; + wPos_t labelWidth; +}; + +/** + * Set the message text + * + * \param b IN widget + * \param arg IN new text + * \return + */ + +void wStatusSetValue( + wStatus_p b, + const char * arg) +{ + if (b->widget == 0) { + abort(); + } + + if (gtk_entry_get_max_length(GTK_ENTRY(b->labelWidget))<strlen(arg)) { + gtk_entry_set_max_length(GTK_ENTRY(b->labelWidget), strlen(arg)); + gtk_entry_set_width_chars(GTK_ENTRY(b->labelWidget), strlen(arg)); + } + + gtk_entry_set_text(GTK_ENTRY(b->labelWidget), wlibConvertInput(arg)); +} +/** + * Create a window for a simple text. + * + * \param IN parent Handle of parent window + * \param IN x position in x direction + * \param IN y position in y direction + * \param IN labelStr ??? + * \param IN width horizontal size of window + * \param IN message message to display ( null terminated ) + * \param IN flags display options + * \return handle for created window + */ + +wStatus_p wStatusCreate( + wWin_p parent, + wPos_t x, + wPos_t y, + const char * labelStr, + wPos_t width, + const char *message) +{ + wStatus_p b; + GtkRequisition requisition; + b = (wStatus_p)wlibAlloc(parent, B_STATUS, x, y, NULL, sizeof *b, NULL); + wlibComputePos((wControl_p)b); + b->message = message; + b->labelWidth = width; + b->labelWidget = gtk_entry_new(); + gtk_editable_set_editable(GTK_EDITABLE(b->labelWidget), FALSE); + gtk_entry_set_has_frame(GTK_ENTRY(b->labelWidget), FALSE); + gtk_widget_set_can_focus(b->labelWidget, FALSE); + gtk_entry_set_text(GTK_ENTRY(b->labelWidget), + message?wlibConvertInput(message):""); + + b->widget = gtk_fixed_new(); + gtk_container_add(GTK_CONTAINER(b->widget), b->labelWidget); + wlibControlGetSize((wControl_p)b); + gtk_fixed_put(GTK_FIXED(parent->widget), b->widget, b->realX, b->realY); + gtk_widget_show(b->widget); + gtk_widget_show(b->labelWidget); + wlibAddButton((wControl_p)b); + + return b; +} + +/** + * Get the anticipated length of a message field + * + * \param testString IN string that should fit into the message box + * \return expected width of message box + */ + +wPos_t +wStatusGetWidth(const char *testString) +{ + GtkWidget *entry; + GtkRequisition requisition; + + entry = gtk_entry_new(); + g_object_ref_sink(entry); + + gtk_entry_set_has_frame(GTK_ENTRY(entry), FALSE); + gtk_entry_set_width_chars(GTK_ENTRY(entry), strlen(testString)); + gtk_entry_set_max_length(GTK_ENTRY(entry), strlen(testString)); + + gtk_widget_size_request(entry, &requisition); + + gtk_widget_destroy(entry); + g_object_unref(entry); + + return (requisition.width+8); +} + +/** + * Get height of message text + * + * \param flags IN text properties (large or small size) + * \return text height + */ + +wPos_t wStatusGetHeight( + long flags) +{ + GtkWidget * temp; + + if (!(flags&COMBOBOX)) { + temp = gtk_entry_new(); //To get size of text itself + gtk_entry_set_has_frame(GTK_ENTRY(temp), FALSE); + } else { + temp = gtk_combo_box_text_new(); //to get max size of an object in infoBar + } + g_object_ref_sink(temp); + + if (wMessageSetFont(flags)) { + GtkStyle *style; + PangoFontDescription *fontDesc; + int fontSize; + /* get the current font descriptor */ + style = gtk_widget_get_style(temp); + fontDesc = style->font_desc; + /* get the current font size */ + fontSize = PANGO_PIXELS(pango_font_description_get_size(fontDesc)); + + /* calculate the new font size */ + if (flags & BM_LARGE) { + pango_font_description_set_size(fontDesc, fontSize * 1.4 * PANGO_SCALE); + } else { + pango_font_description_set_size(fontDesc, fontSize * 0.7 * PANGO_SCALE); + } + + /* set the new font size */ + gtk_widget_modify_font(temp, fontDesc); + } + + if (flags&1L) { + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(temp),"Test"); + } + + GtkRequisition temp_requisition; + gtk_widget_size_request(temp,&temp_requisition); + //g_object_ref_sink(temp); + //g_object_unref(temp); + gtk_widget_destroy(temp); + return temp_requisition.height; +} + +/** + * Set the width of the widget + * + * \param b IN widget + * \param width IN new width + * \return + */ + +void wStatusSetWidth( + wStatus_p b, + wPos_t width) +{ + b->labelWidth = width; + gtk_widget_set_size_request(b->widget, width, -1); +} diff --git a/app/wlib/gtklib/text.c b/app/wlib/gtklib/text.c index 5445984..f7ba288 100644 --- a/app/wlib/gtklib/text.c +++ b/app/wlib/gtklib/text.c @@ -360,12 +360,12 @@ wBool_t wTextPrint( dialog = gtk_message_dialog_new(GTK_WINDOW(gtkMainW->gtkwin), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - error->message); + "%s",error->message); g_error_free(error); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } - + g_object_ref_sink(operation); g_object_unref(operation); return TRUE; } diff --git a/app/wlib/gtklib/tooltip.c b/app/wlib/gtklib/tooltip.c index 15b46d2..20a1ba9 100644 --- a/app/wlib/gtklib/tooltip.c +++ b/app/wlib/gtklib/tooltip.c @@ -45,7 +45,7 @@ static int enableBalloonHelp = TRUE; static GtkWidget * balloonF; /**< balloon help control for hotbar item */
static GtkWidget * balloonPI;
-static const char * balloonMsg = NULL;
+static char balloonMsg[100] = "";
static wControl_p balloonB;
static wPos_t balloonDx, balloonDy;
static wBool_t balloonVisible = FALSE;
@@ -136,54 +136,56 @@ void wControlSetBalloon( wControl_p b, wPos_t dx, wPos_t dy, const char * msg ) wPos_t w, h;
wPos_t xx, yy;
const char * msgConverted;
- GtkAllocation size;
+ GtkRequisition size;
/* return if there is nothing to do */
if (balloonVisible && balloonB == b &&
- balloonDx == dx && balloonDy == dy && msg != NULL && balloonMsg != NULL)
+ balloonDx == dx && balloonDy == dy && msg != NULL && !balloonMsg[0])
if (strcmp(msg,balloonMsg)==0)
return;
/* hide the tooltip */
if ( msg == NULL ) {
- if ( balloonF != NULL ) {
+ if ( balloonF != NULL && balloonVisible) {
gtk_widget_hide( balloonF );
balloonVisible = FALSE;
}
- balloonMsg = "";
+ balloonMsg[0] = '\0';
return;
}
msgConverted = wlibConvertInput(msg);
if ( balloonF == NULL ) {
- GtkWidget *alignment;
+ //GtkWidget *alignment;
- balloonF = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+ balloonF = gtk_window_new( GTK_WINDOW_POPUP );
gtk_window_set_type_hint( GTK_WINDOW( balloonF), GDK_WINDOW_TYPE_HINT_TOOLTIP );
gtk_window_set_decorated (GTK_WINDOW (balloonF), FALSE );
gtk_window_set_resizable( GTK_WINDOW (balloonF), FALSE );
+ gtk_window_set_accept_focus(GTK_WINDOW( balloonF), FALSE);
- alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
+ GtkWidget * alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
gtk_alignment_set_padding( GTK_ALIGNMENT(alignment), 6, 6, 6, 6 );
-
+
gtk_container_add (GTK_CONTAINER (balloonF), alignment);
+
gtk_widget_show (alignment);
balloonPI = gtk_label_new(msgConverted);
gtk_container_add( GTK_CONTAINER(alignment), balloonPI );
- gtk_widget_show( balloonPI );
+ gtk_widget_show_all( balloonPI );
}
gtk_label_set_text( GTK_LABEL(balloonPI), msgConverted );
balloonDx = dx;
balloonDy = dy;
balloonB = b;
- balloonMsg = msg;
- gtk_widget_get_allocation(balloonPI, &size );
+ snprintf(balloonMsg, sizeof(balloonMsg), "%s", msg);
+ gtk_widget_get_requisition(balloonPI, &size );
w = size.width;
h = size.height;
- gdk_window_get_origin( gtk_widget_get_window( GTK_WIDGET(b->parent->gtkwin)), &x, &y );
+ gtk_window_get_position( GTK_WINDOW(b->parent->gtkwin), &x, &y);
x += b->realX + dx;
y += b->realY + b->h - dy;
@@ -200,7 +202,8 @@ void wControlSetBalloon( wControl_p b, wPos_t dx, wPos_t dy, const char * msg ) y = yy - h ;
}
gtk_window_move( GTK_WINDOW( balloonF ), x, y );
- gtk_widget_show( balloonF );
+ gtk_widget_show_all( balloonF );
+ gtk_widget_show( balloonPI );
balloonVisible = TRUE;
}
diff --git a/app/wlib/gtklib/treeview.c b/app/wlib/gtklib/treeview.c index e2f2259..2b743cb 100644 --- a/app/wlib/gtklib/treeview.c +++ b/app/wlib/gtklib/treeview.c @@ -326,6 +326,7 @@ wlibTreeViewAddData(GtkWidget *tv, int cols, char *label, GdkPixbuf *pixbuf, gtk_tree_view_column_set_visible(column, TRUE); } + return 0; } diff --git a/app/wlib/gtklib/util.c b/app/wlib/gtklib/util.c index 61b5b95..e6587a0 100644 --- a/app/wlib/gtklib/util.c +++ b/app/wlib/gtklib/util.c @@ -23,6 +23,7 @@ #include <stdio.h> #include <stdlib.h> #include <signal.h> +#include <string.h> #define GTK_DISABLE_SINGLE_INCLUDES #define GDK_DISABLE_DEPRECATED @@ -74,7 +75,7 @@ static wBool_t reverseIcon = #endif - + /* ***************************************************************************** * @@ -91,7 +92,7 @@ static wBool_t reverseIcon = */ GdkPixbuf* wlibPixbufFromXBM( - wIcon_p ip ) + wIcon_p ip) { GdkPixbuf * pixbuf; @@ -99,39 +100,41 @@ GdkPixbuf* wlibPixbufFromXBM( char line2[40]; char ** pixmapData; - int row,col,wb; + int row, col, wb; long rgb; const char * bits; - wb = (ip->w+7)/8; - pixmapData = (char**)malloc((3+ip->h) * sizeof *pixmapData); + wb = (ip->w + 7) / 8; + pixmapData = (char**) malloc((3 + ip->h) * sizeof *pixmapData); pixmapData[0] = line0; rgb = wDrawGetRGB(ip->color); sprintf(line0, " %d %d 2 1", ip->w, ip->h); - sprintf(line2, "# c #%2.2lx%2.2lx%2.2lx", (rgb>>16)&0xFF, (rgb>>8)&0xFF, - rgb&0xFF); + sprintf(line2, "# c #%2.2lx%2.2lx%2.2lx", (rgb >> 16)&0xFF, (rgb >> 8)&0xFF, + rgb & 0xFF); pixmapData[1] = ". c None s None"; pixmapData[2] = line2; bits = ip->bits; - for (row = 0; row<ip->h; row++) { - pixmapData[row+3] = (char*)malloc((ip->w+1) * sizeof **pixmapData); + for (row = 0; row < ip->h; row++) { + pixmapData[row + 3] = (char*) malloc((ip->w + 1) * sizeof **pixmapData); - for (col = 0; col<ip->w; col++) { - if (bits[ row*wb+(col>>3) ] & (1<<(col&07))) { - pixmapData[row+3][col] = '#'; - } else { - pixmapData[row+3][col] = '.'; + for (col = 0; col < ip->w; col++) { + if (bits[ row * wb + (col >> 3) ] & (1 << (col & 07))) { + pixmapData[row + 3][col] = '#'; + } + else { + pixmapData[row + 3][col] = '.'; } } - pixmapData[row+3][ip->w] = 0; + pixmapData[row + 3][ip->w] = 0; } - pixbuf = gdk_pixbuf_new_from_xpm_data((const char **)pixmapData); + pixbuf = gdk_pixbuf_new_from_xpm_data((const char **) pixmapData); - for (row = 0; row<ip->h; row++) { - free(pixmapData[row+3]); + for (row = 0; row < ip->h; row++) { + free(pixmapData[row + 3]); } + free(pixmapData); return pixbuf; } @@ -145,7 +148,7 @@ GdkPixbuf* wlibPixbufFromXBM( int wlibAddLabel(wControl_p b, const char * labelStr) { - GtkRequisition requisition; + GtkRequisition requisition, reqwidget; if (labelStr == NULL) { return 0; @@ -153,12 +156,15 @@ int wlibAddLabel(wControl_p b, const char * labelStr) b->label = gtk_label_new(wlibConvertInput(labelStr)); gtk_widget_size_request(b->label, &requisition); + if (b->widget) + gtk_widget_size_request(b->widget, &reqwidget); + else + reqwidget.height = requisition.height; gtk_container_add(GTK_CONTAINER(b->parent->widget), b->label); gtk_fixed_move(GTK_FIXED(b->parent->widget), b->label, - b->realX-requisition.width-8, b->realY+LABEL_OFFSET); - + b->realX - requisition.width - 8, b->realY + (reqwidget.height/2 - requisition.height/2)); gtk_widget_show(b->label); - return requisition.width+8; + return requisition.width + 8; } /** @@ -175,15 +181,15 @@ int wlibAddLabel(wControl_p b, const char * labelStr) */ void * wlibAlloc( - wWin_p parent, - wType_e type, - wPos_t origX, - wPos_t origY, - const char * labelStr, - int size, - void * data) + wWin_p parent, + wType_e type, + wPos_t origX, + wPos_t origY, + const char * labelStr, + int size, + void * data) { - wControl_p w = (wControl_p)malloc(size); + wControl_p w = (wControl_p) malloc(size); char * cp; memset(w, 0, size); @@ -197,7 +203,7 @@ void * wlibAlloc( w->origY = origY; if (labelStr) { - cp = (char*)malloc(strlen(labelStr)+1); + cp = (char*) malloc(strlen(labelStr) + 1); w->labelStr = cp; for (; *labelStr; labelStr++) @@ -220,19 +226,21 @@ void * wlibAlloc( */ void wlibComputePos( - wControl_p b) + wControl_p b) { wWin_p w = b->parent; if (b->origX >= 0) { b->realX = b->origX; - } else { + } + else { b->realX = w->lastX + (-b->origX) - 1; } if (b->origY >= 0) { - b->realY = b->origY + BORDERSIZE + ((w->option&F_MENUBAR)?MENUH:0); - } else { + b->realY = b->origY + BORDERSIZE + ((w->option & F_MENUBAR) ? w->menu_height : 0); + } + else { b->realY = w->lastY + (-b->origY) - 1; } } @@ -244,7 +252,7 @@ void wlibComputePos( */ void wlibControlGetSize( - wControl_p b) + wControl_p b) { GtkRequisition requisition; gtk_widget_size_request(b->widget, &requisition); @@ -258,14 +266,15 @@ void wlibControlGetSize( */ void wlibAddButton( - wControl_p b) + wControl_p b) { wWin_p win = b->parent; wBool_t resize = FALSE; if (win->first == NULL) { win->first = b; - } else { + } + else { win->last->next = b; } @@ -275,7 +284,7 @@ void wlibAddButton( win->lastX = b->realX + b->w; win->lastY = b->realY + b->h; - if (win->option&F_AUTOSIZE) { + if (win->option & F_AUTOSIZE) { if (win->lastX > win->realX) { win->realX = win->lastX; @@ -312,20 +321,20 @@ void wlibAddButton( */ wControl_p wlibGetControlFromPos( - wWin_p win, - wPos_t x, - wPos_t y) + wWin_p win, + wPos_t x, + wPos_t y) { wControl_p b; wPos_t xx, yy; - for (b=win->first; b != NULL; b = b->next) { + for (b = win->first; b != NULL; b = b->next) { if (b->widget && gtk_widget_get_visible(b->widget)) { xx = b->realX; yy = b->realY; - if (xx <= x && x < xx+b->w && - yy <= y && y < yy+b->h) { + if (xx <= x && x < xx + b->w && + yy <= y && y < yy + b->h) { return b; } } @@ -334,7 +343,7 @@ wControl_p wlibGetControlFromPos( return NULL; } - + /* ***************************************************************************** * @@ -352,13 +361,12 @@ void wBeep(void) gdk_display_beep(gdk_display_get_default()); } - /** * Flushs all commands to the Window. */ void wFlush( - void) + void) { while (gtk_events_pending()) { gtk_main_iteration(); @@ -427,36 +435,36 @@ char * wlibConvertInput(const char * inString) /* Already UTF-8 encoded? */ if (g_utf8_validate(inString, -1, NULL)) - /* Yes, do not double-convert */ - { - return (char*)inString; + /* Yes, do not double-convert */ { + return (char*) inString; } - for (cp=inString, extCharCnt=0; *cp; cp++) { + for (cp = inString, extCharCnt = 0; *cp; cp++) { if (((*cp)&0x80) != '\0') { extCharCnt++; } } - inCharCnt = cp-inString; + inCharCnt = cp - inString; if (extCharCnt == '\0') { - return (char*)inString; + return (char*) inString; } - DYNARR_SET(char, conversionBuffer_da, inCharCnt+extCharCnt+1); + DYNARR_SET(char, conversionBuffer_da, inCharCnt + extCharCnt + 1); - for (cp=inString, cq=(char*)conversionBuffer_da.ptr; *cp; cp++) { + for (cp = inString, cq = (char*) conversionBuffer_da.ptr; *cp; cp++) { if (((*cp)&0x80) != 0) { - *cq++ = 0xC0+(((*cp)&0xC0)>>6); - *cq++ = 0x80+((*cp)&0x3F); - } else { + *cq++ = 0xC0 + (((*cp)&0xC0) >> 6); + *cq++ = 0x80 + ((*cp)&0x3F); + } + else { *cq++ = *cp; } } *cq = 0; - return (char*)conversionBuffer_da.ptr; + return (char*) conversionBuffer_da.ptr; } /** @@ -472,31 +480,32 @@ char * wlibConvertOutput(const char * inString) char * cq; int extCharCnt, inCharCnt; - for (cp=inString, extCharCnt=0; *cp; cp++) { + for (cp = inString, extCharCnt = 0; *cp; cp++) { if (((*cp)&0xC0) == 0x80) { extCharCnt++; } } - inCharCnt = cp-inString; + inCharCnt = cp - inString; if (extCharCnt == '\0') { - return (char*)inString; + return (char*) inString; } - DYNARR_SET(char, conversionBuffer_da, inCharCnt+1); + DYNARR_SET(char, conversionBuffer_da, inCharCnt + 1); - for (cp=inString, cq=(char*)conversionBuffer_da.ptr; *cp; cp++) { + for (cp = inString, cq = (char*) conversionBuffer_da.ptr; *cp; cp++) { if (((*cp)&0x80) != 0) { - *cq++ = 0xC0+(((*cp)&0xC0)>>6); - *cq++ = 0x80+((*cp)&0x3F); - } else { + *cq++ = 0xC0 + (((*cp)&0xC0) >> 6); + *cq++ = 0x80 + ((*cp)&0x3F); + } + else { *cq++ = *cp; } } *cq = '\0'; - return (char*)conversionBuffer_da.ptr; + return (char*) conversionBuffer_da.ptr; } /*-----------------------------------------------------------------*/ @@ -506,30 +515,32 @@ static dynArr_t accelData_da; #define accelData(N) DYNARR_N( accelData_t, accelData_da, N ) static guint accelKeyMap[] = { - 0, /* wAccelKey_None, */ - GDK_KEY_Delete, /* wAccelKey_Del, */ - GDK_KEY_Insert, /* wAccelKey_Ins, */ - GDK_KEY_Home, /* wAccelKey_Home, */ - GDK_KEY_End, /* wAccelKey_End, */ - GDK_KEY_Page_Up, /* wAccelKey_Pgup, */ - GDK_KEY_Page_Down, /* wAccelKey_Pgdn, */ - GDK_KEY_Up, /* wAccelKey_Up, */ - GDK_KEY_Down, /* wAccelKey_Down, */ - GDK_KEY_Right, /* wAccelKey_Right, */ - GDK_KEY_Left, /* wAccelKey_Left, */ - GDK_KEY_BackSpace, /* wAccelKey_Back, */ - GDK_KEY_F1, /* wAccelKey_F1, */ - GDK_KEY_F2, /* wAccelKey_F2, */ - GDK_KEY_F3, /* wAccelKey_F3, */ - GDK_KEY_F4, /* wAccelKey_F4, */ - GDK_KEY_F5, /* wAccelKey_F5, */ - GDK_KEY_F6, /* wAccelKey_F6, */ - GDK_KEY_F7, /* wAccelKey_F7, */ - GDK_KEY_F8, /* wAccelKey_F8, */ - GDK_KEY_F9, /* wAccelKey_F9, */ - GDK_KEY_F10, /* wAccelKey_F10, */ - GDK_KEY_F11, /* wAccelKey_F11, */ - GDK_KEY_F12 /* wAccelKey_F12, */ + 0, /* wAccelKey_None, */ + GDK_KEY_Delete, /* wAccelKey_Del, */ + GDK_KEY_Insert, /* wAccelKey_Ins, */ + GDK_KEY_Home, /* wAccelKey_Home, */ + GDK_KEY_End, /* wAccelKey_End, */ + GDK_KEY_Page_Up, /* wAccelKey_Pgup, */ + GDK_KEY_Page_Down, /* wAccelKey_Pgdn, */ + GDK_KEY_Up, /* wAccelKey_Up, */ + GDK_KEY_Down, /* wAccelKey_Down, */ + GDK_KEY_Right, /* wAccelKey_Right, */ + GDK_KEY_Left, /* wAccelKey_Left, */ + GDK_KEY_BackSpace, /* wAccelKey_Back, */ + GDK_KEY_F1, /* wAccelKey_F1, */ + GDK_KEY_F2, /* wAccelKey_F2, */ + GDK_KEY_F3, /* wAccelKey_F3, */ + GDK_KEY_F4, /* wAccelKey_F4, */ + GDK_KEY_F5, /* wAccelKey_F5, */ + GDK_KEY_F6, /* wAccelKey_F6, */ + GDK_KEY_F7, /* wAccelKey_F7, */ + GDK_KEY_F8, /* wAccelKey_F8, */ + GDK_KEY_F9, /* wAccelKey_F9, */ + GDK_KEY_F10, /* wAccelKey_F10, */ + GDK_KEY_F11, /* wAccelKey_F11, */ + GDK_KEY_F12, /* wAccelKey_F12, */ + GDK_KEY_KP_Add, /* wAccelKey_Numpad_Add */ + GDK_KEY_KP_Subtract /* wAccelKey_Numpad_Subtract */ }; /** @@ -542,20 +553,20 @@ static guint accelKeyMap[] = { */ void wAttachAccelKey( - wAccelKey_e key, - int modifier, - wAccelKeyCallBack_p action, - void * data) + wAccelKey_e key, + int modifier, + wAccelKeyCallBack_p action, + void * data) { accelData_t * ad; - if (key < 1 || key > wAccelKey_F12) { - fprintf(stderr, "wAttachAccelKey(%d) out of range\n", (int)key); - return; - } +// if (key < 1 || key > wAccelKey_F12) { +// fprintf(stderr, "wAttachAccelKey(%d) out of range\n", (int) key); +// return; +// } DYNARR_APPEND(accelData_t, accelData_da, 10); - ad = &accelData(accelData_da.cnt-1); + ad = &accelData(accelData_da.cnt - 1); ad->key = key; ad->modifier = modifier; ad->action = action; @@ -570,7 +581,7 @@ void wAttachAccelKey( */ struct accelData_t * wlibFindAccelKey( - GdkEventKey * event) + GdkEventKey * event) { accelData_t * ad; int modifier = 0; @@ -587,9 +598,9 @@ struct accelData_t * wlibFindAccelKey( modifier |= WKEY_ALT; } - for (ad=&accelData(0); ad<&accelData(accelData_da.cnt); ad++) + for (ad = &accelData(0); ad<&accelData(accelData_da.cnt); ad++) if (event->keyval == accelKeyMap[ad->key] && - modifier == ad->modifier) { + modifier == ad->modifier) { return ad; } @@ -604,7 +615,7 @@ struct accelData_t * wlibFindAccelKey( */ wBool_t wlibHandleAccelKey( - GdkEventKey *event) + GdkEventKey *event) { accelData_t * ad = wlibFindAccelKey(event); @@ -615,7 +626,7 @@ wBool_t wlibHandleAccelKey( return FALSE; } - + /** * Add control to circular list of synonymous controls. Synonymous controls are kept in sync by * calling wControlLinkedActive for one member of the list @@ -652,8 +663,9 @@ void wControlLinkedActive(wControl_p b, int active) wControl_p savePtr = b; if (savePtr->type == B_MENUITEM) { - wMenuPushEnable((wMenuPush_p)savePtr, active); - } else { + wMenuPushEnable((wMenuPush_p) savePtr, active); + } + else { wControlActive(savePtr, active); } @@ -662,8 +674,9 @@ void wControlLinkedActive(wControl_p b, int active) while (savePtr && savePtr != b) { if (savePtr->type == B_MENUITEM) { - wMenuPushEnable((wMenuPush_p)savePtr, active); - } else { + wMenuPushEnable((wMenuPush_p) savePtr, active); + } + else { wControlActive(savePtr, active); } diff --git a/app/wlib/gtklib/window.c b/app/wlib/gtklib/window.c index 489f35e..65706fd 100644 --- a/app/wlib/gtklib/window.c +++ b/app/wlib/gtklib/window.c @@ -48,6 +48,7 @@ extern wBool_t listHelpStrings; static wControl_p firstWin = NULL, lastWin; static int keyState; static wBool_t gtkBlockEnabled = TRUE; +static wBool_t maximize_at_next_show = FALSE; /* ***************************************************************************** @@ -58,6 +59,44 @@ static wBool_t gtkBlockEnabled = TRUE; */ /** + * Get the "monitor" size for the window (strictly the nearest or most used monitor) + * Note in OSX there is one giant virtual monitor so this doesn't work to force resize down... + * + */ + +static GdkRectangle getMonitorDimensions(GtkWidget * widget) { + + GdkRectangle monitor_dimensions; + + GdkScreen *screen = NULL; + + int monitor; + + GtkWidget * toplevel = gtk_widget_get_toplevel(widget); + + if (gtk_widget_is_toplevel(GTK_WIDGET(toplevel)) && + gtk_widget_get_parent_window(GTK_WIDGET(toplevel))) { + + GdkWindow * window = GDK_WINDOW(gtk_widget_get_parent_window(GTK_WIDGET(toplevel))); + + screen = gdk_window_get_screen(GDK_WINDOW(window)); + + monitor = gdk_screen_get_monitor_at_window(screen,GDK_WINDOW(window)); + + } else { + + screen = gdk_screen_get_default(); + + monitor = gdk_screen_get_primary_monitor(screen); + + } + + gdk_screen_get_monitor_geometry(screen,monitor,&monitor_dimensions); + + return monitor_dimensions; +} + +/** * Get the window size from the resource (.rc) file. The size is saved under the key * SECTIONWINDOWSIZE.window name * @@ -71,6 +110,16 @@ static void getWinSize(wWin_p win, const char * nameStr) const char *cp; char *cp1, *cp2; + /* + * Clamp window to be no bigger than one monitor size (to start - the user can always maximize) + */ + + GdkRectangle monitor_dimensions = getMonitorDimensions(GTK_WIDGET(win->gtkwin)); + + wPos_t maxDisplayWidth = monitor_dimensions.width-5; + wPos_t maxDisplayHeight = monitor_dimensions.height-25; + + if ((win->option&F_RESIZE) && (win->option&F_RECALLPOS) && (cp = wPrefGetString(SECTIONWINDOWSIZE, nameStr)) && @@ -84,6 +133,9 @@ static void getWinSize(wWin_p win, const char * nameStr) h = 10; } + if (w > maxDisplayWidth) w = maxDisplayWidth; + if (h > maxDisplayHeight) h = maxDisplayHeight; + win->w = win->origX = w; win->h = win->origY = h; win->option &= ~F_AUTOSIZE; @@ -103,7 +155,7 @@ static void saveSize(wWin_p win) if ((win->option&F_RESIZE) && (win->option&F_RECALLPOS) && gtk_widget_get_visible(GTK_WIDGET(win->gtkwin))) { - char pos_s[20]; + char pos_s[20]; sprintf(pos_s, "%d %d", win->w, win->h-(BORDERSIZE + ((win->option&F_MENUBAR)?MENUH:0))); @@ -121,14 +173,13 @@ static void saveSize(wWin_p win) static void getPos(wWin_p win) { char *cp1, *cp2; - wPos_t gtkDisplayWidth = gdk_screen_width(); - wPos_t gtkDisplayHeight = gdk_screen_height(); + GdkRectangle monitor_dimensions = getMonitorDimensions(GTK_WIDGET(win->gtkwin)); if ((win->option&F_RECALLPOS) && (!win->shown)) { - const char *cp; + const char *cp; if ((cp = wPrefGetString(SECTIONWINDOWPOS, win->nameStr))) { - int x, y; + int x, y; x = strtod(cp, &cp1); @@ -142,12 +193,12 @@ static void getPos(wWin_p win) return; } - if (y > gtkDisplayHeight-win->h) { - y = gtkDisplayHeight-win->h; + if (y > monitor_dimensions.height+monitor_dimensions.y-win->h) { + y = monitor_dimensions.height+monitor_dimensions.y-win->h; } - if (x > gtkDisplayWidth-win->w) { - x = gtkDisplayWidth-win->w; + if (x > monitor_dimensions.width+monitor_dimensions.x-win->w) { + x = monitor_dimensions.width+monitor_dimensions.x-win->w; } if (x <= 0) { @@ -176,7 +227,7 @@ static void savePos(wWin_p win) int x, y; if ((win->option&F_RECALLPOS)) { - char pos_s[20]; + char pos_s[20]; gdk_window_get_position(gtk_widget_get_window(GTK_WIDGET(win->gtkwin)), &x, &y); x -= 5; @@ -216,7 +267,7 @@ void wWinGetSize( } *width = w; - *height = h - BORDERSIZE - ((win->option&F_MENUBAR)?MENUH:0); + *height = h - BORDERSIZE - ((win->option&F_MENUBAR)?win->menu_height:0); } /** @@ -234,8 +285,8 @@ void wWinSetSize( { win->busy = TRUE; win->w = width; - win->h = height + BORDERSIZE + ((win->option&F_MENUBAR)?MENUH:0); - gtk_widget_set_size_request(win->gtkwin, win->w, win->h); + win->h = height + BORDERSIZE + ((win->option&F_MENUBAR)?win->menu_height:0); + //gtk_widget_set_size_request(win->gtkwin, win->w, win->h); gtk_widget_set_size_request(win->widget, win->w, win->h); win->busy = FALSE; } @@ -271,11 +322,15 @@ void wWinShow( gtk_widget_size_request(win->gtkwin, &requisition); if (requisition.width != win->w || requisition.height != win->h) { - gtk_widget_set_size_request(win->gtkwin, win->w, win->h); - gtk_widget_set_size_request(win->widget, win->w, win->h); + //gtk_window_resize(GTK_WINDOW(win->gtkwin), win->w, win->h); + gtk_widget_set_size_request(win->gtkwin, win->w, win->h); + gtk_widget_set_size_request(win->widget, win->w-20, win->h); if (win->option&F_MENUBAR) { - gtk_widget_set_size_request(win->menubar, win->w, MENUH); + gtk_widget_set_size_request(win->menubar, win->w-20, MENUH); + GtkAllocation allocation; + gtk_widget_get_allocation(win->menubar, &allocation); + win->menu_height = allocation.height; } } } @@ -299,6 +354,10 @@ void wWinShow( } else { wlibDoModal(win, TRUE); } + if (maximize_at_next_show) { + gtk_window_maximize(GTK_WINDOW(win->gtkwin)); + maximize_at_next_show = FALSE; + } } else { wFlush(); saveSize(win); @@ -340,6 +399,18 @@ wBool_t wWinIsVisible( } /** + * Returns whether the window is maximized. + * + * \param win IN window + * \return TRUE if maximized, FALSE otherwise + */ + +wBool_t wWinIsMaximized(wWin_p win) +{ + return win->maximize_initially; +} + +/** * Sets the title of <win> to <title>. * * \param varname1 IN window @@ -480,6 +551,25 @@ void wWinDoCancel( ****************************************************************************** */ +static int window_redraw( + wWin_p win, + wBool_t doWinProc) +{ + wControl_p b; + + if (win==NULL) { + return FALSE; + } + + for (b=win->first; b != NULL; b = b->next) { + if (b->repaintProc) { + b->repaintProc(b); + } + } + + return FALSE; +} + static gint window_delete_event( GtkWidget *widget, GdkEvent *event, @@ -511,25 +601,6 @@ static gint window_delete_event( return (TRUE); } -static int window_redraw( - wWin_p win, - wBool_t doWinProc) -{ - wControl_p b; - - if (win==NULL) { - return FALSE; - } - - for (b=win->first; b != NULL; b = b->next) { - if (b->repaintProc) { - b->repaintProc(b); - } - } - - return FALSE; -} - static int fixed_expose_event( GtkWidget * widget, GdkEventExpose * event, @@ -542,27 +613,37 @@ static int fixed_expose_event( } } +static int resizeTime(wWin_p win) { + + if (win->resizeW == win->w && win->resizeH == win->h) { // If hasn't changed since last + win->resizeTimer = 0; + return FALSE; //Stop Timer and don't resize + } + if (win->busy==FALSE && win->winProc) { //Always drive once + win->winProc(win, wResize_e, win->data); + win->resizeW = win->w; //Remember this one + win->resizeH = win->h; + } + return TRUE; //Will redrive after another timer interval +} + static int window_configure_event( GtkWidget * widget, GdkEventConfigure * event, wWin_p win) { -// wPos_t h; if (win==NULL) { return FALSE; } - //h = event->height - BORDERSIZE; - - //if (win->option&F_MENUBAR) { - //h -= MENUH; - //} - if (win->option&F_RESIZE) { if (event->width < 10 || event->height < 10) { return TRUE; } + int w = win->w; + int h = win->h; + if (win->w != event->width || win->h != event->height) { win->w = event->width; @@ -577,11 +658,18 @@ static int window_configure_event( } if (win->option&F_MENUBAR) { - gtk_widget_set_size_request(win->menubar, win->w, MENUH); + GtkAllocation allocation; + gtk_widget_get_allocation(win->menubar, &allocation); + win->menu_height= allocation.height; + gtk_widget_set_size_request(win->menubar, win->w-20, win->menu_height); } - - if (win->busy==FALSE && win->winProc) { - win->winProc(win, wResize_e, win->data); + if (win->resizeTimer) { // Already have a timer + return FALSE; + } else { + win->resizeW = w; //Remember where this started + win->resizeH = h; + win->resizeTimer = g_timeout_add(200,(GSourceFunc)resizeTime,win); // 200ms delay + return FALSE; } } } @@ -590,6 +678,38 @@ static int window_configure_event( } /** + * Event handler for window state changes (maximize) + * Handles maximize event by storing the new state in the internal structure and + * calling the event handler + * + * \param widget gtk widget + * \param event event information + * \param win the wlib internal window data + * \return TRUE if win is valid, + */ + +gboolean window_state_event( + GtkWidget *widget, + GdkEventWindowState *event, + wWin_p win) +{ + if (!win) { + return (FALSE); + } + + win->maximize_initially = FALSE; + + if (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) { + win->maximize_initially = TRUE; + } + + if (win->busy==FALSE && win->winProc) { + win->winProc(win, wState_e, win->data); + } + + return TRUE; +} +/** * Get current state of shift, ctrl or alt keys. * * \return or'ed value of WKEY_SHIFT, WKEY_CTRL and WKEY_ALT depending on state @@ -680,19 +800,22 @@ static gint window_char_event( ******************************************************************************* */ + /** - * Create a window + * Create a window. + * Default width and height are replaced by values stored in the configuration + * file (.rc) * * \param parent IN parent window * \param winType IN type of window - * \param x IN x position - * \param y IN y position + * \param x IN default width + * \param y IN default height * \param labelStr IN window title - * \param nameStr IN - * \param option IN + * \param nameStr IN name of window + * \param option IN misc options for placement and sizing of window * \param winProc IN window procedure * \param data IN additional data to pass to the window procedure - * \return describe the return value + * \return the newly created window */ static wWin_p wWinCommonCreate( @@ -711,7 +834,9 @@ static wWin_p wWinCommonCreate( w = wlibAlloc(NULL, winType, x, y, labelStr, sizeof *w, data); w->busy = TRUE; w->option = option; - getWinSize(w, nameStr); + w->resizeTimer = 0; + + h = BORDERSIZE; if (w->option&F_MENUBAR) { @@ -728,6 +853,9 @@ static wWin_p wWinCommonCreate( GTK_WINDOW(gtkMainW->gtkwin)); } } + if (winType != W_MAIN) { + getWinSize(w, nameStr); + } if (option & F_HIDE) { gtk_widget_hide(w->gtkwin); @@ -738,6 +866,7 @@ static wWin_p wWinCommonCreate( gtk_window_set_position(GTK_WINDOW(w->gtkwin), GTK_WIN_POS_CENTER_ON_PARENT); } + w->widget = gtk_fixed_new(); if (w->widget == 0) { @@ -748,7 +877,10 @@ static wWin_p wWinCommonCreate( w->menubar = gtk_menu_bar_new(); gtk_container_add(GTK_CONTAINER(w->widget), w->menubar); gtk_widget_show(w->menubar); - gtk_widget_set_size_request(w->menubar, -1, MENUH); + GtkAllocation allocation; + gtk_widget_get_allocation(w->menubar, &allocation); + w->menu_height = allocation.height; + gtk_widget_set_size_request(w->menubar, -1, w->menu_height); } gtk_container_add(GTK_CONTAINER(w->gtkwin), w->widget); @@ -758,14 +890,14 @@ static wWin_p wWinCommonCreate( w->w = 0; w->realY = h; w->h = 0; - } else { + } else if (w->origX != 0){ w->w = w->realX = w->origX; w->h = w->realY = w->origY+h; - gtk_widget_set_size_request(w->gtkwin, w->w, w->h); - gtk_widget_set_size_request(w->widget, w->w, w->h); + gtk_window_set_default_size(GTK_WINDOW(w->gtkwin), w->w, w->h); + //gtk_widget_set_size_request(w->widget, w->w-20, w->h); if (w->option&F_MENUBAR) { - gtk_widget_set_size_request(w->menubar, w->w, MENUH); + gtk_widget_set_size_request(w->menubar, w->w-20, MENUH); } } @@ -777,6 +909,8 @@ static wWin_p wWinCommonCreate( G_CALLBACK(fixed_expose_event), w); g_signal_connect(GTK_OBJECT(w->gtkwin), "configure_event", G_CALLBACK(window_configure_event), w); + g_signal_connect(GTK_OBJECT(w->gtkwin), "window-state-event", + G_CALLBACK(window_state_event), w); g_signal_connect(GTK_OBJECT(w->gtkwin), "key_press_event", G_CALLBACK(window_char_event), w); g_signal_connect(GTK_OBJECT(w->gtkwin), "key_release_event", @@ -813,7 +947,16 @@ static wWin_p wWinCommonCreate( lastWin = (wControl_p)w; gtk_widget_show(w->widget); gtk_widget_realize(w->gtkwin); + GtkAllocation allocation; + gtk_widget_get_allocation(w->gtkwin, &allocation); + w->menu_height = allocation.height; + w->busy = FALSE; + + if (option&F_MAXIMIZE) { + maximize_at_next_show = TRUE; + } + return w; } @@ -846,8 +989,11 @@ wWin_p wWinMainCreate( void * data) /* User context */ { char *pos; + long isMaximized; - if (pos = strchr(name, ';')) { + pos = strchr(name, ';'); + + if (pos) { /* if found, split application name and configuration name */ strcpy(wConfigName, pos + 1); } else { @@ -855,8 +1001,12 @@ wWin_p wWinMainCreate( strcpy(wConfigName, name); } + wPrefGetInteger("draw", "maximized", &isMaximized, 0); + option = option | (isMaximized?F_MAXIMIZE:0); + gtkMainW = wWinCommonCreate(NULL, W_MAIN, x, y, labelStr, nameStr, option, winProc, data); + wDrawColorWhite = wDrawFindColor(0xFFFFFF); wDrawColorBlack = wDrawFindColor(0x000000); return gtkMainW; diff --git a/app/wlib/gtklib/wpref.c b/app/wlib/gtklib/wpref.c index effc2a5..c2541f9 100644 --- a/app/wlib/gtklib/wpref.c +++ b/app/wlib/gtklib/wpref.c @@ -312,7 +312,7 @@ void wPrefSetString( * \param name IN name of parameter */ -const char * wPrefGetString( +char * wPrefGetStringBasic( const char * section, /* Section */ const char * name ) /* Name */ { @@ -358,7 +358,7 @@ const char * wPrefGetString( * \return TRUE if value differs from default, FALSE if the same */ -wBool_t wPrefGetInteger( +wBool_t wPrefGetIntegerBasic( const char * section, /* Section */ const char * name, /* Name */ long * res, /* Address of result */ @@ -367,7 +367,7 @@ wBool_t wPrefGetInteger( const char * cp; char *cp1; - cp = wPrefGetString( section, name ); + cp = wPrefGetStringBasic( section, name ); if (cp == NULL) { *res = def; return FALSE; @@ -410,7 +410,7 @@ wBool_t wPrefGetInteger( */ -wBool_t wPrefGetFloat( +wBool_t wPrefGetFloatBasic( const char * section, /* Section */ const char * name, /* Name */ double * res, /* Address of result */ @@ -419,7 +419,7 @@ wBool_t wPrefGetFloat( const char * cp; char *cp1; - cp = wPrefGetString( section, name ); + cp = wPrefGetStringBasic( section, name ); if (cp == NULL) { *res = def; return FALSE; |