Hello Riccardo,
Hello All,

On 2026-02-26 22:06:48 +0100 Riccardo Mottola
<[email protected]> wrote:

Patrick CARDONA wrote:
Hello,

I am working on an Internet Shortcuts Manager (aka SaveLink).

I associated the same action (statechange:) on my two fields ('name' and 'link').
If they are not empty, the 'savebutton' should be enabled.
But my button state does never change. Initial state is disabled and it remains in this state.


I didn't download your project, just reading the code.

Are you sure you get statechange called? is it connected?

It was never called.

Put an NSLog(@"statechange called") and check.

Si I modified  several things:
- I removed the method statechange.
- I set the class 'SaveLink'  as an NSApp delegate.
- I added two new methods: (1) 'observe' and (2) 'textDidChange' (see
below)
- I connected the textFields to the action 'observe:'


Put an NSLog(@"Enable"); here so you are sure that the condition is matched and the issue is in setEnabled.

- I put all NSLog messages as recommended.


You can easily write this condition as:

if([nameLink length] && [urlLink length])

It checks that both string are valid and longer than zero. Not necessary, but it can also be quicker, since it will bail out on a nil string.

- I used better comparison statements.


you could also try to trim spaces.

- I added trim spaces on nameLink.


Riccardo


Testing:
- Opening a link... then save : working as expected.
- NewLink command or reset button, then save :  working as expected.
- Typing in the form just after the App has started: I did not yet
find the way to make it work.

The code improved:

<SaveLink.m>


<SaveLink_main.m>

and the whole project...

<SaveLink.tar.gz>

--
Patrick Cardona - Pi500 - GNU/Linux aarch64 (Debian 13.3)
Xorg (1:7.7+24) - libcairo2 (1.18.4-1+rpt1 arm64) - Window Maker
(0.96.0-4)
GWorkspace (1.1.0 - 02 2025) - Theme: AGNOSTEP - Classic - MUA:
GNUMail (1.4.0 - rev.947)
/* All rights reserved */

#import "SaveLink.h"

int isDirectoryExists(const char *path)
{
    struct stat stats;

    stat(path, &stats);

    // Check for file existence
    if (S_ISDIR(stats.st_mode))
        return 1;

    return 0;
}

id getFavPath()
{
 // Retrieving UserName of the current User and then his homeDirectory
  NSString *userName = NSUserName();
  NSString *homeDir = NSHomeDirectoryForUser(userName);
  
  // LANG ENV?
  const char *Lang = getenv("LANG");
  NSString *prefLang = [NSString stringWithFormat:@"%s",Lang];
  NSLog(@"Preferred Language: %@", prefLang);
  NSString *shortLG = [prefLang substringToIndex: 2];
  NSLog(@"Prefix Language: %@", shortLG);
  // Favorites Folder Name?
  NSString *favFolder;
  NSArray *items;
  items = [NSArray arrayWithObjects: @"fr", @"en", nil];
  int item = [items indexOfObject: shortLG];
  switch (item) {
    case 0:
       favFolder = @"/Favoris/";
       break;
    case 1:
       favFolder = @"/Favorites/";
       break;
    default:
       favFolder = @"/Favorites/";
   }
   NSString *favPath = [homeDir stringByAppendingString: favFolder];
   return favPath;
}

@implementation SaveLink

- (IBAction) observe:(id)sender
{
  // Register for notifications
  [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(textDidChange:)
                                                 
name:NSControlTextDidChangeNotification
                                               object:name];
                                               
  [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(textDidChange:)
                                                 
name:NSControlTextDidChangeNotification
                                               object:link];
}

- (IBAction) save: (id)sender
{
  NSLog(@"We enter in SaveLink method...");
  // We retrieve values from textFileds outlets
  // Also We trim spaces in the nameLink:
  NSString *nameLink = [[name stringValue] 
stringByReplacingOccurrencesOfString:@" " withString:@""];
  NSString *urlLink = [link stringValue];
  
  // Setting filePath
  NSString *ext = @".url";
  NSString *favPath = getFavPath();
  
  // Retrieving UserName of the current User and then his homeDirectory
  NSString *userName = NSUserName();
  NSString *homeDir = NSHomeDirectoryForUser(userName);
  // We check Favorites path
  const char *path = [favPath UTF8String];
  if (isDirectoryExists(path))
  {
  NSString *filePath = [[[homeDir stringByAppendingString: @"/Favoris/"] 
stringByAppendingString: nameLink] stringByAppendingString: ext];
      
  // Preparing the content to write
  NSString *content = [NSString stringWithFormat: 
@"[InternetShortcut]\nURL=%@\n", urlLink];
  // Writing to File Name.url
  NSError *error;
  BOOL success;

  success = [content writeToFile:filePath
                         atomically:YES
                           encoding:NSUTF8StringEncoding
                              error:&error];

  if (!success) {
    NSLog(@"Failed to write file: %@", [error localizedDescription]);
    [NSApp terminate: self];                   
   }

 NSLog(@"End of save action");
 }
 else
 {
   NSLog(@"Path of Favorites not found!");
   NSAlert *alert = [[[NSAlert alloc] init] autorelease];
   [alert setMessageText:@"Path of Favorites not found!"];
   [alert setInformativeText:@"You should have a Favorites folder in your Home 
Directory."];
   [alert runModal];
   [NSApp terminate:nil];
 }
}

- (IBAction) reset: (id)sender
{
  [link setStringValue:@""];
  [name setStringValue:@""];
  [name becomeFirstResponder];
  [self observe: nil];
}

- (IBAction) open:  (id)sender
{
  NSString *favPath = getFavPath();
  int lenPath = [favPath length];
  
  // Filter: we want only .url files to open
  NSArray *fileTypes;
  fileTypes = [NSArray arrayWithObjects: @"url", nil];
  // Open Panel
  NSOpenPanel *openPanel;
  openPanel = [[[NSOpenPanel alloc] init] autorelease];
  [openPanel runModalForTypes: fileTypes];
  NSArray *selection;
  selection = [openPanel filenames];
  NSString *openPath = [selection firstObject];
  
  // Get Name of the Link
  NSString *filePath = [openPath substringFromIndex: lenPath];
  int lenFilePath = [filePath length];
  NSString *nameLink = [filePath substringToIndex: lenFilePath - 4];
  [name setStringValue: nameLink];
  
  // Get Link value
  NSString *content;
  content = [NSString stringWithContentsOfFile: openPath];
  NSString *url =  [content substringFromIndex: 23];
  [link setStringValue: url];
  [savebutton setEnabled:YES];
  [self observe: nil];
}

- (void)textDidChange:(NSNotification *)notification
{
  // We retrieve values from textFileds outlets
  NSLog(@"textDidChange called.");
  NSString *nameLink = [name stringValue];
  NSString *urlLink = [link stringValue];
  if([nameLink length])
  {
    if([[urlLink substringToIndex: 4] isEqualToString: @"http"])
    {
      NSLog(@"Button save enabled");
      [savebutton setEnabled:YES];
    }
  }
  else
  { 
    [savebutton setEnabled:NO];
  }
}

@end
/* 
   Project: SaveLink

   Author: patrick

   Created: 2026-02-24 16:14:34 +0100 by patrick
*/

#import <AppKit/AppKit.h>
#import "SaveLink.h"

int 
main(int argc, const char *argv[])
{
  [NSApp setDelegate: [SaveLink new]];
  return NSApplicationMain (argc, argv);
}

Attachment: SaveLink.tar.gz
Description: GNU Zip compressed data

Reply via email to