K vašim službám 5: stále vyhrazeno pro programátory - MujMAC.cz - Apple, Mac OS X, Apple iPod

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Odkud pochází fotografka Anne Erhard?

V dnešní soutěži hrajeme o:

Seriály

Více seriálů



Software

K vašim službám 5: stále vyhrazeno pro programátory

macosearly

18. prosince 2001, 00.00 | Minule jsme si slíbili kompletní aplikaci, která umožní prohlížení složek a souborů, a která bude plně podporovat (mj.) souborové služby. Není to nic těžkého — jen se podívejme.

K vašim službám 5: stále vyhrazeno pro programátory

Minule jsme si slíbili kompletní aplikaci, která umožní prohlížení složek a souborů, a která bude plně podporovat (mj.) souborové služby. Není to nic těžkého — jen se podívejme:

Projekt

Ačkoli nový ProjectBuilder není ani zdaleka tak pohodlný, jako býval původní ProjectBuilder z OpenStepu, na to, co potřebujeme dnes, jeho služby nejsou nijak zapeklité: prostě si vyžádáme vytvoření nového projektu typu "Cocoa Application".

Nejprve připravíme uživatelské rozhraní

V přehledu souborů otevřeme skupinu "Resources" a poklepáním otevřeme soubor "MainMenu.nib", který obsahuje základní GUI nově vytvářené aplikace:

ProjectBuilder automaticky spustí aplikaci InterfaceBuilder, a v té provedeme následující kroky:

Příprava browseru pro zobrazení dat

V InterfaceBuilderu vidíme, že systém pro nás už připravil základní okno aplikace; víc jich potřebovat ani nebudeme. Jen do okna umístíme browser, ve kterém budeme zobrazovat složky a soubory.

Najdeme paletu připravených objektů (pokud není vidět, zobrazíme ji příkazem "Tools / Palettes / Show Palettes"), a v ní přepneme na skupinu "Cocoa Data Views" — standardně je v okně palet na pátém místě, a její ikona vypadá jako textový editor. Z této skupiny vybereme browser — je v pravém dolním rohu — a vhodíme jej do okna:

Browser myší roztáhneme tak, aby zabral celé okno, a použijeme inspektor pro nastavení jeho atributů. Inspektor otevřeme příkazem "Tools / Show Info" (v OS X je pro vetší zmatení pojmů nyní v módě říkat inspektorům "info panely"); v jeho horní části je pop-up menu, které přapíná mezi různými režimy. My použijeme zatím režimy "Attributes" a "Size" pro nastavení požadovaného chování browseru:

Objekt, který řídí aplikaci

V korektně navržené objektové aplikaci je obvykle jeden objekt, který řídí aplikaci — na jedné straně interpretuje požadavky uživatele a řídí zobrazení dat v GUI, na straně druhé přistupuje k "datovému modelu" aplikace.

Nejinak tomu bude u nás: připravíme objekt třídy Controller, který bude celou aplikaci řídit. I to můžeme udělat přímo v InterfaceBuilderu: nejprve přepneme hlavní okno InterfaceBuilderu do režimu Classes, a tam nalezneme třídu NSObject. Nad ní použijeme kontextové pop-up menu (pravá klávesa myši, nebo Control-klepnutí pro nešťastníky, kteří mají myš s jediným tlačítkem), a z něj vybereme příkaz "Subclass NSObject"; InterfaceBuilder vytvoří a označí novou třídu MyObject:

Použijeme opět inspektor (v režimu "Attributes"), abychom třídu přejmenovali na "Controller", a abychom do ní přidali jeden "outlet" se jménem "browser". Outlety jsou odkazy na jiné objekty; my budeme potřebovat, aby náš controller měl k dispozici odkaz na browser, a ten jsme se právě připravili.

Nyní musíme zajistit

  1. aby zdrojové soubory, obsahující implementaci controlleru, byly k dispozici v ProjectBuilderu. Toho docílíme tak, že v hlavním okně InterfaceBuilderu nad třídou Controller použijeme opět kontextové pop-up menu, a z něj zvolíme příkaz "Create Files for Controller" (a následující dialog prostě potvrdíme tlačítkem "Choose");
  2. aby skutečně existoval objekt třídy Controller. Toho docílíme tak, že v tomtéž kontextovém pop-up menu zvolíme příkaz "Instantiate Controller".

Potřebná propojení

Nesmíme zapomenout, že v controlleru sice máme outlet "browser", ale ještě jsme se nepostarali o to, aby jeho obsahem byl skutečně odkaz na browser, který jsme hned na začátku umístili do okna. Na to (a na podobné účely) máme v InterfaceBuilderu "dráty": kterékoli dva objekty můžeme propojit tak, že mezi nimi natáhneme "drát" myší, přidržíme-li zároveň přapínač Control; v inspektoru "Connections" pak zvolíme, jaké propojení máme na mysli.

Pro naši aplikaci potřebujeme propojení tři:

  • z controlleru (který se nám po poslední akci "Instantiate..." objevil v hlavním okně jako modrá krychlička) natáhneme drát na browser, a v inspektoru zvolíme náš outlet "browser";
  • z ikonky "File's Owner" natáhneme drát na controller, a v inspektoru vybereme outlet "delegate" — tak zajistíme, že controller bude zapojen do "responder chainu", a můžeme v něm implementovat metody pro práci se Services (viz minulý díl seriálu);
  • z browseru natáhneme drát na controller, a opět zvolíme outlet "delegate". Tím zajistíme, že browser si od controlleru vyžádá data, jež bude zobrazovat.

Následující obrázek ilustruje první "prodrátování"; druhá dvě jsou stejně jednoduchá:

Stačí dopsat pár metod...

S GUI jsme hotovi, musíme jen dopsat pát zbylých metod

  • pro zobrazení složek a souborů v browseru;
  • pro podporu Services.

Zobrazení složek a souborů

Vzhledem k tomu, že se nejedná o hlavní téma našeho seriálu, projdeme tuto část jen velmi rychle:

  1. do souboru Controller.h přidáme vedle outletu "browser" (který tam už samozřejmě je) novou proměnnou "fm": do ní za chvilku uložíme objekt třídy NSFileManager, který nám zajistí přístup k souborům;
  2. v souboru Controller.m opět použijeme metodu awakeFromNib pro inicializaci (zatím v ní jen naplníme proměnnou "fm");
  3. přidáme metodu browser:numberOfRowsInColumn:, jejímž prostřednictvím se browser svého delegáta ptá, kolik má být řádků v daném sloupci. Implementace prostě zjistí od file manageru počet objektů na odpovídající cestě, a ten vrátí;
  4. přidáme metodu browser:willDisplayCell:atRow:column: — tu browser používá pro určení hodnoty pro konkrétní položku. My si prostě vyžádáme odpovídající soubor nebo složku od file manageru, a jméno uložíme do browseru. Navíc zjistíme, jde-li o soubor nebo složku, a podle toho určíme atribut "leaf" (list).

Oba soubory nyní vypadají takto:

// Controller.h
#import <Cocoa/Cocoa.h>
@interface Controller : NSObject {
    IBOutlet id browser;
    id fm;
}
@end

//Controller.m
#import "Controller.h"
@implementation Controller
-(void)awakeFromNib {
    fm=[NSFileManager defaultManager];
}
-(int)browser:(NSBrowser*)sender numberOfRowsInColumn:(int)column {
    NSString *path=column?[sender pathToColumn:column]:@"/";
    return [[fm directoryContentsAtPath:path] count];
}
-(void)browser:(NSBrowser*)sender willDisplayCell:(id)cell
        atRow:(int)row column:(int)column {
    NSString *path=column?[sender pathToColumn:column]:@"/";
    NSString *component=[[fm directoryContentsAtPath:path] objectAtIndex:row];
    NSDictionary *attrib=[fm fileAttributesAtPath:
        [path stringByAppendingPathComponent:component] traverseLink:YES];
    [cell setTitle:component];
    [cell setLeaf:![[attrib objectForKey:NSFileType] isEqualToString:NSFileTypeDirectory]];
}
@end

Nyní už můžeme browser používat pro prohlížení systému složek a souborů (mimochodem, zkuste to! Nestačíte se divit, jak nepřesnou představu o tom, jaké složky a soubory jsou skutečně k dispozici a pod jakými jmény dává Finder!). Chybí však zatím to hlavní, kvůli čemu jsme se do celé práce pouštěli: podpora služeb.

Podpora Services

Podpora Services však je poměrně jednoduchá. Připomeňme z minulého dílu, že stačí zařídit tři věci:

  1. na začátku se aplikace zaregistruje se všemi datovými typy, nad nimiž má pro ni smysl vůbec Services využívat;
  2. implementovat metodu validRequestorForSendType:returnType: pro zjištění, jaká data jsou momentálně k dispozici;
  3. implementovat metodu writeSelectionToPasteboard:types: pro odeslání dat.

Vzhledem k tomu, že jsme zapojili náš controller do responder chainu (připojením na outlet "delegate" objektu "File's Owner"), můžeme vše implementovat přímo v něm. Pro zajištění prvého bodu prostě stačí přidat do metody awakeFromNib řádek

[NSApp registerServicesMenuSendTypes:[NSArray arrayWithObject:NSFilenamesPboardType]
    returnTypes:nil];

I metoda validRequestorForSendType:returnType: je triviální — jen ověříme požadovaný typ, a zjistíme, je-li vůbec něco v browseru označeno:

-(id)validRequestorForSendType:(NSString*)sendType returnType:(NSString*)returnType {
    if ([sendType isEqual:NSFilenamesPboardType] && [browser selectedCell])
        return self;
    return nil;
}

Malinko složitější je jen poslední metoda, writeSelectionToPasteboard:types:. Příčinou je to, že v browseru může být označeno libovolně mnoho objektů najednou, a my samozřejmě musíme systému služeb předat všechny. Proto je zapotřebí nejprve pomocí NSEnumeratoru připravit seznam všech označených objektů, a pak teprve jej již známým způsobem předat dál. I tak nám na ni stačí přibližně deset řádků:

-(BOOL)writeSelectionToPasteboard:(NSPasteboard*)pboard types:(NSArray*)types {
    if ([types containsObject:NSFilenamesPboardType] && [browser selectedCell]) {
        NSString *rootPath=[[browser path] stringByDeletingLastPathComponent];
        NSMutableArray *selectedFiles=[NSMutableArray array];
        NSEnumerator *en=[[browser selectedCells] objectEnumerator];
        NSCell *cell;
        while (cell=[en nextObject])
            [selectedFiles addObject:
                [rootPath stringByAppendingPathComponent:[cell title]]];
        [pboard declareTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil];
        return [pboard setPropertyList:selectedFiles forType:NSFilenamesPboardType];
    }
    return NO;
}

To je už opravdu vše: můžeme aplikaci zbuildovat a vyzkoušet — hned máme k dispozici např. služby pro archivaci souborů:

(Mimochodem, podpora tear-off menu stále není standardní součástí OSX; protože však bez ní je OSX zhola nepoužitelný, napsal jsem si na to hack, který aspoň zčásti vrací skvělé vlastnosti GUI NeXTStepu.)

Ti, kdo by snad s postupnou tvorbou aplikace měli potíže, naleznou kompletní projekt, připravený přesně popsaným postupem, na www.ocs.cz/Apps/MiniWM.tar.gz.

Příště...

...už seriál opravdu ukončíme tím, že si ukážeme, jak naprogramovat poskytování služeb ostatním aplikacím.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Informace  

 » Rubriky  » Agregator  

 » Rubriky  » Software  

 

 

 

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: