1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gio.MountT; 26 27 public import gio.AsyncResultIF; 28 public import gio.Cancellable; 29 public import gio.Drive; 30 public import gio.DriveIF; 31 public import gio.File; 32 public import gio.FileIF; 33 public import gio.Icon; 34 public import gio.IconIF; 35 public import gio.MountOperation; 36 public import gio.Volume; 37 public import gio.VolumeIF; 38 public import glib.ErrorG; 39 public import glib.GException; 40 public import glib.Str; 41 public import gobject.ObjectG; 42 public import gobject.Signals; 43 public import gtkc.gio; 44 public import gtkc.giotypes; 45 public import std.algorithm; 46 47 48 /** 49 * The #GMount interface represents user-visible mounts. Note, when 50 * porting from GnomeVFS, #GMount is the moral equivalent of #GnomeVFSVolume. 51 * 52 * #GMount is a "mounted" filesystem that you can access. Mounted is in 53 * quotes because it's not the same as a unix mount, it might be a gvfs 54 * mount, but you can still access the files on it if you use GIO. Might or 55 * might not be related to a volume object. 56 * 57 * Unmounting a #GMount instance is an asynchronous operation. For 58 * more information about asynchronous operations, see #GAsyncResult 59 * and #GTask. To unmount a #GMount instance, first call 60 * g_mount_unmount_with_operation() with (at least) the #GMount instance and a 61 * #GAsyncReadyCallback. The callback will be fired when the 62 * operation has resolved (either with success or failure), and a 63 * #GAsyncReady structure will be passed to the callback. That 64 * callback should then call g_mount_unmount_with_operation_finish() with the #GMount 65 * and the #GAsyncReady data to see if the operation was completed 66 * successfully. If an @error is present when g_mount_unmount_with_operation_finish() 67 * is called, then it will be filled with any error information. 68 */ 69 public template MountT(TStruct) 70 { 71 /** Get the main Gtk struct */ 72 public GMount* getMountStruct(bool transferOwnership = false) 73 { 74 if (transferOwnership) 75 ownedRef = false; 76 return cast(GMount*)getStruct(); 77 } 78 79 80 /** 81 * Checks if @mount can be eject. 82 * 83 * Returns: %TRUE if the @mount can be ejected. 84 */ 85 public bool canEject() 86 { 87 return g_mount_can_eject(getMountStruct()) != 0; 88 } 89 90 /** 91 * Checks if @mount can be mounted. 92 * 93 * Returns: %TRUE if the @mount can be unmounted. 94 */ 95 public bool canUnmount() 96 { 97 return g_mount_can_unmount(getMountStruct()) != 0; 98 } 99 100 /** 101 * Ejects a mount. This is an asynchronous operation, and is 102 * finished by calling g_mount_eject_finish() with the @mount 103 * and #GAsyncResult data returned in the @callback. 104 * 105 * Deprecated: Use g_mount_eject_with_operation() instead. 106 * 107 * Params: 108 * flags = flags affecting the unmount if required for eject 109 * cancellable = optional #GCancellable object, %NULL to ignore. 110 * callback = a #GAsyncReadyCallback, or %NULL. 111 * userData = user data passed to @callback. 112 */ 113 public void eject(GMountUnmountFlags flags, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 114 { 115 g_mount_eject(getMountStruct(), flags, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 116 } 117 118 /** 119 * Finishes ejecting a mount. If any errors occurred during the operation, 120 * @error will be set to contain the errors and %FALSE will be returned. 121 * 122 * Deprecated: Use g_mount_eject_with_operation_finish() instead. 123 * 124 * Params: 125 * result = a #GAsyncResult. 126 * 127 * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise. 128 * 129 * Throws: GException on failure. 130 */ 131 public bool ejectFinish(AsyncResultIF result) 132 { 133 GError* err = null; 134 135 auto p = g_mount_eject_finish(getMountStruct(), (result is null) ? null : result.getAsyncResultStruct(), &err) != 0; 136 137 if (err !is null) 138 { 139 throw new GException( new ErrorG(err) ); 140 } 141 142 return p; 143 } 144 145 /** 146 * Ejects a mount. This is an asynchronous operation, and is 147 * finished by calling g_mount_eject_with_operation_finish() with the @mount 148 * and #GAsyncResult data returned in the @callback. 149 * 150 * Params: 151 * flags = flags affecting the unmount if required for eject 152 * mountOperation = a #GMountOperation or %NULL to avoid 153 * user interaction. 154 * cancellable = optional #GCancellable object, %NULL to ignore. 155 * callback = a #GAsyncReadyCallback, or %NULL. 156 * userData = user data passed to @callback. 157 * 158 * Since: 2.22 159 */ 160 public void ejectWithOperation(GMountUnmountFlags flags, MountOperation mountOperation, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 161 { 162 g_mount_eject_with_operation(getMountStruct(), flags, (mountOperation is null) ? null : mountOperation.getMountOperationStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 163 } 164 165 /** 166 * Finishes ejecting a mount. If any errors occurred during the operation, 167 * @error will be set to contain the errors and %FALSE will be returned. 168 * 169 * Params: 170 * result = a #GAsyncResult. 171 * 172 * Returns: %TRUE if the mount was successfully ejected. %FALSE otherwise. 173 * 174 * Since: 2.22 175 * 176 * Throws: GException on failure. 177 */ 178 public bool ejectWithOperationFinish(AsyncResultIF result) 179 { 180 GError* err = null; 181 182 auto p = g_mount_eject_with_operation_finish(getMountStruct(), (result is null) ? null : result.getAsyncResultStruct(), &err) != 0; 183 184 if (err !is null) 185 { 186 throw new GException( new ErrorG(err) ); 187 } 188 189 return p; 190 } 191 192 /** 193 * Gets the default location of @mount. The default location of the given 194 * @mount is a path that reflects the main entry point for the user (e.g. 195 * the home directory, or the root of the volume). 196 * 197 * Returns: a #GFile. 198 * The returned object should be unreffed with 199 * g_object_unref() when no longer needed. 200 */ 201 public FileIF getDefaultLocation() 202 { 203 auto p = g_mount_get_default_location(getMountStruct()); 204 205 if(p is null) 206 { 207 return null; 208 } 209 210 return ObjectG.getDObject!(File, FileIF)(cast(GFile*) p, true); 211 } 212 213 /** 214 * Gets the drive for the @mount. 215 * 216 * This is a convenience method for getting the #GVolume and then 217 * using that object to get the #GDrive. 218 * 219 * Returns: a #GDrive or %NULL if @mount is not associated with a volume or a drive. 220 * The returned object should be unreffed with 221 * g_object_unref() when no longer needed. 222 */ 223 public DriveIF getDrive() 224 { 225 auto p = g_mount_get_drive(getMountStruct()); 226 227 if(p is null) 228 { 229 return null; 230 } 231 232 return ObjectG.getDObject!(Drive, DriveIF)(cast(GDrive*) p, true); 233 } 234 235 /** 236 * Gets the icon for @mount. 237 * 238 * Returns: a #GIcon. 239 * The returned object should be unreffed with 240 * g_object_unref() when no longer needed. 241 */ 242 public IconIF getIcon() 243 { 244 auto p = g_mount_get_icon(getMountStruct()); 245 246 if(p is null) 247 { 248 return null; 249 } 250 251 return ObjectG.getDObject!(Icon, IconIF)(cast(GIcon*) p, true); 252 } 253 254 /** 255 * Gets the name of @mount. 256 * 257 * Returns: the name for the given @mount. 258 * The returned string should be freed with g_free() 259 * when no longer needed. 260 */ 261 public string getName() 262 { 263 auto retStr = g_mount_get_name(getMountStruct()); 264 265 scope(exit) Str.freeString(retStr); 266 return Str.toString(retStr); 267 } 268 269 /** 270 * Gets the root directory on @mount. 271 * 272 * Returns: a #GFile. 273 * The returned object should be unreffed with 274 * g_object_unref() when no longer needed. 275 */ 276 public FileIF getRoot() 277 { 278 auto p = g_mount_get_root(getMountStruct()); 279 280 if(p is null) 281 { 282 return null; 283 } 284 285 return ObjectG.getDObject!(File, FileIF)(cast(GFile*) p, true); 286 } 287 288 /** 289 * Gets the sort key for @mount, if any. 290 * 291 * Returns: Sorting key for @mount or %NULL if no such key is available. 292 * 293 * Since: 2.32 294 */ 295 public string getSortKey() 296 { 297 return Str.toString(g_mount_get_sort_key(getMountStruct())); 298 } 299 300 /** 301 * Gets the symbolic icon for @mount. 302 * 303 * Returns: a #GIcon. 304 * The returned object should be unreffed with 305 * g_object_unref() when no longer needed. 306 * 307 * Since: 2.34 308 */ 309 public IconIF getSymbolicIcon() 310 { 311 auto p = g_mount_get_symbolic_icon(getMountStruct()); 312 313 if(p is null) 314 { 315 return null; 316 } 317 318 return ObjectG.getDObject!(Icon, IconIF)(cast(GIcon*) p, true); 319 } 320 321 /** 322 * Gets the UUID for the @mount. The reference is typically based on 323 * the file system UUID for the mount in question and should be 324 * considered an opaque string. Returns %NULL if there is no UUID 325 * available. 326 * 327 * Returns: the UUID for @mount or %NULL if no UUID can be computed. 328 * The returned string should be freed with g_free() 329 * when no longer needed. 330 */ 331 public string getUuid() 332 { 333 auto retStr = g_mount_get_uuid(getMountStruct()); 334 335 scope(exit) Str.freeString(retStr); 336 return Str.toString(retStr); 337 } 338 339 /** 340 * Gets the volume for the @mount. 341 * 342 * Returns: a #GVolume or %NULL if @mount is not associated with a volume. 343 * The returned object should be unreffed with 344 * g_object_unref() when no longer needed. 345 */ 346 public VolumeIF getVolume() 347 { 348 auto p = g_mount_get_volume(getMountStruct()); 349 350 if(p is null) 351 { 352 return null; 353 } 354 355 return ObjectG.getDObject!(Volume, VolumeIF)(cast(GVolume*) p, true); 356 } 357 358 /** 359 * Tries to guess the type of content stored on @mount. Returns one or 360 * more textual identifiers of well-known content types (typically 361 * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 362 * memory cards. See the 363 * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec) 364 * specification for more on x-content types. 365 * 366 * This is an asynchronous operation (see 367 * g_mount_guess_content_type_sync() for the synchronous version), and 368 * is finished by calling g_mount_guess_content_type_finish() with the 369 * @mount and #GAsyncResult data returned in the @callback. 370 * 371 * Params: 372 * forceRescan = Whether to force a rescan of the content. 373 * Otherwise a cached result will be used if available 374 * cancellable = optional #GCancellable object, %NULL to ignore 375 * callback = a #GAsyncReadyCallback 376 * userData = user data passed to @callback 377 * 378 * Since: 2.18 379 */ 380 public void guessContentType(bool forceRescan, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 381 { 382 g_mount_guess_content_type(getMountStruct(), forceRescan, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 383 } 384 385 /** 386 * Finishes guessing content types of @mount. If any errors occurred 387 * during the operation, @error will be set to contain the errors and 388 * %FALSE will be returned. In particular, you may get an 389 * %G_IO_ERROR_NOT_SUPPORTED if the mount does not support content 390 * guessing. 391 * 392 * Params: 393 * result = a #GAsyncResult 394 * 395 * Returns: a %NULL-terminated array of content types or %NULL on error. 396 * Caller should free this array with g_strfreev() when done with it. 397 * 398 * Since: 2.18 399 * 400 * Throws: GException on failure. 401 */ 402 public string[] guessContentTypeFinish(AsyncResultIF result) 403 { 404 GError* err = null; 405 406 auto retStr = g_mount_guess_content_type_finish(getMountStruct(), (result is null) ? null : result.getAsyncResultStruct(), &err); 407 408 if (err !is null) 409 { 410 throw new GException( new ErrorG(err) ); 411 } 412 413 scope(exit) Str.freeStringArray(retStr); 414 return Str.toStringArray(retStr); 415 } 416 417 /** 418 * Tries to guess the type of content stored on @mount. Returns one or 419 * more textual identifiers of well-known content types (typically 420 * prefixed with "x-content/"), e.g. x-content/image-dcf for camera 421 * memory cards. See the 422 * [shared-mime-info](http://www.freedesktop.org/wiki/Specifications/shared-mime-info-spec) 423 * specification for more on x-content types. 424 * 425 * This is an synchronous operation and as such may block doing IO; 426 * see g_mount_guess_content_type() for the asynchronous version. 427 * 428 * Params: 429 * forceRescan = Whether to force a rescan of the content. 430 * Otherwise a cached result will be used if available 431 * cancellable = optional #GCancellable object, %NULL to ignore 432 * 433 * Returns: a %NULL-terminated array of content types or %NULL on error. 434 * Caller should free this array with g_strfreev() when done with it. 435 * 436 * Since: 2.18 437 * 438 * Throws: GException on failure. 439 */ 440 public string[] guessContentTypeSync(bool forceRescan, Cancellable cancellable) 441 { 442 GError* err = null; 443 444 auto retStr = g_mount_guess_content_type_sync(getMountStruct(), forceRescan, (cancellable is null) ? null : cancellable.getCancellableStruct(), &err); 445 446 if (err !is null) 447 { 448 throw new GException( new ErrorG(err) ); 449 } 450 451 scope(exit) Str.freeStringArray(retStr); 452 return Str.toStringArray(retStr); 453 } 454 455 /** 456 * Determines if @mount is shadowed. Applications or libraries should 457 * avoid displaying @mount in the user interface if it is shadowed. 458 * 459 * A mount is said to be shadowed if there exists one or more user 460 * visible objects (currently #GMount objects) with a root that is 461 * inside the root of @mount. 462 * 463 * One application of shadow mounts is when exposing a single file 464 * system that is used to address several logical volumes. In this 465 * situation, a #GVolumeMonitor implementation would create two 466 * #GVolume objects (for example, one for the camera functionality of 467 * the device and one for a SD card reader on the device) with 468 * activation URIs `gphoto2://[usb:001,002]/store1/` 469 * and `gphoto2://[usb:001,002]/store2/`. When the 470 * underlying mount (with root 471 * `gphoto2://[usb:001,002]/`) is mounted, said 472 * #GVolumeMonitor implementation would create two #GMount objects 473 * (each with their root matching the corresponding volume activation 474 * root) that would shadow the original mount. 475 * 476 * The proxy monitor in GVfs 2.26 and later, automatically creates and 477 * manage shadow mounts (and shadows the underlying mount) if the 478 * activation root on a #GVolume is set. 479 * 480 * Returns: %TRUE if @mount is shadowed. 481 * 482 * Since: 2.20 483 */ 484 public bool isShadowed() 485 { 486 return g_mount_is_shadowed(getMountStruct()) != 0; 487 } 488 489 /** 490 * Remounts a mount. This is an asynchronous operation, and is 491 * finished by calling g_mount_remount_finish() with the @mount 492 * and #GAsyncResults data returned in the @callback. 493 * 494 * Remounting is useful when some setting affecting the operation 495 * of the volume has been changed, as these may need a remount to 496 * take affect. While this is semantically equivalent with unmounting 497 * and then remounting not all backends might need to actually be 498 * unmounted. 499 * 500 * Params: 501 * flags = flags affecting the operation 502 * mountOperation = a #GMountOperation or %NULL to avoid 503 * user interaction. 504 * cancellable = optional #GCancellable object, %NULL to ignore. 505 * callback = a #GAsyncReadyCallback, or %NULL. 506 * userData = user data passed to @callback. 507 */ 508 public void remount(GMountMountFlags flags, MountOperation mountOperation, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 509 { 510 g_mount_remount(getMountStruct(), flags, (mountOperation is null) ? null : mountOperation.getMountOperationStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 511 } 512 513 /** 514 * Finishes remounting a mount. If any errors occurred during the operation, 515 * @error will be set to contain the errors and %FALSE will be returned. 516 * 517 * Params: 518 * result = a #GAsyncResult. 519 * 520 * Returns: %TRUE if the mount was successfully remounted. %FALSE otherwise. 521 * 522 * Throws: GException on failure. 523 */ 524 public bool remountFinish(AsyncResultIF result) 525 { 526 GError* err = null; 527 528 auto p = g_mount_remount_finish(getMountStruct(), (result is null) ? null : result.getAsyncResultStruct(), &err) != 0; 529 530 if (err !is null) 531 { 532 throw new GException( new ErrorG(err) ); 533 } 534 535 return p; 536 } 537 538 /** 539 * Increments the shadow count on @mount. Usually used by 540 * #GVolumeMonitor implementations when creating a shadow mount for 541 * @mount, see g_mount_is_shadowed() for more information. The caller 542 * will need to emit the #GMount::changed signal on @mount manually. 543 * 544 * Since: 2.20 545 */ 546 public void shadow() 547 { 548 g_mount_shadow(getMountStruct()); 549 } 550 551 /** 552 * Unmounts a mount. This is an asynchronous operation, and is 553 * finished by calling g_mount_unmount_finish() with the @mount 554 * and #GAsyncResult data returned in the @callback. 555 * 556 * Deprecated: Use g_mount_unmount_with_operation() instead. 557 * 558 * Params: 559 * flags = flags affecting the operation 560 * cancellable = optional #GCancellable object, %NULL to ignore. 561 * callback = a #GAsyncReadyCallback, or %NULL. 562 * userData = user data passed to @callback. 563 */ 564 public void unmount(GMountUnmountFlags flags, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 565 { 566 g_mount_unmount(getMountStruct(), flags, (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 567 } 568 569 /** 570 * Finishes unmounting a mount. If any errors occurred during the operation, 571 * @error will be set to contain the errors and %FALSE will be returned. 572 * 573 * Deprecated: Use g_mount_unmount_with_operation_finish() instead. 574 * 575 * Params: 576 * result = a #GAsyncResult. 577 * 578 * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise. 579 * 580 * Throws: GException on failure. 581 */ 582 public bool unmountFinish(AsyncResultIF result) 583 { 584 GError* err = null; 585 586 auto p = g_mount_unmount_finish(getMountStruct(), (result is null) ? null : result.getAsyncResultStruct(), &err) != 0; 587 588 if (err !is null) 589 { 590 throw new GException( new ErrorG(err) ); 591 } 592 593 return p; 594 } 595 596 /** 597 * Unmounts a mount. This is an asynchronous operation, and is 598 * finished by calling g_mount_unmount_with_operation_finish() with the @mount 599 * and #GAsyncResult data returned in the @callback. 600 * 601 * Params: 602 * flags = flags affecting the operation 603 * mountOperation = a #GMountOperation or %NULL to avoid 604 * user interaction. 605 * cancellable = optional #GCancellable object, %NULL to ignore. 606 * callback = a #GAsyncReadyCallback, or %NULL. 607 * userData = user data passed to @callback. 608 * 609 * Since: 2.22 610 */ 611 public void unmountWithOperation(GMountUnmountFlags flags, MountOperation mountOperation, Cancellable cancellable, GAsyncReadyCallback callback, void* userData) 612 { 613 g_mount_unmount_with_operation(getMountStruct(), flags, (mountOperation is null) ? null : mountOperation.getMountOperationStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 614 } 615 616 /** 617 * Finishes unmounting a mount. If any errors occurred during the operation, 618 * @error will be set to contain the errors and %FALSE will be returned. 619 * 620 * Params: 621 * result = a #GAsyncResult. 622 * 623 * Returns: %TRUE if the mount was successfully unmounted. %FALSE otherwise. 624 * 625 * Since: 2.22 626 * 627 * Throws: GException on failure. 628 */ 629 public bool unmountWithOperationFinish(AsyncResultIF result) 630 { 631 GError* err = null; 632 633 auto p = g_mount_unmount_with_operation_finish(getMountStruct(), (result is null) ? null : result.getAsyncResultStruct(), &err) != 0; 634 635 if (err !is null) 636 { 637 throw new GException( new ErrorG(err) ); 638 } 639 640 return p; 641 } 642 643 /** 644 * Decrements the shadow count on @mount. Usually used by 645 * #GVolumeMonitor implementations when destroying a shadow mount for 646 * @mount, see g_mount_is_shadowed() for more information. The caller 647 * will need to emit the #GMount::changed signal on @mount manually. 648 * 649 * Since: 2.20 650 */ 651 public void unshadow() 652 { 653 g_mount_unshadow(getMountStruct()); 654 } 655 656 protected class OnChangedDelegateWrapper 657 { 658 static OnChangedDelegateWrapper[] listeners; 659 void delegate(MountIF) dlg; 660 gulong handlerId; 661 662 this(void delegate(MountIF) dlg) 663 { 664 this.dlg = dlg; 665 this.listeners ~= this; 666 } 667 668 void remove(OnChangedDelegateWrapper source) 669 { 670 foreach(index, wrapper; listeners) 671 { 672 if (wrapper.handlerId == source.handlerId) 673 { 674 listeners[index] = null; 675 listeners = std.algorithm.remove(listeners, index); 676 break; 677 } 678 } 679 } 680 } 681 682 /** 683 * Emitted when the mount has been changed. 684 */ 685 gulong addOnChanged(void delegate(MountIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 686 { 687 auto wrapper = new OnChangedDelegateWrapper(dlg); 688 wrapper.handlerId = Signals.connectData( 689 this, 690 "changed", 691 cast(GCallback)&callBackChanged, 692 cast(void*)wrapper, 693 cast(GClosureNotify)&callBackChangedDestroy, 694 connectFlags); 695 return wrapper.handlerId; 696 } 697 698 extern(C) static void callBackChanged(GMount* mountStruct, OnChangedDelegateWrapper wrapper) 699 { 700 wrapper.dlg(wrapper.outer); 701 } 702 703 extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure) 704 { 705 wrapper.remove(wrapper); 706 } 707 708 protected class OnPreUnmountDelegateWrapper 709 { 710 static OnPreUnmountDelegateWrapper[] listeners; 711 void delegate(MountIF) dlg; 712 gulong handlerId; 713 714 this(void delegate(MountIF) dlg) 715 { 716 this.dlg = dlg; 717 this.listeners ~= this; 718 } 719 720 void remove(OnPreUnmountDelegateWrapper source) 721 { 722 foreach(index, wrapper; listeners) 723 { 724 if (wrapper.handlerId == source.handlerId) 725 { 726 listeners[index] = null; 727 listeners = std.algorithm.remove(listeners, index); 728 break; 729 } 730 } 731 } 732 } 733 734 /** 735 * This signal is emitted when the #GMount is about to be 736 * unmounted. 737 * 738 * Since: 2.22 739 */ 740 gulong addOnPreUnmount(void delegate(MountIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 741 { 742 auto wrapper = new OnPreUnmountDelegateWrapper(dlg); 743 wrapper.handlerId = Signals.connectData( 744 this, 745 "pre-unmount", 746 cast(GCallback)&callBackPreUnmount, 747 cast(void*)wrapper, 748 cast(GClosureNotify)&callBackPreUnmountDestroy, 749 connectFlags); 750 return wrapper.handlerId; 751 } 752 753 extern(C) static void callBackPreUnmount(GMount* mountStruct, OnPreUnmountDelegateWrapper wrapper) 754 { 755 wrapper.dlg(wrapper.outer); 756 } 757 758 extern(C) static void callBackPreUnmountDestroy(OnPreUnmountDelegateWrapper wrapper, GClosure* closure) 759 { 760 wrapper.remove(wrapper); 761 } 762 763 protected class OnUnmountedDelegateWrapper 764 { 765 static OnUnmountedDelegateWrapper[] listeners; 766 void delegate(MountIF) dlg; 767 gulong handlerId; 768 769 this(void delegate(MountIF) dlg) 770 { 771 this.dlg = dlg; 772 this.listeners ~= this; 773 } 774 775 void remove(OnUnmountedDelegateWrapper source) 776 { 777 foreach(index, wrapper; listeners) 778 { 779 if (wrapper.handlerId == source.handlerId) 780 { 781 listeners[index] = null; 782 listeners = std.algorithm.remove(listeners, index); 783 break; 784 } 785 } 786 } 787 } 788 789 /** 790 * This signal is emitted when the #GMount have been 791 * unmounted. If the recipient is holding references to the 792 * object they should release them so the object can be 793 * finalized. 794 */ 795 gulong addOnUnmounted(void delegate(MountIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 796 { 797 auto wrapper = new OnUnmountedDelegateWrapper(dlg); 798 wrapper.handlerId = Signals.connectData( 799 this, 800 "unmounted", 801 cast(GCallback)&callBackUnmounted, 802 cast(void*)wrapper, 803 cast(GClosureNotify)&callBackUnmountedDestroy, 804 connectFlags); 805 return wrapper.handlerId; 806 } 807 808 extern(C) static void callBackUnmounted(GMount* mountStruct, OnUnmountedDelegateWrapper wrapper) 809 { 810 wrapper.dlg(wrapper.outer); 811 } 812 813 extern(C) static void callBackUnmountedDestroy(OnUnmountedDelegateWrapper wrapper, GClosure* closure) 814 { 815 wrapper.remove(wrapper); 816 } 817 }