📄 uif_selections.c
字号:
/*================================================================== * uif_selections.c - Sound font item selection management routines * * Smurf Sound Font Editor * Copyright (C) 1999-2001 Josh Green * * 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 or point your web browser to http://www.gnu.org. * * To contact the author of this program: * Email: Josh Green <jgreen@users.sourceforge.net> * Smurf homepage: http://smurf.sourceforge.net *==================================================================*/#include <stdio.h>#include <string.h>#include <gtk/gtk.h>#include "uif_selections.h"#include "uif_sfont.h"#include "uif_sftree.h"#include "glade_interface.h"#include "uif_pianospan.h"#include "wavetable.h"#include "sfundo.h"#include "sfdofunc.h"#include "smurfcfg.h"#include "util.h"#include "i18n.h"/* WARNING: Ugly code ahead, proceed with caution :) */enum { UISEL_START, UISEL_CHANGE, UISEL_REPLACE, UISEL_KEEP, UISEL_CANCEL };/* hashes to group duplicates and "remember" user choices */static GHashTable *inst_hash = NULL;static GHashTable *sample_hash = NULL;/* current item awaiting user input */static SFNodeType paste_item_type;static gpointer paste_item_data;/* dialog widget awaiting user input */GtkWidget *dup_item_dialog;/* user requested action for all items of type.. */static gint preset_all_mode;static gint inst_all_mode;static gint sample_all_mode;static GSList *uisel_clone_preset (GSList *lpset, UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_clone_inst (GSList *linst, UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_clone_sample (GSList *lsam, UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_new_preset_from_inst (SFTreeRef *dstref, SFTreeRef *srcref, UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_new_inst_from_sample (SFTreeRef *dstref, SFTreeRef *srcref, UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_paste_pzone (GtkCTreeNode *pnode, SFTreeRef *srcref, UISFont *dstuisf, UISFont *srcuisf, gint mode);static GSList *uisel_paste_izone (GtkCTreeNode *pnode, SFTreeRef *srcref, UISFont *dstuisf, UISFont *srcuisf, gint mode);static gpointer uisel_vbank_paste (GtkCTreeNode *dstnode, SFPreset *pset, SFData *srcsf);static void uisel_dup_item_dialog (gchar *lbl1, ...);static gboolean uisel_cb_dup_item_destroy (GtkWidget *dialog);static void uisel_cb_preset_change_okay (GtkWidget *cfgdialog);static void uisel_cb_inst_change_okay (GtkWidget *cfgdialog);static void uisel_cb_sample_change_okay (GtkWidget *cfgdialog);static void uisel_cb_dup_zone (gpointer data, GtkWidget *popdog);static gboolean uisel_cb_dup_zone_destroy (GtkWidget *popdog);static void uisel_cb_dialog_selection_delete_okay (gpointer data, GtkWidget *popdog);voiduisel_paste_items_start (void){ if (sftree_rclicked_itemid == SFITEMID_NONE) return; uisel_paste_items (sftree_rclicked_itemid, UISEL_START);}/* pastes appropriate selected items to a node */voiduisel_paste_items (SFItemID itemid, gint mode){ static GtkCTreeNode *dstnode; static GList *sel; static GList *selp; UISFont *dstuisf, *srcuisf; SFTreeRef *dstref, *srcref; GSList *p; gint dsttype, srctype; GtkCTreeNode *n; gpointer retp; if (mode == UISEL_START) /* start? */ { if (!(dstnode = SFTREE_LOOKUP_ITEMID (itemid))) return; sel = selp = sftree_get_selection (); inst_hash = g_hash_table_new (NULL, NULL); sample_hash = g_hash_table_new (NULL, NULL); preset_all_mode = inst_all_mode = sample_all_mode = UISEL_START; sfdo_group (_("Paste sound font items")); SFTREE_FREEZE (); } dstuisf = SFTREE_UPFIND_UISF (dstnode); dstref = SFTREE_NODE_REF (dstnode); dsttype = dstref->type; while (selp) /* loop over selection */ { /* get CTree node from item ID */ n = SFTREE_LOOKUP_ITEMID (GPOINTER_TO_INT (selp->data)); if (!n) { /* node been removed? skip */ mode = UISEL_START; selp = g_list_next (selp); continue; } srcuisf = SFTREE_UPFIND_UISF (n); srcref = SFTREE_NODE_REF (n); p = srcref->dptr; srctype = srcref->type; if (srctype == NODE_PRESET && (dsttype == NODE_SFONT || dsttype == NODE_PRESETROOT || dsttype == NODE_MELODIC || dsttype == NODE_PERCUSS)) /* clone preset */ retp = uisel_clone_preset (p, dstuisf, srcuisf, mode); else if (srctype == NODE_INST /* clone instrument */ && (dsttype == NODE_SFONT || dsttype == NODE_INSTROOT)) retp = uisel_clone_inst (p, dstuisf, srcuisf, mode); else if (srctype == NODE_SAMPLE && (dsttype == NODE_SFONT || dsttype == NODE_SAMPLEROOT || dsttype == NODE_USER || dsttype == NODE_ROM)) /* clone sample */ retp = uisel_clone_sample (p, dstuisf, srcuisf, mode); else if (dsttype == NODE_PRESET && /* paste preset zone */ (srctype == NODE_INST || srctype == NODE_PZONE)) retp = uisel_paste_pzone (dstnode, srcref, dstuisf, srcuisf, mode); else if (dsttype == NODE_INST && /* paste instrument zone */ (srctype == NODE_SAMPLE || srctype == NODE_IZONE)) retp = uisel_paste_izone (dstnode, srcref, dstuisf, srcuisf, mode); else if (srctype == NODE_INST && (dsttype == NODE_PRESETROOT || dsttype == NODE_MELODIC || dsttype == NODE_PERCUSS)) /* create preset from instrument */ retp = uisel_new_preset_from_inst (dstref, srcref, dstuisf, srcuisf, mode); else if (srctype == NODE_SAMPLE /* create instrument from sample */ && (dsttype == NODE_INSTROOT)) retp = uisel_new_inst_from_sample (dstref, srcref, dstuisf, srcuisf, mode); else if (srctype == NODE_PRESET && (dsttype == NODE_VBANK || dsttype == NODE_VBNK_MAPROOT || dsttype == NODE_VBNK_MAP)) { /* paste preset to vbank */ uisel_vbank_paste (dstnode, (SFPreset *)(p->data), srcuisf->sf); } else if (srctype == NODE_SFONT && dsttype == NODE_VBNK_DEFBANK) { UIVBank *uivb = SFTREE_UPFIND_UIVB (dstnode); gchar *s = vbank_base_fname (srcuisf->sf->fname); vbank_set_defsf (uivb->vbnk, s); g_free (s); } else retp = GINT_TO_POINTER (1); /* A non NULL value */ if (mode == UISEL_CANCEL) /* User requested Cancel? */ { sfdo_retract (); /* undo partially copied selection */ SFTREE_THAW (); g_hash_table_destroy (sample_hash); g_hash_table_destroy (inst_hash); g_list_free (sel); return; } if (!retp) return; /* only NULL if waiting for user input */ mode = UISEL_START; selp = g_list_next (selp); } sfdo_done (); SFTREE_THAW (); g_hash_table_destroy (sample_hash); g_hash_table_destroy (inst_hash); g_list_free (sel);}static GSList *uisel_clone_preset (GSList *lpset, UISFont *dstuisf, UISFont *srcuisf, gint mode){ SFZone *z; GSList *linst; GtkCTreeNode *node; static SFPreset *dup; static GSList *p; static gboolean check; static GSList *duplpset; if (mode == UISEL_START) { dup = sfont_preset_dup ((SFPreset *)(lpset->data), SFDUP_NORMAL); p = dup->zone; check = FALSE; } if (!check) { if (mode == UISEL_START || mode == UISEL_CHANGE) /* check for duplicate preset (including itself) */ if ((duplpset = sfont_find_preset (dstuisf->sf, dup->name, dup->bank, dup->prenum, NULL))) { if (preset_all_mode == UISEL_START || mode != UISEL_START) { /* if no all mode or mode not UISEL_START */ SFPreset *dup2 = (SFPreset *)(duplpset->data); gchar *s1, *s2, *s3, *s4; paste_item_type = NODE_PRESET; paste_item_data = dup; s1 = g_strdup_printf ("%d", dup->bank); s2 = g_strdup_printf ("%d", dup2->bank); s3 = g_strdup_printf ("%d", dup->prenum); s4 = g_strdup_printf ("%d", dup2->prenum); /* Duplicate preset dialog: Change, Replace, Keep, Cancel */ uisel_dup_item_dialog (_("Type"), _("Preset"), NULL, _("Name"), dup->name, dup2->name, _("Bank"), s1, s2, _("Preset"), s3, s4, _("Sound font"), sfont_get_info (srcuisf->sf, INAM_ID), sfont_get_info (dstuisf->sf, INAM_ID), _("File name"), srcuisf->sf->fname, dstuisf->sf->fname, NULL); g_free (s1); g_free (s2); g_free (s3); g_free (s4); return (NULL); /* return to wait for user input */ } else mode = preset_all_mode; /* user requested all mode */ } switch (mode) { case UISEL_REPLACE: /* Replace duplicate preset (not done yet) */ break; case UISEL_KEEP: /* Keep existing duplicate preset */ sfont_preset_destroy (dup); return (duplpset); case UISEL_CANCEL: /* Cancel paste operation */ sfont_preset_destroy (dup); return (NULL); } check = TRUE; /* flag duplicate check as done */ mode = UISEL_START; /* Reset mode */ } /* if src and dest sound font is different, copy instruments/samples too */ if (dstuisf != srcuisf) { while (p) /* loop over preset zones */ { z = (SFZone *)(p->data); linst = NULL; /* if zone has an inst then duplicate it */ if (z->instsamp) { linst = uisel_clone_inst (z->instsamp, dstuisf, srcuisf, mode); if (mode == UISEL_CANCEL) /* catch cancel request */ sfont_preset_destroy (dup); /* uisel_clone_inst is waiting for user input or canceled */ if (!linst) return (NULL); mode = UISEL_START; /* Reset mode */ } z->instsamp = linst; /* assign instrument pointer */ p = g_slist_next (p); } } /* add the duplicated preset to the destination sound font and the sftree */ sfont_add_preset (dstuisf->sf, dup); duplpset = g_slist_find (dstuisf->sf->preset, dup); node = sftree_add_preset_sorted (duplpset, dstuisf->nodes); /* tell sfundo about our new item */ dofunc_noitem_save (SFTREE_NODE_REF (node)->itemid); return (duplpset);}static GSList *uisel_clone_inst (GSList *linst, UISFont *dstuisf, UISFont *srcuisf, gint mode){ SFZone *z; GSList *lsam; GtkCTreeNode *node; static SFInst *dup; static GSList *p; static gboolean check; static GSList *duplinst; if (mode == UISEL_START) { /* check if this instrument already processed */ if ((duplinst = g_hash_table_lookup (inst_hash, linst))) return (duplinst); dup = sfont_inst_dup ((SFInst *)(linst->data), SFDUP_NORMAL); p = dup->zone; check = FALSE; } if (!check) { if (mode == UISEL_START || mode == UISEL_CHANGE) /* check for duplicate instrument (including itself) */ if ((duplinst = sfont_find_inst (dstuisf->sf, dup->name, NULL))) { if (inst_all_mode == UISEL_START || mode != UISEL_START) { /* if no all mode or mode not UISEL_START */ paste_item_type = NODE_INST; paste_item_data = dup; /* Duplicate inst dialog: Change, Replace, Keep, Cancel */ uisel_dup_item_dialog (_("Type"), _("Instrument"), NULL, _("Name"), dup->name, NULL, _("Sound font"), sfont_get_info (srcuisf->sf, INAM_ID), sfont_get_info (dstuisf->sf, INAM_ID), _("File name"), srcuisf->sf->fname, dstuisf->sf->fname, NULL); return (NULL); /* return to wait for user input */ } else mode = inst_all_mode; /* user requested all mode */ } switch (mode) { case UISEL_REPLACE: /* Replace duplicate inst (not done yet) */ break; case UISEL_KEEP: /* Keep existing duplicate inst */ /* add ptr to inst hash of the destination inst to keep, it will be used for all references to this intrument */ g_hash_table_insert (inst_hash, linst, duplinst); sfont_inst_destroy (dup); return (duplinst); case UISEL_CANCEL: /* Cancel paste operation */ sfont_inst_destroy (dup); return (NULL); } check = TRUE; /* flag duplicate check as done */ mode = UISEL_START; /* Reset mode */ } /* if src and dest sound font is different, copy samples too */ if (dstuisf != srcuisf) { while (p) { /* loop over inst zones */ z = (SFZone *)(p->data); lsam = NULL; /* if zone has a sample duplicate it */ if (z->instsamp) { lsam = uisel_clone_sample (z->instsamp, dstuisf, srcuisf, mode); if (mode == UISEL_CANCEL) /* catch cancel request */ sfont_inst_destroy (dup); /* uisel_clone_sample is waiting for user input or canceled */ if (!lsam) return (NULL); mode = UISEL_START; /* Reset mode */ } z->instsamp = lsam; /* assign sample pointer */ p = g_slist_next (p); } } /* add the duplicated inst to the destination sound font and the sftree */ sfont_add_inst (dstuisf->sf, dup); duplinst = g_slist_find (dstuisf->sf->inst, dup); node = sftree_add_inst (duplinst, dstuisf->nodes, SFTREE_NODE_APPEND);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -