262 lines · 6.3 KB · C++
RawDownload
/*    Copyright 2019 Wolfgang Thaller.     This file is part of Retro68.     Retro68 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 3 of the License, or    (at your option) any later version.     Retro68 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 Retro68.  If not, see <http://www.gnu.org/licenses/>.*/ #include "Preferences.h" #ifdef HAVE_NAVIGATION#include <Navigation.h>#endif#include <StandardFile.h>#include <LowMem.h>#include <stdio.h>#include <string.h>#include <algorithm>#include "Window.h"#include "SystemInfo.h" static void ConvertToPathName(const FSSpec& spec){    Str255 buf;    unsigned char path[257];     CInfoPBRec ipb;     long dirID = spec.parID;    path[0] = 0;     while(dirID != 1)    {        ipb.dirInfo.ioCompletion = nullptr;        ipb.dirInfo.ioVRefNum = spec.vRefNum;        ipb.dirInfo.ioNamePtr = buf;        ipb.dirInfo.ioFDirIndex = -1;        ipb.dirInfo.ioDrDirID = dirID;         PBGetCatInfoSync(&ipb);         buf[buf[0]+1] = 0;        printf("element: %s\n", buf+1);         if(path[0] + buf[0] + 1 > 255)        {            printf("Path length overflow.\n");            return;        }         path[++path[0]] = ':';        std::reverse_copy(buf + 1, buf + 1 + buf[0], path + path[0] + 1);        path[0] += buf[0];         dirID = ipb.dirInfo.ioDrParID;    }    std::reverse(path + 1, path + 1 + path[0]);    path[path[0] + 1] = 0;    printf("path: %s\n", path+1);     memcpy(gPrefs.sharedDirectoryPath, path, path[0] + 1);    WritePrefs();} #ifdef HAVE_NAVIGATIONstatic pascal void NavEventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms, void *callBackUD){    if(callBackSelector == kNavCBEvent)    {        if(callBackParms->eventData.eventDataParms.event->what == updateEvt)        {            auto win = reinterpret_cast<WindowRef>(callBackParms->eventData.eventDataParms.event->message);            if(auto winObject = reinterpret_cast<Window*>(GetWRefCon(win)))            {                winObject->Update();            }        }    }} static bool ChooseSharedDirectoryNav(FSSpec& spec){    bool success = false;    NavReplyRecord reply = {};    NavDialogOptions options = {};     options.version = kNavDialogOptionsVersion;    options.location = {-1,-1};     auto eventProc = NewNavEventUPP(&NavEventProc);    OSErr err = NavChooseFolder(nullptr, &reply, &options, eventProc, nullptr, nullptr);    DisposeNavEventUPP(eventProc);     if(err == noErr)    {        if(reply.validRecord)        {            long count = 0;            err = AECountItems(&reply.selection, &count);            if(err == noErr && count > 0)            {                AEKeyword keyword;                DescType actualType;                Size actualSize;                 err = AEGetNthPtr(&reply.selection, 1, typeFSS, &keyword, &actualType,                    &spec, sizeof(spec), &actualSize);                 if(err == noErr)                    success = true;            }             NavDisposeReply(&reply);        }    }    return success;}#endif #if !TARGET_API_MAC_CARBONstatic bool choosePressed = false;static pascal short DlgHookProc(short item, DialogRef theDialog){    if(choosePressed)        return 1;    if(item == 11)    {        short type;        Rect r;        ControlHandle button;         GetDialogItem(theDialog, 1, &type, (Handle*)&button, &r);         choosePressed = true;        if((*button)->contrlHilite == 0)            return sfHookOpenFolder;        else            return 1;    }     return item;} static pascal Boolean FileFilterProc(CInfoPBPtr pb){    return true;} static bool ChooseSharedDirectory6(FSSpec& spec){    SFReply reply;    auto dlgHookProc = NewDlgHookUPP(&DlgHookProc);    auto fileFilterProc = NewFileFilterUPP(&FileFilterProc);    choosePressed = false;     Point position = { short((qd.screenBits.bounds.bottom - 225) / 2),                       short((qd.screenBits.bounds.right  - 348) / 2) };     SFPGetFile(position, "\p", fileFilterProc, 0, nullptr, dlgHookProc, &reply, 128, nullptr);    DisposeDlgHookUPP(dlgHookProc);    DisposeFileFilterUPP(fileFilterProc);     if(choosePressed)    {        spec.name[0] = 0;        spec.parID = LMGetCurDirStore();        spec.vRefNum = -LMGetSFSaveDisk();        return true;    }    return false;}static pascal short DlgHookYDProc(short item, DialogRef theDialog, void *yourDataPtr){    if(GetWRefCon(theDialog) != sfMainDialogRefCon)        return item;     if(choosePressed)        return 1;    if(item == 10)    {        choosePressed = true;        return sfHookOpenFolder;    }     return item;} static pascal Boolean FileFilterYDProc(CInfoPBPtr pb, void *yourDataPtr){    return true;} static bool ChooseSharedDirectory7(FSSpec& spec){    StandardFileReply reply;    auto dlgHookProc = NewDlgHookYDUPP(&DlgHookYDProc);    auto fileFilterProc = NewFileFilterYDUPP(&FileFilterYDProc);    choosePressed = false;    CustomGetFile(        fileFilterProc,        0,        nullptr,        &reply,        129,        Point{-1,-1},        dlgHookProc,        /*filterProc*/nullptr,        nullptr, nullptr,        nullptr);     DisposeDlgHookYDUPP(dlgHookProc);    DisposeFileFilterYDUPP(fileFilterProc);     if(choosePressed)    {        spec.name[0] = 0;        spec.parID = LMGetCurDirStore();        spec.vRefNum = -LMGetSFSaveDisk();        return true;    }    return false;} #endif void ChooseSharedDirectory(){    FSSpec spec;    bool ok = false;  #if TARGET_CPU_68K    if(!hasSys7StdFile)        ok = ChooseSharedDirectory6(spec);    else#endif#ifdef HAVE_NAVIGATION#if !TARGET_API_MAC_CARBON        if(NavServicesAvailable())#endif            ok = ChooseSharedDirectoryNav(spec);#if !TARGET_API_MAC_CARBON        else            ok = ChooseSharedDirectory7(spec);#endif#else        ok = ChooseSharedDirectory7(spec);#endif    if(ok)        ConvertToPathName(spec);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t