2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
2003-10-02 19:26:26 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2009-01-18 06:28:01 +08:00
|
|
|
* This program is free software: you can redistribute it and/or modify
|
2003-10-02 19:26:26 +08:00
|
|
|
* it under the terms of the GNU General Public License as published by
|
2009-01-18 06:28:01 +08:00
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
2003-10-02 19:26:26 +08:00
|
|
|
* (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
|
2009-01-18 06:28:01 +08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2003-10-02 19:26:26 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2004-04-27 20:28:27 +08:00
|
|
|
#include <string.h>
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#include <errno.h>
|
2004-04-27 20:28:27 +08:00
|
|
|
|
2008-10-10 04:24:04 +08:00
|
|
|
#include <gegl.h>
|
2003-10-02 19:26:26 +08:00
|
|
|
#include <gtk/gtk.h>
|
2008-03-29 18:50:10 +08:00
|
|
|
|
|
|
|
#ifdef GDK_WINDOWING_X11
|
2008-03-29 08:03:52 +08:00
|
|
|
#include <gdk/gdkx.h>
|
2008-03-29 18:50:10 +08:00
|
|
|
#endif
|
2003-10-02 19:26:26 +08:00
|
|
|
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#ifdef G_OS_WIN32
|
|
|
|
#include <windows.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <io.h>
|
|
|
|
|
|
|
|
#ifndef pipe
|
|
|
|
#define pipe(fds) _pipe(fds, 4096, _O_BINARY)
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "libgimpbase/gimpbase.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
|
|
|
#include "gui-types.h"
|
|
|
|
|
2003-11-12 07:56:00 +08:00
|
|
|
#include "config/gimpguiconfig.h"
|
|
|
|
|
2003-10-02 19:26:26 +08:00
|
|
|
#include "core/gimp.h"
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#include "core/gimp-parallel.h"
|
|
|
|
#include "core/gimp-spawn.h"
|
2004-07-11 06:25:02 +08:00
|
|
|
#include "core/gimp-utils.h"
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#include "core/gimpasync.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "core/gimpbrush.h"
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#include "core/gimpcancelable.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "core/gimpcontainer.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
#include "core/gimpcontext.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "core/gimpgradient.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
#include "core/gimpimage.h"
|
2008-03-24 19:11:15 +08:00
|
|
|
#include "core/gimpimagefile.h"
|
|
|
|
#include "core/gimplist.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "core/gimppalette.h"
|
|
|
|
#include "core/gimppattern.h"
|
2004-08-11 02:47:21 +08:00
|
|
|
#include "core/gimpprogress.h"
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#include "core/gimpwaitable.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
|
|
|
|
#include "text/gimpfont.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
#include "pdb/gimppdb.h"
|
|
|
|
#include "pdb/gimpprocedure.h"
|
|
|
|
|
2016-01-04 03:05:27 +08:00
|
|
|
#include "plug-in/gimppluginmanager-file.h"
|
2014-07-05 02:01:08 +08:00
|
|
|
|
2004-04-26 23:01:00 +08:00
|
|
|
#include "widgets/gimpactiongroup.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "widgets/gimpbrushselect.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
#include "widgets/gimpdialogfactory.h"
|
2006-06-26 16:09:23 +08:00
|
|
|
#include "widgets/gimpdocked.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "widgets/gimpfontselect.h"
|
|
|
|
#include "widgets/gimpgradientselect.h"
|
2004-07-11 04:29:11 +08:00
|
|
|
#include "widgets/gimphelp.h"
|
2004-07-10 03:14:59 +08:00
|
|
|
#include "widgets/gimphelp-ids.h"
|
|
|
|
#include "widgets/gimpmenufactory.h"
|
|
|
|
#include "widgets/gimppaletteselect.h"
|
|
|
|
#include "widgets/gimppatternselect.h"
|
2004-08-11 02:47:21 +08:00
|
|
|
#include "widgets/gimpprogressdialog.h"
|
2004-04-22 00:33:17 +08:00
|
|
|
#include "widgets/gimpuimanager.h"
|
2005-09-10 02:07:31 +08:00
|
|
|
#include "widgets/gimpwidgets-utils.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
|
|
|
|
#include "display/gimpdisplay.h"
|
|
|
|
#include "display/gimpdisplay-foreach.h"
|
|
|
|
#include "display/gimpdisplayshell.h"
|
2011-07-04 02:55:03 +08:00
|
|
|
#include "display/gimpsinglewindowstrategy.h"
|
|
|
|
#include "display/gimpmultiwindowstrategy.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
|
2004-04-26 23:01:00 +08:00
|
|
|
#include "actions/plug-in-actions.h"
|
|
|
|
|
2004-05-06 15:41:53 +08:00
|
|
|
#include "menus/menus.h"
|
|
|
|
|
2015-08-23 16:51:31 +08:00
|
|
|
#include "dialogs/color-profile-import-dialog.h"
|
|
|
|
|
2014-05-03 06:54:20 +08:00
|
|
|
#include "gui.h"
|
2006-07-19 14:50:34 +08:00
|
|
|
#include "gui-message.h"
|
2006-10-30 18:13:06 +08:00
|
|
|
#include "gui-vtable.h"
|
2015-12-09 03:52:12 +08:00
|
|
|
#include "icon-themes.h"
|
2003-11-10 23:13:29 +08:00
|
|
|
#include "themes.h"
|
2003-10-02 19:26:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
|
2014-07-11 04:52:29 +08:00
|
|
|
static void gui_ungrab (Gimp *gimp);
|
|
|
|
|
2018-05-02 22:14:54 +08:00
|
|
|
static void gui_threads_enter (Gimp *gimp);
|
|
|
|
static void gui_threads_leave (Gimp *gimp);
|
|
|
|
|
2014-07-11 04:52:29 +08:00
|
|
|
static void gui_set_busy (Gimp *gimp);
|
|
|
|
static void gui_unset_busy (Gimp *gimp);
|
|
|
|
|
|
|
|
static void gui_help (Gimp *gimp,
|
|
|
|
GimpProgress *progress,
|
|
|
|
const gchar *help_domain,
|
|
|
|
const gchar *help_id);
|
|
|
|
static const gchar * gui_get_program_class (Gimp *gimp);
|
|
|
|
static gchar * gui_get_display_name (Gimp *gimp,
|
|
|
|
gint display_ID,
|
2018-04-29 23:27:47 +08:00
|
|
|
GObject **monitor,
|
|
|
|
gint *monitor_number);
|
2014-07-11 04:52:29 +08:00
|
|
|
static guint32 gui_get_user_time (Gimp *gimp);
|
2014-07-17 16:09:19 +08:00
|
|
|
static GFile * gui_get_theme_dir (Gimp *gimp);
|
2015-12-09 03:52:12 +08:00
|
|
|
static GFile * gui_get_icon_theme_dir (Gimp *gimp);
|
2014-07-11 04:52:29 +08:00
|
|
|
static GimpObject * gui_get_window_strategy (Gimp *gimp);
|
|
|
|
static GimpObject * gui_get_empty_display (Gimp *gimp);
|
|
|
|
static GimpObject * gui_display_get_by_ID (Gimp *gimp,
|
|
|
|
gint ID);
|
|
|
|
static gint gui_display_get_ID (GimpObject *display);
|
|
|
|
static guint32 gui_display_get_window_id (GimpObject *display);
|
|
|
|
static GimpObject * gui_display_create (Gimp *gimp,
|
|
|
|
GimpImage *image,
|
|
|
|
GimpUnit unit,
|
|
|
|
gdouble scale,
|
2018-04-29 23:27:47 +08:00
|
|
|
GObject *monitor);
|
2014-07-11 04:52:29 +08:00
|
|
|
static void gui_display_delete (GimpObject *display);
|
|
|
|
static void gui_displays_reconnect (Gimp *gimp,
|
|
|
|
GimpImage *old_image,
|
|
|
|
GimpImage *new_image);
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
static gboolean gui_wait (Gimp *gimp,
|
|
|
|
GimpWaitable *waitable,
|
|
|
|
const gchar *message);
|
2014-07-11 04:52:29 +08:00
|
|
|
static GimpProgress * gui_new_progress (Gimp *gimp,
|
|
|
|
GimpObject *display);
|
|
|
|
static void gui_free_progress (Gimp *gimp,
|
|
|
|
GimpProgress *progress);
|
|
|
|
static gboolean gui_pdb_dialog_new (Gimp *gimp,
|
|
|
|
GimpContext *context,
|
|
|
|
GimpProgress *progress,
|
|
|
|
GimpContainer *container,
|
|
|
|
const gchar *title,
|
|
|
|
const gchar *callback_name,
|
|
|
|
const gchar *object_name,
|
|
|
|
va_list args);
|
|
|
|
static gboolean gui_pdb_dialog_set (Gimp *gimp,
|
|
|
|
GimpContainer *container,
|
|
|
|
const gchar *callback_name,
|
|
|
|
const gchar *object_name,
|
|
|
|
va_list args);
|
|
|
|
static gboolean gui_pdb_dialog_close (Gimp *gimp,
|
|
|
|
GimpContainer *container,
|
|
|
|
const gchar *callback_name);
|
|
|
|
static gboolean gui_recent_list_add_file (Gimp *gimp,
|
|
|
|
GFile *file,
|
|
|
|
const gchar *mime_type);
|
|
|
|
static void gui_recent_list_load (Gimp *gimp);
|
|
|
|
|
2015-08-23 16:51:31 +08:00
|
|
|
static GMountOperation
|
|
|
|
* gui_get_mount_operation (Gimp *gimp,
|
2014-07-23 02:29:52 +08:00
|
|
|
GimpProgress *progress);
|
2008-03-24 19:11:15 +08:00
|
|
|
|
2015-08-23 16:51:31 +08:00
|
|
|
static GimpColorProfilePolicy
|
|
|
|
gui_query_profile_policy (Gimp *gimp,
|
|
|
|
GimpImage *image,
|
|
|
|
GimpContext *context,
|
|
|
|
GimpColorProfile **dest_profile,
|
2016-06-06 04:36:52 +08:00
|
|
|
GimpColorRenderingIntent *intent,
|
|
|
|
gboolean *bpc,
|
2015-08-23 16:51:31 +08:00
|
|
|
gboolean *dont_ask);
|
|
|
|
|
2003-10-02 19:26:26 +08:00
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
|
|
|
void
|
|
|
|
gui_vtable_init (Gimp *gimp)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
|
|
|
|
2014-07-11 04:52:29 +08:00
|
|
|
gimp->gui.ungrab = gui_ungrab;
|
2018-05-02 22:14:54 +08:00
|
|
|
gimp->gui.threads_enter = gui_threads_enter;
|
|
|
|
gimp->gui.threads_leave = gui_threads_leave;
|
2014-07-11 04:52:29 +08:00
|
|
|
gimp->gui.set_busy = gui_set_busy;
|
|
|
|
gimp->gui.unset_busy = gui_unset_busy;
|
|
|
|
gimp->gui.show_message = gui_message;
|
|
|
|
gimp->gui.help = gui_help;
|
|
|
|
gimp->gui.get_program_class = gui_get_program_class;
|
|
|
|
gimp->gui.get_display_name = gui_get_display_name;
|
|
|
|
gimp->gui.get_user_time = gui_get_user_time;
|
|
|
|
gimp->gui.get_theme_dir = gui_get_theme_dir;
|
2015-12-09 03:52:12 +08:00
|
|
|
gimp->gui.get_icon_theme_dir = gui_get_icon_theme_dir;
|
2014-07-11 04:52:29 +08:00
|
|
|
gimp->gui.get_window_strategy = gui_get_window_strategy;
|
|
|
|
gimp->gui.get_empty_display = gui_get_empty_display;
|
|
|
|
gimp->gui.display_get_by_id = gui_display_get_by_ID;
|
|
|
|
gimp->gui.display_get_id = gui_display_get_ID;
|
|
|
|
gimp->gui.display_get_window_id = gui_display_get_window_id;
|
|
|
|
gimp->gui.display_create = gui_display_create;
|
|
|
|
gimp->gui.display_delete = gui_display_delete;
|
|
|
|
gimp->gui.displays_reconnect = gui_displays_reconnect;
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
gimp->gui.wait = gui_wait;
|
2014-07-11 04:52:29 +08:00
|
|
|
gimp->gui.progress_new = gui_new_progress;
|
|
|
|
gimp->gui.progress_free = gui_free_progress;
|
|
|
|
gimp->gui.pdb_dialog_new = gui_pdb_dialog_new;
|
|
|
|
gimp->gui.pdb_dialog_set = gui_pdb_dialog_set;
|
|
|
|
gimp->gui.pdb_dialog_close = gui_pdb_dialog_close;
|
|
|
|
gimp->gui.recent_list_add_file = gui_recent_list_add_file;
|
|
|
|
gimp->gui.recent_list_load = gui_recent_list_load;
|
2014-07-23 02:29:52 +08:00
|
|
|
gimp->gui.get_mount_operation = gui_get_mount_operation;
|
2015-08-23 16:51:31 +08:00
|
|
|
gimp->gui.query_profile_policy = gui_query_profile_policy;
|
2003-10-02 19:26:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* private functions */
|
|
|
|
|
2006-09-10 00:36:15 +08:00
|
|
|
static void
|
|
|
|
gui_ungrab (Gimp *gimp)
|
|
|
|
{
|
|
|
|
GdkDisplay *display = gdk_display_get_default ();
|
|
|
|
|
2006-09-10 19:39:24 +08:00
|
|
|
if (display)
|
2018-05-24 01:19:51 +08:00
|
|
|
gdk_seat_ungrab (gdk_display_get_default_seat (display));
|
2006-09-10 00:36:15 +08:00
|
|
|
}
|
|
|
|
|
2018-05-02 22:14:54 +08:00
|
|
|
static void
|
|
|
|
gui_threads_enter (Gimp *gimp)
|
|
|
|
{
|
|
|
|
GDK_THREADS_ENTER ();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gui_threads_leave (Gimp *gimp)
|
|
|
|
{
|
|
|
|
GDK_THREADS_LEAVE ();
|
|
|
|
}
|
|
|
|
|
2003-10-02 19:26:26 +08:00
|
|
|
static void
|
|
|
|
gui_set_busy (Gimp *gimp)
|
|
|
|
{
|
|
|
|
gimp_displays_set_busy (gimp);
|
2010-03-01 06:20:57 +08:00
|
|
|
gimp_dialog_factory_set_busy (gimp_dialog_factory_get_singleton ());
|
2003-10-02 19:26:26 +08:00
|
|
|
|
2018-05-08 06:54:02 +08:00
|
|
|
gdk_display_flush (gdk_display_get_default ());
|
2003-10-02 19:26:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gui_unset_busy (Gimp *gimp)
|
|
|
|
{
|
|
|
|
gimp_displays_unset_busy (gimp);
|
2010-03-01 06:20:57 +08:00
|
|
|
gimp_dialog_factory_unset_busy (gimp_dialog_factory_get_singleton ());
|
2003-10-02 19:26:26 +08:00
|
|
|
|
2018-05-08 06:54:02 +08:00
|
|
|
gdk_display_flush (gdk_display_get_default ());
|
2003-10-02 19:26:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2008-06-10 17:54:54 +08:00
|
|
|
gui_help (Gimp *gimp,
|
|
|
|
GimpProgress *progress,
|
|
|
|
const gchar *help_domain,
|
|
|
|
const gchar *help_id)
|
2003-10-02 19:26:26 +08:00
|
|
|
{
|
2008-06-10 17:54:54 +08:00
|
|
|
gimp_help_show (gimp, progress, help_domain, help_id);
|
2003-10-02 19:26:26 +08:00
|
|
|
}
|
|
|
|
|
2004-07-12 19:41:19 +08:00
|
|
|
static const gchar *
|
|
|
|
gui_get_program_class (Gimp *gimp)
|
|
|
|
{
|
|
|
|
return gdk_get_program_class ();
|
|
|
|
}
|
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
static gint
|
|
|
|
get_monitor_number (GdkMonitor *monitor)
|
|
|
|
{
|
|
|
|
GdkDisplay *display = gdk_monitor_get_display (monitor);
|
|
|
|
gint n_monitors = gdk_display_get_n_monitors (display);
|
|
|
|
gint i;
|
|
|
|
|
|
|
|
for (i = 0; i < n_monitors; i++)
|
|
|
|
if (gdk_display_get_monitor (display, i) == monitor)
|
|
|
|
return i;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-07-12 19:41:19 +08:00
|
|
|
static gchar *
|
2014-05-03 06:54:20 +08:00
|
|
|
gui_get_display_name (Gimp *gimp,
|
|
|
|
gint display_ID,
|
2018-04-29 23:27:47 +08:00
|
|
|
GObject **monitor,
|
|
|
|
gint *monitor_number)
|
2004-07-12 19:41:19 +08:00
|
|
|
{
|
2018-04-29 23:27:47 +08:00
|
|
|
GimpDisplay *display = NULL;
|
|
|
|
GdkDisplay *gdk_display;
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
if (display_ID > 0)
|
|
|
|
display = gimp_display_get_by_ID (gimp, display_ID);
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
if (display)
|
2004-07-12 19:41:19 +08:00
|
|
|
{
|
2018-04-29 23:27:47 +08:00
|
|
|
GimpDisplayShell *shell = gimp_display_get_shell (display);
|
|
|
|
|
|
|
|
gdk_display = gtk_widget_get_display (GTK_WIDGET (shell));
|
2009-10-06 01:58:03 +08:00
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
*monitor = G_OBJECT (gimp_widget_get_monitor (GTK_WIDGET (shell)));
|
2004-07-12 19:41:19 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-04-29 23:27:47 +08:00
|
|
|
*monitor = G_OBJECT (gui_get_initial_monitor (gimp));
|
2014-05-03 06:54:20 +08:00
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
if (! *monitor)
|
|
|
|
*monitor = G_OBJECT (gimp_get_monitor_at_pointer ());
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
gdk_display = gdk_monitor_get_display (GDK_MONITOR (*monitor));
|
|
|
|
}
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
*monitor_number = get_monitor_number (GDK_MONITOR (*monitor));
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
return gdk_screen_make_display_name (gdk_display_get_default_screen (gdk_display));
|
2004-07-12 19:41:19 +08:00
|
|
|
}
|
|
|
|
|
2008-03-28 00:30:29 +08:00
|
|
|
static guint32
|
|
|
|
gui_get_user_time (Gimp *gimp)
|
|
|
|
{
|
|
|
|
#ifdef GDK_WINDOWING_X11
|
|
|
|
return gdk_x11_display_get_user_time (gdk_display_get_default ());
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-07-17 16:09:19 +08:00
|
|
|
static GFile *
|
2004-07-12 19:41:19 +08:00
|
|
|
gui_get_theme_dir (Gimp *gimp)
|
|
|
|
{
|
|
|
|
return themes_get_theme_dir (gimp, GIMP_GUI_CONFIG (gimp->config)->theme);
|
|
|
|
}
|
|
|
|
|
2015-12-09 03:52:12 +08:00
|
|
|
static GFile *
|
|
|
|
gui_get_icon_theme_dir (Gimp *gimp)
|
|
|
|
{
|
|
|
|
return icon_themes_get_theme_dir (gimp, GIMP_GUI_CONFIG (gimp->config)->icon_theme);
|
|
|
|
}
|
|
|
|
|
2011-07-04 02:55:03 +08:00
|
|
|
static GimpObject *
|
|
|
|
gui_get_window_strategy (Gimp *gimp)
|
|
|
|
{
|
|
|
|
if (GIMP_GUI_CONFIG (gimp->config)->single_window_mode)
|
|
|
|
return gimp_single_window_strategy_get_singleton ();
|
|
|
|
else
|
|
|
|
return gimp_multi_window_strategy_get_singleton ();
|
|
|
|
}
|
|
|
|
|
2008-03-25 18:50:42 +08:00
|
|
|
static GimpObject *
|
|
|
|
gui_get_empty_display (Gimp *gimp)
|
|
|
|
{
|
|
|
|
GimpObject *display = NULL;
|
|
|
|
|
2008-11-21 06:45:19 +08:00
|
|
|
if (gimp_container_get_n_children (gimp->displays) == 1)
|
2008-03-25 18:50:42 +08:00
|
|
|
{
|
2008-04-09 17:50:29 +08:00
|
|
|
display = gimp_container_get_first_child (gimp->displays);
|
2008-03-25 18:50:42 +08:00
|
|
|
|
2009-10-07 01:20:44 +08:00
|
|
|
if (gimp_display_get_image (GIMP_DISPLAY (display)))
|
2008-03-25 18:50:42 +08:00
|
|
|
{
|
|
|
|
/* The display was not empty */
|
|
|
|
display = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return display;
|
|
|
|
}
|
|
|
|
|
2004-07-12 19:41:19 +08:00
|
|
|
static GimpObject *
|
|
|
|
gui_display_get_by_ID (Gimp *gimp,
|
|
|
|
gint ID)
|
|
|
|
{
|
|
|
|
return (GimpObject *) gimp_display_get_by_ID (gimp, ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gui_display_get_ID (GimpObject *display)
|
|
|
|
{
|
|
|
|
return gimp_display_get_ID (GIMP_DISPLAY (display));
|
|
|
|
}
|
|
|
|
|
2005-09-06 04:47:12 +08:00
|
|
|
static guint32
|
2011-02-06 19:07:55 +08:00
|
|
|
gui_display_get_window_id (GimpObject *display)
|
2005-09-06 04:47:12 +08:00
|
|
|
{
|
2009-10-06 01:58:03 +08:00
|
|
|
GimpDisplay *disp = GIMP_DISPLAY (display);
|
|
|
|
GimpDisplayShell *shell = gimp_display_get_shell (disp);
|
2005-09-10 02:07:31 +08:00
|
|
|
|
2009-10-06 01:58:03 +08:00
|
|
|
if (shell)
|
2009-09-30 23:01:55 +08:00
|
|
|
{
|
2009-10-06 01:58:03 +08:00
|
|
|
GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (shell));
|
2009-09-30 23:01:55 +08:00
|
|
|
|
|
|
|
if (GTK_IS_WINDOW (toplevel))
|
2011-02-06 19:07:55 +08:00
|
|
|
return gimp_window_get_native_id (GTK_WINDOW (toplevel));
|
2009-09-30 23:01:55 +08:00
|
|
|
}
|
2005-09-10 02:07:31 +08:00
|
|
|
|
2005-09-06 04:47:12 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-07-12 19:41:19 +08:00
|
|
|
static GimpObject *
|
2008-03-19 05:22:21 +08:00
|
|
|
gui_display_create (Gimp *gimp,
|
|
|
|
GimpImage *image,
|
2004-07-12 19:41:19 +08:00
|
|
|
GimpUnit unit,
|
2014-05-03 02:20:46 +08:00
|
|
|
gdouble scale,
|
2018-04-29 23:27:47 +08:00
|
|
|
GObject *monitor)
|
2004-07-12 19:41:19 +08:00
|
|
|
{
|
2008-03-19 05:22:21 +08:00
|
|
|
GimpContext *context = gimp_get_user_context (gimp);
|
2008-03-30 06:08:15 +08:00
|
|
|
GimpDisplay *display = GIMP_DISPLAY (gui_get_empty_display (gimp));
|
2008-03-19 05:22:21 +08:00
|
|
|
|
2018-04-29 23:27:47 +08:00
|
|
|
if (! monitor)
|
|
|
|
monitor = G_OBJECT (gimp_get_monitor_at_pointer ());
|
2014-05-03 02:20:46 +08:00
|
|
|
|
2008-03-25 18:50:42 +08:00
|
|
|
if (display)
|
2008-03-19 05:22:21 +08:00
|
|
|
{
|
2008-03-20 00:15:50 +08:00
|
|
|
gimp_display_fill (display, image, unit, scale);
|
2008-03-19 05:22:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GList *image_managers = gimp_ui_managers_from_name ("<Image>");
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
g_return_val_if_fail (image_managers != NULL, NULL);
|
2008-02-27 16:20:54 +08:00
|
|
|
|
2008-03-19 05:22:21 +08:00
|
|
|
display = gimp_display_new (gimp, image, unit, scale,
|
2008-03-23 21:40:39 +08:00
|
|
|
image_managers->data,
|
2014-05-03 02:20:46 +08:00
|
|
|
gimp_dialog_factory_get_singleton (),
|
2018-04-29 23:27:47 +08:00
|
|
|
GDK_MONITOR (monitor));
|
2008-03-19 05:22:21 +08:00
|
|
|
}
|
2004-07-12 19:41:19 +08:00
|
|
|
|
2008-03-21 05:07:09 +08:00
|
|
|
if (gimp_context_get_display (context) == display)
|
|
|
|
{
|
|
|
|
gimp_context_set_image (context, image);
|
|
|
|
gimp_context_display_changed (context);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gimp_context_set_display (context, display);
|
|
|
|
}
|
2008-03-21 04:05:45 +08:00
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
return GIMP_OBJECT (display);
|
2004-07-12 19:41:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gui_display_delete (GimpObject *display)
|
|
|
|
{
|
2008-04-06 04:32:24 +08:00
|
|
|
gimp_display_close (GIMP_DISPLAY (display));
|
2004-07-12 19:41:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gui_displays_reconnect (Gimp *gimp,
|
|
|
|
GimpImage *old_image,
|
|
|
|
GimpImage *new_image)
|
|
|
|
{
|
|
|
|
gimp_displays_reconnect (gimp, old_image, new_image);
|
|
|
|
}
|
|
|
|
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
static void
|
|
|
|
gui_wait_input_async (GimpAsync *async,
|
|
|
|
const gint input_pipe[2])
|
|
|
|
{
|
|
|
|
guint8 buffer[1];
|
|
|
|
|
|
|
|
while (read (input_pipe[0], buffer, sizeof (buffer)) == -1 &&
|
|
|
|
errno == EINTR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
2018-05-30 04:32:07 +08:00
|
|
|
gui_wait (Gimp *gimp,
|
|
|
|
GimpWaitable *waitable,
|
|
|
|
const gchar *message)
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
{
|
|
|
|
GimpProcedure *procedure;
|
|
|
|
GimpValueArray *args;
|
|
|
|
GimpAsync *input_async = NULL;
|
|
|
|
GError *error = NULL;
|
|
|
|
gint input_pipe[2];
|
|
|
|
gint output_pipe[2];
|
|
|
|
|
|
|
|
procedure = gimp_pdb_lookup_procedure (gimp->pdb, "plug-in-busy-dialog");
|
|
|
|
|
|
|
|
if (! procedure)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (pipe (input_pipe))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (pipe (output_pipe))
|
|
|
|
{
|
|
|
|
close (input_pipe[0]);
|
|
|
|
close (input_pipe[1]);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_spawn_set_cloexec (input_pipe[0]);
|
|
|
|
gimp_spawn_set_cloexec (output_pipe[1]);
|
|
|
|
|
|
|
|
args = gimp_procedure_get_arguments (procedure);
|
|
|
|
gimp_value_array_truncate (args, 5);
|
|
|
|
|
|
|
|
g_value_set_int (gimp_value_array_index (args, 0),
|
|
|
|
GIMP_RUN_INTERACTIVE);
|
|
|
|
g_value_set_int (gimp_value_array_index (args, 1),
|
|
|
|
output_pipe[0]);
|
|
|
|
g_value_set_int (gimp_value_array_index (args, 2),
|
|
|
|
input_pipe[1]);
|
|
|
|
g_value_set_string (gimp_value_array_index (args, 3),
|
|
|
|
message);
|
|
|
|
g_value_set_int (gimp_value_array_index (args, 4),
|
|
|
|
GIMP_IS_CANCELABLE (waitable));
|
|
|
|
|
|
|
|
gimp_procedure_execute_async (procedure, gimp,
|
|
|
|
gimp_get_user_context (gimp),
|
|
|
|
NULL, args, NULL, &error);
|
|
|
|
|
|
|
|
gimp_value_array_unref (args);
|
|
|
|
|
|
|
|
close (input_pipe[1]);
|
|
|
|
close (output_pipe[0]);
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
g_clear_error (&error);
|
|
|
|
|
|
|
|
close (input_pipe[0]);
|
|
|
|
close (output_pipe[1]);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GIMP_IS_CANCELABLE (waitable))
|
|
|
|
{
|
|
|
|
/* listens for a cancellation request */
|
|
|
|
input_async = gimp_parallel_run_async (
|
|
|
|
TRUE,
|
|
|
|
(GimpParallelRunAsyncFunc) gui_wait_input_async,
|
|
|
|
input_pipe);
|
|
|
|
|
|
|
|
while (! gimp_waitable_wait_for (waitable, 0.1 * G_TIME_SPAN_SECOND))
|
|
|
|
{
|
|
|
|
/* check for a cancellation request */
|
|
|
|
if (gimp_waitable_try_wait (GIMP_WAITABLE (input_async)))
|
|
|
|
{
|
|
|
|
gimp_cancelable_cancel (GIMP_CANCELABLE (waitable));
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_waitable_wait (waitable);
|
|
|
|
|
|
|
|
/* signal completion to the plug-in */
|
|
|
|
close (output_pipe[1]);
|
|
|
|
|
2018-05-30 04:32:07 +08:00
|
|
|
if (input_async)
|
|
|
|
{
|
|
|
|
gimp_waitable_wait (GIMP_WAITABLE (input_async));
|
|
|
|
|
|
|
|
g_object_unref (input_async);
|
|
|
|
}
|
app: add gimp_wait()
Add a GimpGui::wait() virtual function, and a corresponding
gimp_wait() function. The function takes an object implementing
the GimpWaitable interface, and a printf-style message, and waits
for the object to become ready, displaying the message as
indication in the meantime. The default implementation simply
prints the message to STDERR.
Implement the function in gui-vtable, using the busy-dialog plug-
in added in the previous commit, to display the message in a
dialog. Additionally, if the object implements the GimpCancelable
interface, provide a "cancel" button in the dialog, which, when
pressed, causes gimp_cancelable_cancel() to be called on the
object. Note that the function keeps waiting on the object even
after requesting cancelation; GimpTriviallyCancelableWaitable can
be used to stop the wait once cancelation has been requested.
2018-05-29 23:59:51 +08:00
|
|
|
|
|
|
|
close (input_pipe[0]);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2003-10-02 19:26:26 +08:00
|
|
|
static GimpProgress *
|
2006-03-24 05:56:13 +08:00
|
|
|
gui_new_progress (Gimp *gimp,
|
|
|
|
GimpObject *display)
|
2003-10-02 19:26:26 +08:00
|
|
|
{
|
2006-03-24 05:56:13 +08:00
|
|
|
g_return_val_if_fail (display == NULL || GIMP_IS_DISPLAY (display), NULL);
|
2004-08-11 17:36:51 +08:00
|
|
|
|
|
|
|
if (display)
|
|
|
|
return GIMP_PROGRESS (display);
|
|
|
|
|
2004-08-11 02:47:21 +08:00
|
|
|
return GIMP_PROGRESS (gimp_progress_dialog_new ());
|
2003-10-02 19:26:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-08-11 02:47:21 +08:00
|
|
|
gui_free_progress (Gimp *gimp,
|
|
|
|
GimpProgress *progress)
|
2003-10-02 19:26:26 +08:00
|
|
|
{
|
2004-08-11 02:47:21 +08:00
|
|
|
g_return_if_fail (GIMP_IS_PROGRESS_DIALOG (progress));
|
2003-10-02 19:26:26 +08:00
|
|
|
|
2004-08-11 17:36:51 +08:00
|
|
|
if (GIMP_IS_PROGRESS_DIALOG (progress))
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (progress));
|
2003-10-02 19:26:26 +08:00
|
|
|
}
|
|
|
|
|
2007-08-07 21:15:47 +08:00
|
|
|
static gboolean
|
|
|
|
gui_pdb_dialog_present (GtkWindow *window)
|
|
|
|
{
|
|
|
|
gtk_window_present (window);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-07-10 03:14:59 +08:00
|
|
|
static gboolean
|
|
|
|
gui_pdb_dialog_new (Gimp *gimp,
|
|
|
|
GimpContext *context,
|
2006-09-22 17:24:41 +08:00
|
|
|
GimpProgress *progress,
|
2004-07-10 03:14:59 +08:00
|
|
|
GimpContainer *container,
|
|
|
|
const gchar *title,
|
|
|
|
const gchar *callback_name,
|
|
|
|
const gchar *object_name,
|
|
|
|
va_list args)
|
|
|
|
{
|
2004-09-27 18:45:49 +08:00
|
|
|
GType dialog_type = G_TYPE_NONE;
|
|
|
|
const gchar *dialog_role = NULL;
|
|
|
|
const gchar *help_id = NULL;
|
2004-07-10 03:14:59 +08:00
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (gimp_container_get_children_type (container) == GIMP_TYPE_BRUSH)
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
dialog_type = GIMP_TYPE_BRUSH_SELECT;
|
|
|
|
dialog_role = "gimp-brush-selection";
|
|
|
|
help_id = GIMP_HELP_BRUSH_DIALOG;
|
|
|
|
}
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_FONT)
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
dialog_type = GIMP_TYPE_FONT_SELECT;
|
|
|
|
dialog_role = "gimp-font-selection";
|
|
|
|
help_id = GIMP_HELP_FONT_DIALOG;
|
|
|
|
}
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_GRADIENT)
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
dialog_type = GIMP_TYPE_GRADIENT_SELECT;
|
|
|
|
dialog_role = "gimp-gradient-selection";
|
|
|
|
help_id = GIMP_HELP_GRADIENT_DIALOG;
|
|
|
|
}
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_PALETTE)
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
dialog_type = GIMP_TYPE_PALETTE_SELECT;
|
|
|
|
dialog_role = "gimp-palette-selection";
|
|
|
|
help_id = GIMP_HELP_PALETTE_DIALOG;
|
|
|
|
}
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_PATTERN)
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
dialog_type = GIMP_TYPE_PATTERN_SELECT;
|
|
|
|
dialog_role = "gimp-pattern-selection";
|
|
|
|
help_id = GIMP_HELP_PATTERN_DIALOG;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dialog_type != G_TYPE_NONE)
|
|
|
|
{
|
|
|
|
GimpObject *object = NULL;
|
|
|
|
|
|
|
|
if (object_name && strlen (object_name))
|
|
|
|
object = gimp_container_get_child_by_name (container, object_name);
|
|
|
|
|
|
|
|
if (! object)
|
2008-11-21 07:43:58 +08:00
|
|
|
object = gimp_context_get_by_type (context,
|
|
|
|
gimp_container_get_children_type (container));
|
2004-07-10 03:14:59 +08:00
|
|
|
|
|
|
|
if (object)
|
|
|
|
{
|
2018-01-01 22:20:05 +08:00
|
|
|
gint n_properties = 0;
|
|
|
|
gchar **names = NULL;
|
|
|
|
GValue *values = NULL;
|
2004-07-11 06:25:02 +08:00
|
|
|
GtkWidget *dialog;
|
2006-06-26 16:09:23 +08:00
|
|
|
GtkWidget *view;
|
2004-07-11 06:25:02 +08:00
|
|
|
|
2018-01-01 22:20:05 +08:00
|
|
|
names = gimp_properties_append (dialog_type,
|
|
|
|
&n_properties, names, &values,
|
|
|
|
"title", title,
|
|
|
|
"role", dialog_role,
|
|
|
|
"help-func", gimp_standard_help_func,
|
|
|
|
"help-id", help_id,
|
|
|
|
"pdb", gimp->pdb,
|
|
|
|
"context", context,
|
|
|
|
"select-type", gimp_container_get_children_type (container),
|
|
|
|
"initial-object", object,
|
|
|
|
"callback-name", callback_name,
|
|
|
|
"menu-factory", global_menu_factory,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
names = gimp_properties_append_valist (dialog_type,
|
|
|
|
&n_properties, names, &values,
|
|
|
|
args);
|
|
|
|
|
|
|
|
dialog = (GtkWidget *)
|
|
|
|
g_object_new_with_properties (dialog_type,
|
|
|
|
n_properties,
|
|
|
|
(const gchar **) names,
|
|
|
|
(const GValue *) values);
|
|
|
|
|
|
|
|
gimp_properties_free (n_properties, names, values);
|
2004-07-10 03:14:59 +08:00
|
|
|
|
2006-06-26 16:09:23 +08:00
|
|
|
view = GIMP_PDB_DIALOG (dialog)->view;
|
|
|
|
if (view)
|
|
|
|
gimp_docked_set_show_button_bar (GIMP_DOCKED (view), FALSE);
|
|
|
|
|
2006-09-22 17:24:41 +08:00
|
|
|
if (progress)
|
|
|
|
{
|
2011-02-06 19:07:55 +08:00
|
|
|
guint32 window_id = gimp_progress_get_window_id (progress);
|
2006-09-22 17:24:41 +08:00
|
|
|
|
2011-02-06 19:07:55 +08:00
|
|
|
if (window_id)
|
|
|
|
gimp_window_set_transient_for (GTK_WINDOW (dialog), window_id);
|
2006-09-22 17:24:41 +08:00
|
|
|
}
|
|
|
|
|
2004-07-10 03:14:59 +08:00
|
|
|
gtk_widget_show (dialog);
|
|
|
|
|
2007-08-07 21:15:47 +08:00
|
|
|
/* workaround for bug #360106 */
|
|
|
|
{
|
2007-08-13 15:08:50 +08:00
|
|
|
GSource *source = g_timeout_source_new (100);
|
|
|
|
GClosure *closure;
|
|
|
|
|
|
|
|
closure = g_cclosure_new_object (G_CALLBACK (gui_pdb_dialog_present),
|
|
|
|
G_OBJECT (dialog));
|
2007-08-07 21:15:47 +08:00
|
|
|
|
|
|
|
g_source_set_closure (source, closure);
|
|
|
|
g_source_attach (source, NULL);
|
|
|
|
g_source_unref (source);
|
|
|
|
}
|
|
|
|
|
2004-07-10 03:14:59 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gui_pdb_dialog_set (Gimp *gimp,
|
|
|
|
GimpContainer *container,
|
|
|
|
const gchar *callback_name,
|
|
|
|
const gchar *object_name,
|
|
|
|
va_list args)
|
|
|
|
{
|
|
|
|
GimpPdbDialogClass *klass = NULL;
|
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (gimp_container_get_children_type (container) == GIMP_TYPE_BRUSH)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_BRUSH_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_FONT)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_FONT_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_GRADIENT)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_GRADIENT_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_PALETTE)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_PALETTE_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_PATTERN)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_PATTERN_SELECT);
|
|
|
|
|
|
|
|
if (klass)
|
|
|
|
{
|
|
|
|
GimpPdbDialog *dialog;
|
|
|
|
|
|
|
|
dialog = gimp_pdb_dialog_get_by_callback (klass, callback_name);
|
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (dialog && dialog->select_type == gimp_container_get_children_type (container))
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
GimpObject *object;
|
|
|
|
|
|
|
|
object = gimp_container_get_child_by_name (container, object_name);
|
|
|
|
|
|
|
|
if (object)
|
|
|
|
{
|
2005-11-24 23:33:42 +08:00
|
|
|
const gchar *prop_name = va_arg (args, const gchar *);
|
2004-07-10 03:14:59 +08:00
|
|
|
|
|
|
|
gimp_context_set_by_type (dialog->context, dialog->select_type,
|
|
|
|
object);
|
|
|
|
|
|
|
|
if (prop_name)
|
|
|
|
g_object_set_valist (G_OBJECT (dialog), prop_name, args);
|
|
|
|
|
|
|
|
gtk_window_present (GTK_WINDOW (dialog));
|
2005-11-24 23:33:42 +08:00
|
|
|
|
2004-07-10 03:14:59 +08:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gui_pdb_dialog_close (Gimp *gimp,
|
|
|
|
GimpContainer *container,
|
|
|
|
const gchar *callback_name)
|
|
|
|
{
|
|
|
|
GimpPdbDialogClass *klass = NULL;
|
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (gimp_container_get_children_type (container) == GIMP_TYPE_BRUSH)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_BRUSH_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_FONT)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_FONT_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_GRADIENT)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_GRADIENT_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_PALETTE)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_PALETTE_SELECT);
|
2008-11-21 07:43:58 +08:00
|
|
|
else if (gimp_container_get_children_type (container) == GIMP_TYPE_PATTERN)
|
2004-07-10 03:14:59 +08:00
|
|
|
klass = g_type_class_peek (GIMP_TYPE_PATTERN_SELECT);
|
|
|
|
|
|
|
|
if (klass)
|
|
|
|
{
|
|
|
|
GimpPdbDialog *dialog;
|
|
|
|
|
|
|
|
dialog = gimp_pdb_dialog_get_by_callback (klass, callback_name);
|
|
|
|
|
2008-11-21 07:43:58 +08:00
|
|
|
if (dialog && dialog->select_type == gimp_container_get_children_type (container))
|
2004-07-10 03:14:59 +08:00
|
|
|
{
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (dialog));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
|
|
|
|
static gboolean
|
2014-07-05 18:51:54 +08:00
|
|
|
gui_recent_list_add_file (Gimp *gimp,
|
|
|
|
GFile *file,
|
|
|
|
const gchar *mime_type)
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
{
|
2008-03-24 19:11:15 +08:00
|
|
|
GtkRecentData recent;
|
|
|
|
const gchar *groups[2] = { "Graphics", NULL };
|
2014-07-05 18:51:54 +08:00
|
|
|
gchar *uri;
|
|
|
|
gboolean success;
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
|
2014-07-05 18:51:54 +08:00
|
|
|
g_return_val_if_fail (G_IS_FILE (file), FALSE);
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
|
|
|
|
/* use last part of the URI */
|
|
|
|
recent.display_name = NULL;
|
2007-09-14 00:55:55 +08:00
|
|
|
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
/* no special description */
|
2007-09-14 00:55:55 +08:00
|
|
|
recent.description = NULL;
|
2007-09-21 03:28:39 +08:00
|
|
|
recent.mime_type = (mime_type ?
|
|
|
|
(gchar *) mime_type : "application/octet-stream");
|
2007-09-14 23:17:48 +08:00
|
|
|
recent.app_name = "GNU Image Manipulation Program";
|
2007-09-14 00:55:55 +08:00
|
|
|
recent.app_exec = GIMP_COMMAND " %u";
|
2007-09-21 03:28:39 +08:00
|
|
|
recent.groups = (gchar **) groups;
|
2007-09-14 00:55:55 +08:00
|
|
|
recent.is_private = FALSE;
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
|
2014-07-05 18:51:54 +08:00
|
|
|
uri = g_file_get_uri (file);
|
|
|
|
|
|
|
|
success = gtk_recent_manager_add_full (gtk_recent_manager_get_default (),
|
|
|
|
uri, &recent);
|
|
|
|
|
|
|
|
g_free (uri);
|
|
|
|
|
|
|
|
return success;
|
2008-03-24 19:11:15 +08:00
|
|
|
}
|
|
|
|
|
2008-03-25 07:08:46 +08:00
|
|
|
static gint
|
|
|
|
gui_recent_list_compare (gconstpointer a,
|
|
|
|
gconstpointer b)
|
|
|
|
{
|
|
|
|
return (gtk_recent_info_get_modified ((GtkRecentInfo *) a) -
|
|
|
|
gtk_recent_info_get_modified ((GtkRecentInfo *) b));
|
|
|
|
}
|
|
|
|
|
2008-03-24 19:11:15 +08:00
|
|
|
static void
|
|
|
|
gui_recent_list_load (Gimp *gimp)
|
|
|
|
{
|
|
|
|
GList *items;
|
|
|
|
GList *list;
|
|
|
|
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
|
|
|
|
|
|
|
gimp_container_freeze (gimp->documents);
|
|
|
|
gimp_container_clear (gimp->documents);
|
|
|
|
|
|
|
|
items = gtk_recent_manager_get_items (gtk_recent_manager_get_default ());
|
|
|
|
|
2008-03-25 07:08:46 +08:00
|
|
|
items = g_list_sort (items, gui_recent_list_compare);
|
|
|
|
|
2008-03-24 19:11:15 +08:00
|
|
|
for (list = items; list; list = list->next)
|
|
|
|
{
|
|
|
|
GtkRecentInfo *info = list->data;
|
|
|
|
|
|
|
|
if (gtk_recent_info_has_application (info,
|
|
|
|
"GNU Image Manipulation Program"))
|
|
|
|
{
|
2014-07-05 02:01:08 +08:00
|
|
|
const gchar *mime_type = gtk_recent_info_get_mime_type (info);
|
2008-03-24 19:11:15 +08:00
|
|
|
|
2014-07-05 02:01:08 +08:00
|
|
|
if (mime_type &&
|
2016-01-04 03:05:27 +08:00
|
|
|
gimp_plug_in_manager_file_procedure_find_by_mime_type (gimp->plug_in_manager,
|
|
|
|
GIMP_FILE_PROCEDURE_GROUP_OPEN,
|
|
|
|
mime_type))
|
2014-07-05 02:01:08 +08:00
|
|
|
{
|
|
|
|
GimpImagefile *imagefile;
|
2014-07-05 18:51:54 +08:00
|
|
|
GFile *file;
|
2008-03-24 19:11:15 +08:00
|
|
|
|
2014-07-05 18:51:54 +08:00
|
|
|
file = g_file_new_for_uri (gtk_recent_info_get_uri (info));
|
|
|
|
imagefile = gimp_imagefile_new (gimp, file);
|
|
|
|
g_object_unref (file);
|
2008-03-24 19:11:15 +08:00
|
|
|
|
2014-07-05 02:01:08 +08:00
|
|
|
gimp_imagefile_set_mime_type (imagefile, mime_type);
|
|
|
|
|
|
|
|
gimp_container_add (gimp->documents, GIMP_OBJECT (imagefile));
|
|
|
|
g_object_unref (imagefile);
|
|
|
|
}
|
2008-03-24 19:11:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
gtk_recent_info_unref (info);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_list_free (items);
|
|
|
|
|
|
|
|
gimp_container_thaw (gimp->documents);
|
drop own recently used files code in favour of GtkRecentManager:
* app/core/gimp-gui.c (gimp_recent_list_add_uri), app/core/gimp-gui.h,
app/gui/gui-vtable.c (gui_recent_list_add_uri): add
{gimp,gui}_recent_list_add_uri(), gui_recent_list_add_uri() dispatches to
GtkRecentManager
* app/dialogs/file-save-dialog.c (file_save_dialog_save_image),
app/actions/file-commands.c (file_save_cmd_callback),
app/widgets/gimpdnd-xds.c (gimp_dnd_xds_save_image): pass Gimp instance to
file_save() calls
* app/file/file-open.c (file_open_with_proc_and_display,
file_open_layers), app/file/file-save.c (file_save), app/file/file-save.h:
pass Gimp instance to gimp_recent_list_add_uri() calls
* app/file/gimprecentitem.c, app/file/gimprecentitem.h,
app/file/gimprecentlist.c, app/file/gimprecentlist.h: removed
* app/file/Makefile.am: drop reference to removed files
svn path=/trunk/; revision=23526
2007-09-13 22:19:30 +08:00
|
|
|
}
|
2014-07-11 04:52:29 +08:00
|
|
|
|
2014-07-23 02:29:52 +08:00
|
|
|
static GMountOperation *
|
|
|
|
gui_get_mount_operation (Gimp *gimp,
|
|
|
|
GimpProgress *progress)
|
2014-07-11 04:52:29 +08:00
|
|
|
{
|
2014-07-23 02:29:52 +08:00
|
|
|
GtkWidget *toplevel = NULL;
|
2014-07-11 04:52:29 +08:00
|
|
|
|
|
|
|
if (GTK_IS_WIDGET (progress))
|
|
|
|
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (progress));
|
|
|
|
|
2014-07-23 02:29:52 +08:00
|
|
|
return gtk_mount_operation_new (GTK_WINDOW (toplevel));
|
2014-07-11 04:52:29 +08:00
|
|
|
}
|
2015-08-23 16:51:31 +08:00
|
|
|
|
|
|
|
static GimpColorProfilePolicy
|
2016-06-06 04:36:52 +08:00
|
|
|
gui_query_profile_policy (Gimp *gimp,
|
|
|
|
GimpImage *image,
|
|
|
|
GimpContext *context,
|
|
|
|
GimpColorProfile **dest_profile,
|
|
|
|
GimpColorRenderingIntent *intent,
|
|
|
|
gboolean *bpc,
|
|
|
|
gboolean *dont_ask)
|
2015-08-23 16:51:31 +08:00
|
|
|
{
|
|
|
|
return color_profile_import_dialog_run (image, context, NULL,
|
2016-06-06 04:36:52 +08:00
|
|
|
dest_profile,
|
|
|
|
intent, bpc,
|
|
|
|
dont_ask);
|
2015-08-23 16:51:31 +08:00
|
|
|
}
|