|  | @@ -21,7 +21,7 @@
 | 
	
		
			
				|  |  |  extern LA MAIN;
 | 
	
		
			
				|  |  |  extern struct _tnsMain *T;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void la_DefaultOperatorParser(laStringSplitor *ss, uint32_t *IconID, char *DisplayString){
 | 
	
		
			
				|  |  | +void la_DefaultOperatorParser(laPropPack* parent, laStringSplitor *ss, uint32_t *IconID, char *DisplayString){
 | 
	
		
			
				|  |  |      char *StrArg;
 | 
	
		
			
				|  |  |      laStringPart *sp;
 | 
	
		
			
				|  |  |      if (ss && ss->parts.pFirst){
 | 
	
	
		
			
				|  | @@ -33,9 +33,9 @@ void la_DefaultOperatorParser(laStringSplitor *ss, uint32_t *IconID, char *Displ
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -void la_PanelActiviatorParser(laStringSplitor *ss, uint32_t *IconID, char *DisplayString){
 | 
	
		
			
				|  |  | +void la_PanelActiviatorParser(laPropPack* parent, laStringSplitor *ss, uint32_t *IconID, char *DisplayString){
 | 
	
		
			
				|  |  |      char *StrArg;
 | 
	
		
			
				|  |  | -    la_DefaultOperatorParser(ss,IconID,DisplayString);
 | 
	
		
			
				|  |  | +    la_DefaultOperatorParser(parent,ss,IconID,DisplayString);
 | 
	
		
			
				|  |  |      if (ss && ss->parts.pFirst){
 | 
	
		
			
				|  |  |          if (StrArg = strGetArgumentString(ss, "text")){
 | 
	
		
			
				|  |  |              strCopyFull(DisplayString, StrArg);
 | 
	
	
		
			
				|  | @@ -48,6 +48,19 @@ void la_PanelActiviatorParser(laStringSplitor *ss, uint32_t *IconID, char *Displ
 | 
	
		
			
				|  |  |          strCopyFull(DisplayString, transLate("Activate A Panel"));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +void la_RunToolboxEntryParser(laPropPack* parent, laStringSplitor *ss, uint32_t *IconID, char *DisplayString){
 | 
	
		
			
				|  |  | +    char *StrArg;
 | 
	
		
			
				|  |  | +    la_DefaultOperatorParser(parent, ss,IconID,DisplayString);
 | 
	
		
			
				|  |  | +    if(parent && parent->EndInstance){
 | 
	
		
			
				|  |  | +        laInputMappingEntry* ime=parent->EndInstance;
 | 
	
		
			
				|  |  | +        char* display=SSTR(ime->Key), *opname=SSTR(ime->OperatorName);
 | 
	
		
			
				|  |  | +        if(ime->UseOperator){
 | 
	
		
			
				|  |  | +            sprintf(DisplayString,"%s",display[0]?display:opname); 
 | 
	
		
			
				|  |  | +        }else{
 | 
	
		
			
				|  |  | +            sprintf(DisplayString,"%s",display[0]?display:SSTR(ime->Signal)); 
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  laProp *la_PropLookup(laListHandle *lst, char *ID);
 | 
	
		
			
				|  |  |  void la_EnsurePanelSnapping(laPanel *p, int CW, int CH);
 | 
	
	
		
			
				|  | @@ -357,12 +370,11 @@ findnext:
 | 
	
		
			
				|  |  |          Name[0] = *pd;
 | 
	
		
			
				|  |  |          if (GetDiskFreeSpaceEx(Name, &FreeAvailable, &TotalSpace, &FreeSpace_UNUSED)){
 | 
	
		
			
				|  |  |              dl = memAcquire(sizeof(laDiskItem));
 | 
	
		
			
				|  |  | -            dl->ID = *pd;
 | 
	
		
			
				|  |  | +            dl->Path[0] = *pd;
 | 
	
		
			
				|  |  |              dl->Total_GB = (real)TotalSpace / 1073741824.0f;   //B->GB
 | 
	
		
			
				|  |  |              dl->Free_GB = (real)FreeAvailable / 1073741824.0f; //B->GB
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            if (Name[0] == fb->Path[0])
 | 
	
		
			
				|  |  | -                fb->RootDisk = dl;
 | 
	
		
			
				|  |  | +            if (Name[0] == fb->Path[0]) fb->RootDisk = dl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              lstAppendItem(&fb->Disks, dl);
 | 
	
		
			
				|  |  |          }
 | 
	
	
		
			
				|  | @@ -370,6 +382,39 @@ findnext:
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +#ifdef LA_LINUX
 | 
	
		
			
				|  |  | +    /* Loop over mount points, not caring about gvfs network drives. */
 | 
	
		
			
				|  |  | +    struct mntent *mnt;
 | 
	
		
			
				|  |  | +    FILE *fp;
 | 
	
		
			
				|  |  | +    fp = setmntent(MOUNTED, "r");
 | 
	
		
			
				|  |  | +    if (!fp) {
 | 
	
		
			
				|  |  | +        logPrintNew("Could not get a list of mounted file-systems\n");
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    else {
 | 
	
		
			
				|  |  | +        while ((mnt = getmntent(fp))) {
 | 
	
		
			
				|  |  | +            if (strPrefix(mnt->mnt_dir, "/boot")) continue;
 | 
	
		
			
				|  |  | +            if (!strPrefix(mnt->mnt_fsname, "/dev")) continue;
 | 
	
		
			
				|  |  | +            if (strPrefix(mnt->mnt_fsname, "/dev/loop")) continue;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            dl = memAcquire(sizeof(laDiskItem));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            strcpy(dl->Path, mnt->mnt_dir);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            struct statvfs stats={0};
 | 
	
		
			
				|  |  | +            statvfs(mnt->mnt_dir, &stats);
 | 
	
		
			
				|  |  | +            dl->Total_GB = (real)stats.f_frsize*stats.f_blocks / 1073741824.0f;
 | 
	
		
			
				|  |  | +            dl->Free_GB = (real)stats.f_bsize*stats.f_bavail / 1073741824.0f;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (strPrefix(fb->Path, dl->Path)) fb->RootDisk = dl;
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            lstAppendItem(&fb->Disks, dl);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (endmntent(fp) == 0) {
 | 
	
		
			
				|  |  | +            logPrintNew("Could not close the list of mounted file-systems\n");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      fb->Active = 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  laFileBrowser *la_FileBrowserInit(laOperator *a){
 | 
	
	
		
			
				|  | @@ -491,15 +536,25 @@ void *laget_FileBrowserFirstFile(laFileBrowser *fb, void* unused){
 | 
	
		
			
				|  |  |  void *laget_FileBrowserActiveFile(laFileBrowser *fb){
 | 
	
		
			
				|  |  |      return fb->Active;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -void laget_FileBrowserDiskID(laDiskItem *di, char *result){
 | 
	
		
			
				|  |  | +void laget_FileBrowserDiskID(laDiskItem *di, char *result, char** move){
 | 
	
		
			
				|  |  | +#ifdef _WIN32
 | 
	
		
			
				|  |  |      result[0] = di->ID;
 | 
	
		
			
				|  |  |      result[1] = U':';
 | 
	
		
			
				|  |  |      result[2] = LA_PATH_SEP;
 | 
	
		
			
				|  |  |      result[3] = U'\0';
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +#ifdef LA_LINUX
 | 
	
		
			
				|  |  | +    *move = di->Path;
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +void laget_FileBrowserDiskCapacity(laDiskItem *di, char *result, char** move){
 | 
	
		
			
				|  |  | +    sprintf(result, "%.1lf/%.1lfGB",di->Free_GB,di->Total_GB);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  void *laset_FileBrowserActiveDisk(laFileBrowser *fb, laDiskItem *di, int UNUSED_State){
 | 
	
		
			
				|  |  |      fb->RootDisk = di;
 | 
	
		
			
				|  |  | -    laget_FileBrowserDiskID(di, fb->Path);
 | 
	
		
			
				|  |  | +    char path[1024]; char* _path=path;
 | 
	
		
			
				|  |  | +    laget_FileBrowserDiskID(di, path, &_path);
 | 
	
		
			
				|  |  | +    strcpy(fb->Path,_path);
 | 
	
		
			
				|  |  |      la_FileBrowserRebuildList(fb);
 | 
	
		
			
				|  |  |      fb->FileName[0] = 0;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -899,10 +954,12 @@ int OPINV_RemoveResourceFolder(laOperator *a, laEvent *e){
 | 
	
		
			
				|  |  |  int OPCHK_Undo(laPropPack *This, laStringSplitor *ss){
 | 
	
		
			
				|  |  |      laDiff* diff=MAIN.HeadDifference; if(!diff) return 0;
 | 
	
		
			
				|  |  |      diff=diff->Item.pPrev; if(!diff) return 0;
 | 
	
		
			
				|  |  | +    return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  int OPCHK_Redo(laPropPack *This, laStringSplitor *ss){
 | 
	
		
			
				|  |  |      laDiff* diff=MAIN.HeadDifference; if(!diff) return 0;
 | 
	
		
			
				|  |  |      if(diff==MAIN.Differences.pLast) return 0;
 | 
	
		
			
				|  |  | +    return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  int OPINV_Undo(laOperator *a, laEvent *e){
 | 
	
		
			
				|  |  |      laUndo();
 | 
	
	
		
			
				|  | @@ -955,6 +1012,15 @@ int OPMOD_RemoveToolbox(laOperator *a, laEvent *e){
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      return LA_RUNNING;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +int OPINV_RunToolboxEntry(laOperator *a, laEvent* e){
 | 
	
		
			
				|  |  | +    laInputMappingEntry* ime = a->This?a->This->EndInstance:0; if(!ime) return LA_CANCELED;
 | 
	
		
			
				|  |  | +    if(ime->UseOperator && ime->OperatorType){
 | 
	
		
			
				|  |  | +        laInvokeP(a, ime->OperatorType, e, 0, SSTR(ime->OperatorArguments), 0);
 | 
	
		
			
				|  |  | +    }else{
 | 
	
		
			
				|  |  | +        la_SendSignalEvent(e->window->win, ime->SignalValue);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    return LA_FINISHED;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  int OPINV_NewInputMapping(laOperator *a, laEvent *e){
 | 
	
		
			
				|  |  |      laNewInputMapping("New Mapping"); laNotifyUsers("la.input_mapping"); return LA_FINISHED;
 | 
	
	
		
			
				|  | @@ -2625,6 +2691,7 @@ void la_RegisterBuiltinOperators(){
 | 
	
		
			
				|  |  |          laAddStringProperty(p, "id", "ID", "Disk identifier", 0, 0, 0, 0, 0, 0, 0, laget_FileBrowserDiskID, 0, 0, 0);
 | 
	
		
			
				|  |  |          laAddFloatProperty(p, "total_gb", "Total", "Disk total compacity in gigabytes", 0, 0, "GB", 0, 0, 0, 0, 0, offsetof(laDiskItem, Total_GB), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);
 | 
	
		
			
				|  |  |          laAddFloatProperty(p, "free_gb", "Free", "Disk Free Space Size In Gigabytes", 0, 0, "GB", 0, 0, 0, 0, 0, offsetof(laDiskItem, Free_GB), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,LA_READ_ONLY);
 | 
	
		
			
				|  |  | +        laAddStringProperty(p,"capacity","Capacity","Capacity of this disk",LA_WIDGET_STRING_PLAIN,0,0,0,0,0,0,laget_FileBrowserDiskCapacity,0,0,LA_READ_ONLY);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      p = laAddPropertyContainer("file_item", "File Item", "A file item in a list", U'🖹', 0, 0, 0, 0, 0);{
 | 
	
		
			
				|  |  |          laAddStringProperty(p, "name", "Name", "The name of the file (with extension)", 0, 0, 0, 0, 0, offsetof(laFileItem, Name), 0, 0, 0, 0, LA_UDF_LOCAL);
 | 
	
	
		
			
				|  | @@ -2705,6 +2772,8 @@ void la_RegisterBuiltinOperators(){
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  |      laCreateOperatorType("LA_send_signal", "Send Signal", "Send signal to the UI", 0, 0, 0, OPINV_SendSignal, 0, 0, LA_ACTUATOR_SYSTEM);
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | +    laCreateOperatorType("LA_run_toolbox_entry", "Run Entry", "Run toolbox entry", 0, 0, 0, OPINV_RunToolboxEntry, 0, 0, LA_ACTUATOR_SYSTEM)
 | 
	
		
			
				|  |  | +        ->ParseArgs = la_RunToolboxEntryParser;
 | 
	
		
			
				|  |  |      laCreateOperatorType("LA_new_toolbox", "New Toolbox", "New custom toolbox", 0, 0, 0, OPINV_NewToolbox, 0, '+', LA_ACTUATOR_SYSTEM);
 | 
	
		
			
				|  |  |      laCreateOperatorType("LA_remove_toolbox", "Remove Toolbox", "Remove custom toolbox", 0, 0, 0, OPINV_RemoveToolbox, OPINV_RemoveToolbox, U'🞫', LA_ACTUATOR_SYSTEM);
 | 
	
		
			
				|  |  |      laCreateOperatorType("LA_new_input_mapping", "New Mapping", "New input mapping", 0, 0, 0, OPINV_NewInputMapping, 0, '+', LA_ACTUATOR_SYSTEM);
 |