~ubuntu-branches/ubuntu/trusty/anjuta/trusty

« back to all changes in this revision

Viewing changes to libanjuta/anjuta-profile-manager.c

  • Committer: Package Import Robot
  • Author(s): Steve Ovens
  • Date: 2014-01-03 21:06:06 UTC
  • mfrom: (1.1.55)
  • Revision ID: package-import@ubuntu.com-20140103210606-pmvzhu0s68qy6261
Tags: 2:3.10.2-0ubuntu1
* New upstream release (LP: #1266037)
- Updated Build-Depends of libgtk-3-dev (>= 3.6.0),
  libglib2.0-dev (>= 2.34.0)

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 * @stability: Unstable
26
26
 * @include: libanjuta/anjuta-profile-manager.h
27
27
 * 
28
 
 * Anjuta uses up to two profiles. A "no project" profile is used when no
29
 
 * project is loaded a project profile when one is loaded.
 
28
 * Anjuta uses up to three profiles. A system profile which contains mandatory
 
29
 * plugins which are never unloaded. A user profile is used when no project is
 
30
 * loaded and a project profile when one is loaded.
30
31
 * If a second project is loaded, it is loaded in another instance of Anjuta.
31
 
 * When a project is closed, Anjuta goes back to the "no project" profile.
 
32
 * When a project is closed, Anjuta goes back to the user profile.
32
33
 *
33
34
 * The profile manager can be in a frozen state where you can push or 
34
35
 * pop a profile from the stack without triggering a change of the profile.
51
52
{
52
53
        PROFILE_PUSHED,
53
54
        PROFILE_POPPED,
54
 
        PROFILE_DESCOPED,
55
 
        PROFILE_SCOPED,
56
55
        LAST_SIGNAL
57
56
};
58
57
 
72
71
static guint profile_manager_signals[LAST_SIGNAL] = { 0 };
73
72
 
74
73
static void
75
 
on_plugin_activated (AnjutaPluginManager *plugin_manager,
76
 
                                         AnjutaPluginDescription *plugin_desc,
77
 
                                         GObject *plugin_object,
78
 
                                         AnjutaProfileManager *profile_manager)
79
 
{
80
 
        AnjutaProfileManagerPriv *priv;
81
 
        priv = profile_manager->priv;
82
 
 
83
 
        if (priv->profiles)
84
 
        {
85
 
                /* Add it current profile */
86
 
                gboolean exclude;
87
 
 
88
 
                if (!anjuta_plugin_description_get_boolean (plugin_desc, "Anjuta Plugin", "ExcludeFromSession", &exclude) || !exclude)
89
 
                {
90
 
                        anjuta_profile_add_plugin (ANJUTA_PROFILE (priv->profiles->data),
91
 
                                                                           plugin_desc);
92
 
                }
93
 
        }
94
 
}
95
 
 
96
 
static void
97
 
on_plugin_deactivated (AnjutaPluginManager *plugin_manager,
98
 
                                           AnjutaPluginDescription *plugin_desc,
99
 
                                           GObject *plugin_object,
100
 
                                           AnjutaProfileManager *profile_manager)
101
 
{
102
 
        AnjutaProfileManagerPriv *priv;
103
 
        priv = profile_manager->priv;
104
 
        
105
 
        if (priv->profiles)
106
 
        {
107
 
                /* Remove from current profile */
108
 
                anjuta_profile_remove_plugin (ANJUTA_PROFILE (priv->profiles->data),
109
 
                                                                          plugin_desc);
110
 
        }
111
 
}
112
 
 
113
 
static void
114
74
anjuta_profile_manager_init (AnjutaProfileManager *object)
115
75
{
116
76
        object->priv = g_new0 (AnjutaProfileManagerPriv, 1);
144
104
        case PROP_PLUGIN_MANAGER:
145
105
                g_return_if_fail (ANJUTA_IS_PLUGIN_MANAGER (g_value_get_object (value)));
146
106
                priv->plugin_manager = g_value_get_object (value);
147
 
                g_signal_connect (priv->plugin_manager, "plugin-activated",
148
 
                                                  G_CALLBACK (on_plugin_activated), object);
149
 
                g_signal_connect (priv->plugin_manager, "plugin-deactivated",
150
 
                                                  G_CALLBACK (on_plugin_deactivated), object);
151
107
                break;
152
108
        default:
153
109
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
236
192
                              G_TYPE_NONE, 1,
237
193
                              ANJUTA_TYPE_PROFILE);
238
194
        
239
 
        /**
240
 
         * AnjutaProfileManager::profile-descoped:
241
 
         * @profile_manager: a #AnjutaProfileManager object.
242
 
         * @profile: the old unloaded #AnjutaProfile.
243
 
         * 
244
 
         * Emitted when a profile will be unloaded.
245
 
         */
246
 
        profile_manager_signals[PROFILE_DESCOPED] =
247
 
                g_signal_new ("profile-descoped",
248
 
                              G_OBJECT_CLASS_TYPE (klass),
249
 
                              G_SIGNAL_RUN_FIRST,
250
 
                              G_STRUCT_OFFSET (AnjutaProfileManagerClass,
251
 
                                                                           profile_descoped),
252
 
                              NULL, NULL,
253
 
                                          anjuta_cclosure_marshal_VOID__OBJECT,
254
 
                              G_TYPE_NONE, 1,
255
 
                              ANJUTA_TYPE_PROFILE);
256
 
        
257
 
        /**
258
 
         * AnjutaProfileManager::profile-scoped:
259
 
         * @profile_manager: a #AnjutaProfileManager object.
260
 
         * @profile: the current loaded #AnjutaProfile.
261
 
         * 
262
 
         * Emitted when a new profile is loaded.
263
 
         */
264
 
        profile_manager_signals[PROFILE_SCOPED] =
265
 
                g_signal_new ("profile-scoped",
266
 
                              G_OBJECT_CLASS_TYPE (klass),
267
 
                              G_SIGNAL_RUN_FIRST,
268
 
                              G_STRUCT_OFFSET (AnjutaProfileManagerClass,
269
 
                                                                           profile_scoped),
270
 
                              NULL, NULL,
271
 
                                          anjuta_cclosure_marshal_VOID__OBJECT,
272
 
                              G_TYPE_NONE, 1,
273
 
                              ANJUTA_TYPE_PROFILE);
274
195
}
275
196
 
276
197
GType
320
241
}
321
242
 
322
243
static gboolean
323
 
anjuta_profile_manager_load_profile (AnjutaProfileManager *profile_manager,
324
 
                                                                         AnjutaProfile *profile,
325
 
                                                                         AnjutaProfile *previous_profile,
326
 
                                                                         GError **error)
 
244
anjuta_profile_manager_load_profiles (AnjutaProfileManager *profile_manager, GError **error)
327
245
{
328
246
        AnjutaProfileManagerPriv *priv;
329
 
        GList *active_plugins, *node;
330
 
        GList *plugins_to_activate, *plugins_to_deactivate;
331
 
        GList *selected_plugins;
332
 
                
333
 
        GHashTable *active_plugins_hash, *plugins_to_activate_hash;
334
 
        
 
247
        gboolean loaded = FALSE;
 
248
 
335
249
        priv = profile_manager->priv;
336
 
        
337
 
        /* Disable profile synchronization while the profile is being activated */
338
 
        g_signal_handlers_block_by_func (priv->plugin_manager,
339
 
                                                                         G_CALLBACK (on_plugin_activated),
340
 
                                                                         profile_manager);
341
 
        g_signal_handlers_block_by_func (priv->plugin_manager,
342
 
                                                                         G_CALLBACK (on_plugin_deactivated),
343
 
                                                                         profile_manager);
344
 
        
345
 
        /* Emit pre-change for the last profile */
346
 
        if (previous_profile)
347
 
        {
348
 
                g_signal_emit_by_name (profile_manager, "profile-descoped",
349
 
                                                           previous_profile);
350
 
        }
351
 
        
352
 
        /* Prepare plugins to activate */
353
 
        plugins_to_activate_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
354
 
        
355
 
        /* Select plugins in the profile */
356
 
        if (profile)
357
 
                selected_plugins = anjuta_profile_get_plugins (profile);
358
 
        else
359
 
                selected_plugins = NULL;
360
 
        
361
 
        node = selected_plugins;
362
 
        while (node)
363
 
        {
364
 
                g_hash_table_insert (plugins_to_activate_hash, node->data, node->data);
365
 
                node = g_list_next (node);
366
 
        }
367
 
        
368
 
        /* Prepare active plugins hash */
369
 
        active_plugins =
370
 
                anjuta_plugin_manager_get_active_plugins (priv->plugin_manager);
371
 
        active_plugins_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
372
 
        node = active_plugins;
373
 
        while (node)
374
 
        {
375
 
                g_hash_table_insert (active_plugins_hash, node->data, node->data);
376
 
                node = g_list_next (node);
377
 
        }
378
 
        
379
 
        plugins_to_deactivate = NULL;
380
 
        
381
 
        /* Prepare plugins to deactiveate that are already active, but are
382
 
         * not requested to be active
383
 
         */
384
 
        node = active_plugins;
385
 
        while (node)
386
 
        {
387
 
                if (!g_hash_table_lookup (plugins_to_activate_hash, node->data))
388
 
                {
389
 
                        plugins_to_deactivate = g_list_prepend (plugins_to_deactivate,
390
 
                                                                                                        node->data);
391
 
                }
392
 
                node = g_list_next (node);
393
 
        }
394
 
        plugins_to_deactivate = g_list_reverse (plugins_to_deactivate);
395
 
 
396
 
        /* Deactivate plugins */
397
 
        node = plugins_to_deactivate;
398
 
        while (node)
399
 
        {
400
 
                AnjutaPluginDescription *desc;
401
 
                gchar *plugin_id = NULL;
402
 
                
403
 
                desc = (AnjutaPluginDescription *)node->data;
404
 
                anjuta_plugin_description_get_string (desc, "Anjuta Plugin",
405
 
                                                                                          "Location", &plugin_id);
406
 
                g_assert (plugin_id != NULL);
407
 
                
408
 
                /* DEBUG_PRINT ("Profile: deactivating %s", plugin_id); */
409
 
                
410
 
                anjuta_plugin_manager_unload_plugin_by_id (priv->plugin_manager,
411
 
                                                           plugin_id);
412
 
                node = g_list_next (node);
413
 
        }
414
 
        
415
 
        /* Prepare the plugins to activate */
416
 
        plugins_to_activate = NULL;
417
 
        node = selected_plugins;
418
 
        while (node)
419
 
        {
420
 
                if (!g_hash_table_lookup (active_plugins_hash, node->data))
421
 
                        plugins_to_activate = g_list_prepend (plugins_to_activate,
422
 
                                                                                                   node->data);
423
 
                node = g_list_next (node);
424
 
        }
425
 
        
426
 
        /* Now activate the plugins */
427
 
        if (plugins_to_activate)
428
 
        {
429
 
                /* Activate them */
430
 
                plugins_to_activate = g_list_reverse (plugins_to_activate);
431
 
                anjuta_plugin_manager_activate_plugins (priv->plugin_manager,
432
 
                                                                                                plugins_to_activate);
433
 
        }
434
 
        
435
 
        g_list_free (plugins_to_activate);
436
 
        g_list_free (active_plugins);
437
 
        
438
 
        g_hash_table_destroy (plugins_to_activate_hash);
439
 
        g_hash_table_destroy (active_plugins_hash);
440
 
 
441
 
        /* Enable profile synchronization */
442
 
        g_signal_handlers_unblock_by_func (priv->plugin_manager,
443
 
                                                                           G_CALLBACK (on_plugin_activated),
444
 
                                                                           profile_manager);
445
 
        g_signal_handlers_unblock_by_func (priv->plugin_manager,
446
 
                                                                           G_CALLBACK (on_plugin_deactivated),
447
 
                                                                           profile_manager);
448
 
        g_signal_emit_by_name (profile_manager, "profile-scoped", profile);
449
 
        return TRUE;
 
250
 
 
251
        /* If there is no freeze load profile now */
 
252
        while ((priv->freeze_count <= 0) && (priv->profiles_queue != NULL))
 
253
        {
 
254
                AnjutaProfile *previous_profile = NULL;
 
255
                GList *node;
 
256
 
 
257
                /* We need to load each profile one by one because a "system" profile
 
258
                 * contains plugins which are never unloaded. */
 
259
                if (priv->profiles)
 
260
                        previous_profile = priv->profiles->data;
 
261
                node = g_list_last (priv->profiles_queue);
 
262
                priv->profiles_queue = g_list_remove_link (priv->profiles_queue, node);
 
263
                priv->profiles = g_list_concat (node, priv->profiles);
 
264
 
 
265
                /* Load profile. Note that loading a profile can trigger the load of
 
266
                 * additional profile. Typically loading the default profile will
 
267
                 * trigger the load of the last project profile. */
 
268
                if (previous_profile != NULL) anjuta_profile_unload (previous_profile, NULL);
 
269
                loaded = anjuta_profile_load (ANJUTA_PROFILE (node->data), error);
 
270
        }
 
271
 
 
272
        return loaded;
450
273
}
451
274
 
452
275
static gboolean
457
280
        AnjutaProfileManagerPriv *priv;
458
281
        
459
282
        priv = profile_manager->priv;
460
 
        priv->profiles_queue = g_list_prepend (priv->profiles_queue,
461
 
                                                                                        profile);
 
283
 
 
284
        priv->profiles_queue = g_list_prepend (priv->profiles_queue, profile);
 
285
 
462
286
        /* If there is no freeze load profile now */
463
 
        if (priv->freeze_count <= 0)
464
 
        {
465
 
                AnjutaProfile *previous_profile = NULL;
466
 
                
467
 
                if (priv->profiles)
468
 
                        previous_profile = priv->profiles->data;
469
 
                
470
 
                /* Push queued profiles in stack */
471
 
                priv->profiles = g_list_concat (priv->profiles_queue, priv->profiles);
472
 
                priv->profiles_queue = NULL;
473
 
                
474
 
                return anjuta_profile_manager_load_profile (profile_manager,
475
 
                                                                                ANJUTA_PROFILE (priv->profiles->data),
476
 
                                                                                                        previous_profile,
477
 
                                                                                                        error);
478
 
        }
479
 
        else
480
 
        {
481
 
                return FALSE;
482
 
        }
 
287
        return anjuta_profile_manager_load_profiles (profile_manager, error);
483
288
}
484
289
 
485
290
/**
492
297
 * manager is not frozen, this new profile will be loaded immediatly and
493
298
 * become the current profile.
494
299
 *
495
 
 * Return value: TRUE on success, FALSE otherwise.
 
300
 * Return value: %TRUE on success, %FALSE otherwise.
496
301
 */
497
302
gboolean
498
303
anjuta_profile_manager_push (AnjutaProfileManager *profile_manager,
511
316
/**
512
317
 * anjuta_profile_manager_pop:
513
318
 * @profile_manager: the #AnjutaProfileManager object.
514
 
 * @profile_name: the name of the profile to remove.
 
319
 * @profile: the #AnjutaProfile to remove.
515
320
 * @error: error propagation and reporting.
516
321
 * 
517
322
 * Remove a profile from the profile manager stack. If the manager is not
520
325
 * If the manager is frozen, the current profile or the last pushed profile
521
326
 * can be removed.
522
327
 *
523
 
 * Return value: TRUE on success, FALSE otherwise.
 
328
 * Return value: %TRUE on success, %FALSE otherwise.
524
329
 */
525
330
gboolean
526
331
anjuta_profile_manager_pop (AnjutaProfileManager *profile_manager,
527
 
                                                        const gchar *profile_name, GError **error)
 
332
                                                        AnjutaProfile *profile, GError **error)
528
333
{
529
334
        AnjutaProfileManagerPriv *priv;
530
 
        AnjutaProfile *profile;
531
335
 
532
336
        g_return_val_if_fail (ANJUTA_IS_PROFILE_MANAGER (profile_manager), FALSE);
533
337
        priv = profile_manager->priv;
535
339
        /* First check in the queue */
536
340
        if (priv->profiles_queue)
537
341
        {
538
 
                profile = priv->profiles_queue->data;
539
 
                g_return_val_if_fail (strcmp (anjuta_profile_get_name (profile),
540
 
                                                                          profile_name) == 0, FALSE);
 
342
                g_return_val_if_fail (priv->profiles_queue->data == profile, FALSE);
541
343
                priv->profiles_queue = g_list_remove (priv->profiles_queue, profile);
542
344
                
543
345
                g_signal_emit_by_name (profile_manager, "profile-popped",
550
352
        /* Then check in the current stack */
551
353
        if (priv->profiles)
552
354
        {
553
 
                profile = priv->profiles->data;
554
 
                g_return_val_if_fail (strcmp (anjuta_profile_get_name (profile),
555
 
                                                                          profile_name) == 0, FALSE);
 
355
                g_return_val_if_fail (priv->profiles->data == profile, FALSE);
556
356
                priv->profiles = g_list_remove (priv->profiles, profile);
557
357
                
558
358
                g_signal_emit_by_name (profile_manager, "profile-popped",
559
359
                                                           profile);
560
360
                
561
361
                /* Restore the next profile in the stack */
 
362
                anjuta_profile_unload (profile, NULL);
 
363
                g_object_unref (profile);
562
364
                if (priv->profiles)
563
365
                {
564
 
                        return anjuta_profile_manager_load_profile (profile_manager,
565
 
                                                                        ANJUTA_PROFILE (priv->profiles->data),
566
 
                                                                                                                profile,
567
 
                                                                                                                error);
568
 
                }
569
 
                else
570
 
                {
571
 
                        return anjuta_profile_manager_load_profile (profile_manager,
572
 
                                                                                                                NULL, profile,
573
 
                                                                                                                error);
574
 
                }
575
 
                g_object_unref (profile);
 
366
                        return anjuta_profile_load (ANJUTA_PROFILE (priv->profiles->data), error);
 
367
                }
 
368
                return TRUE;
576
369
        }
577
370
 
578
371
        return FALSE;
606
399
 * anjuta_profile_manager_freeze(). It will load a new profile if one has been
607
400
 * added while the manager was frozen.
608
401
 *
609
 
 * Return value: TRUE on success, FALSE otherwise.
 
402
 * Return value: %TRUE on success, %FALSE otherwise.
610
403
 */
611
404
gboolean
612
405
anjuta_profile_manager_thaw (AnjutaProfileManager *profile_manager,
619
412
 
620
413
        if (priv->freeze_count > 0)
621
414
                priv->freeze_count--;
622
 
        
623
 
        if (priv->freeze_count <= 0 && priv->profiles_queue)
624
 
        {
625
 
                AnjutaProfile *previous_profile = NULL;
626
 
                
627
 
                if (priv->profiles)
628
 
                        previous_profile = priv->profiles->data;
629
 
                
630
 
                /* Push queued profiles in stack */
631
 
                priv->profiles = g_list_concat (priv->profiles_queue, priv->profiles);
632
 
                priv->profiles_queue = NULL;
633
 
                
634
 
                /* Load the profile */
635
 
                return anjuta_profile_manager_load_profile (profile_manager,
636
 
                                                                                ANJUTA_PROFILE (priv->profiles->data),
637
 
                                                                                                        previous_profile,
638
 
                                                                                                        error);
639
 
        }
640
 
        else
641
 
        {
642
 
                return FALSE;
643
 
        }
 
415
 
 
416
        return anjuta_profile_manager_load_profiles (profile_manager, error);
644
417
}
645
418
 
646
419
/**
649
422
 * 
650
423
 * Return the current profile.
651
424
 *
652
 
 * Return value: a #AnjutaProfile object or NULL if the profile stack is empty.
 
425
 * Return value: (transfer none) (allow-none): a #AnjutaProfile object or %NULL
 
426
 * if the profile stack is empty.
653
427
 */
654
428
AnjutaProfile*
655
429
anjuta_profile_manager_get_current (AnjutaProfileManager *profile_manager)
668
442
 * anjuta_profile_manager_close:
669
443
 * @profile_manager: A #AnjutaProfileManager object.
670
444
 *
671
 
 * Close the #AnjutaProfileManager causing "profile-descoped" to be emitted and
 
445
 * Close the #AnjutaProfileManager causing "descoped" to be emitted and
672
446
 * all queued and previous profiles to be released. This function is to be used
673
447
 * when destroying an Anjuta instance.
674
448
 */
681
455
 
682
456
        priv = profile_manager->priv;
683
457
 
684
 
        g_signal_handlers_disconnect_by_func (priv->plugin_manager,
685
 
                                              on_plugin_activated, profile_manager);
686
 
        g_signal_handlers_disconnect_by_func (priv->plugin_manager,
687
 
                                              on_plugin_deactivated, profile_manager);
688
 
 
689
458
        if (priv->profiles)
690
459
        {
691
460
                AnjutaProfile *profile = ANJUTA_PROFILE (priv->profiles->data);
692
461
 
693
 
                /* Emit "profile-descoped" so that other parts of anjuta can store
 
462
                /* Emit "descoped" so that other parts of anjuta can store
694
463
                 * information about the currently loaded profile. */
695
 
                g_signal_emit_by_name (profile_manager, "profile-descoped",
696
 
                                       profile);
 
464
                anjuta_profile_unload (profile, NULL);
697
465
 
698
466
                g_list_free_full (priv->profiles, g_object_unref);
699
467
                priv->profiles = NULL;