Commits

Ivan Vučica committed 884da14

Doc: AppKit (work from a few days ago). Doc: libclang up to cursors.

Comments (0)

Files changed (1)

 %\raggedleft
 %\begin{minipage}{5cm}
 
-\begin{wrapfigure}{r}{7.5cm} % wrap
-\vspace{-20pt} %wrap
+\begin{wrapfigure}{r}{7.2cm} % wrap
+\vspace{-23pt} %wrap
 \begin{center} % wrap
-\includegraphics[width=7.5cm]{global-menu.png}
+\includegraphics[width=7.2cm]{global-menu.png}
 \end{center} % wrap
-\vspace{-10pt} % wrap
+\vspace{-12pt} % wrap
 \caption{Globalni izbornik}
 \label{img:globalmenu}
-\vspace{-10pt} % wrap
+\vspace{-12pt} % wrap
 \end{wrapfigure} % wrap
 %\end{minipage}
 %\end{figure}
 %\raggedleft
 %\begin{minipage}{5cm}
 
-\begin{wrapfigure}{r}{7.5cm} % wrap
-\vspace{-20pt} %wrap
+\begin{wrapfigure}{r}{7.2cm} % wrap
+\vspace{-23pt} %wrap
 \begin{center} % wrap
-\includegraphics[width=7.5cm]{mac-os-x-public-beta.png}
+\includegraphics[width=7.2cm]{mac-os-x-public-beta.png}
 \end{center} % wrap
-\vspace{-10pt} % wrap
+\vspace{-12pt} % wrap
 \caption{Mac OS X Public Beta: dock, globalni izbornik, fokus na aplikacije}
 \label{img:macosxpublicbeta}
-\vspace{-10pt} % wrap
+\vspace{-12pt} % wrap
 \end{wrapfigure} % wrap
 %\end{minipage}
 %\end{figure}
 Dosta spomenutih posebnosti mogu se dobiti i na drugim sustavima koristeći
 biblioteke koje reimplementiraju Cocoa, kao što je GNUstep ili Cocotron.
 
-\section{Jezik Objective-C i biblioteka Foundation}
+%%
+\section{Jezik Objective-C}
 Programski jezik Objective-C primarno je prepoznatljiv po "uglatim zagradama".
 Radi se o sintaksnom elementu koji ukazuje na njegovo naslijeđe od jezika
 SmallTalk, jednog od začetnika koncepta objektno orijentirane paradigme.
 
+U jeziku Objective-C ne postoji koncept višestrukog nasljeđivanja. 
+Gotovo nikad se ne piše korijenska \engl{root} klasa, s obzirom da takva
+klasa mora implementirati veliku količinu tehničkog koda radi integracije
+s \textit{runtimeom} jezika. Također, sav ostali kod napisan od autora 
+platforme, kao i od treće strane, tipično očekuje postojanje nekih metoda
+u svakom objektu koji postoji u programu. Stoga sve klase tipično nasljeđuju
+klasu \texttt{NSObject}, a puno rjeđe klasu \texttt{NSProxy}. Gotovo nikad
+se ne koristi neka treća korijenska klasa ili vlastita korijenska klasa.
+
+Metode se u ovom jeziku pronalaze dinamički, bazirano na stringu (odnosno
+ekvivalentnoj strukturi koja se naziva selektor). Sve metode su obične
+C funkcije s preddefiniranim \textit{signatureom} kao u listingu
+\ref{lst:signature}.
+
+\begin{lstlisting}[caption=\textit{Signature} za metode,
+  label=lst:signature,
+  %float=t % prazno mjesto na vrhu
+]
+typedef id (*IMP)(id, SEL, ...); 
+\end{lstlisting}
+
+Selektor prema konvenciji započinje malim slovom. Formira se kao 
+\textit{camel-case} opis onoga što metoda radi, a argumenti se ubacuju
+na mjesta dvotočki.
+
+Ovo sve nije toliko zbunjujuće jer se, konceptualno, pozivanje metode
+ne smatra pozivanjem metode, već "slanjem poruke". Pri slanju jedne poruke,
+unutar uglatih zagrada prvo se navodi odredišni objekt za primanje
+poruke (tip podataka \texttt{id} koji određuje "pokazivač na bilo kakav 
+objekt"), te zatim selektor izmiješan s argumentima metode. Sam izraz
+s uglatim zagradama ima vrijednost koja je neki C-ov tip podataka (pri čemu
+su Objective-C tipovi podataka također C-ovi tipovi podataka). Primjer
+možemo vidjeti u listingu \ref{lst:messagesend}. U istom listingu, vidimo
+situaciju gdje se povratna vrijednost jednog slanja poruke (slanje poruke
+\texttt{alloc} klasi \texttt{NSWindow} kroz \texttt{[NSWindow alloc]})
+koristi kao odredište za drugo slanje poruke (slanje poruke 
+\texttt{initWithContentRect:styleMask:backing:defer:} instanci klase
+\texttt{NSWindow}).
+
+\begin{lstlisting}[caption=Slanje poruke,
+  label=lst:messagesend
+]
+[[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 150, 150)
+                             styleMask:NSTitledWindowMask|NSClosableWindowMask
+                               backing:NSBackingStoreBuffered
+                                 defer:NO] autorelease];
+\end{lstlisting}
+
+S obzirom da se sve metode dinamički traže, moguće je pozvati metodu koja
+u klasi ne postoji. Tipovi se provjeravaju pri prevođenju, no pozivanje
+nepostojeće metode izaziva samo upozorenje.
+
+U listingu \ref{lst:messagesend}, vidimo slanje poruke \texttt{autorelease}.
+To je metoda instance za klasu \texttt{NSObject}, a pronalazi "najbliži" 
+objekt klase \texttt{NSAutoreleasePool} i ubacuje se u njega. Zatim, kada
+se navedeni \textit{pool} isprazni, svim objektima šalje se poruka
+\texttt{release}.
+
+Poruke \texttt{retain} i \texttt{release} dvije su komplementarne radnje u
+metodi upravljanja memorijom koja je raširena u Objective-C, a to je
+brojanje referenci \engl{reference counting}. Svaka instanca objekta ima
+dodijeljen brojač referenci koji se koristeći \texttt{retain} ručno poveća
+kad god neki objekt želi osigurati da drugi objekt "ostane živ", odnosno da
+pokazivač na njega ostane važiti. Kada ga pojedini objekt više ne zanima,
+tada poziva \texttt{release}. Kada brojač referenci padne na nulu, metoda
+\texttt{release} zove metodu \texttt{dealloc}, čija osnovna implementacija
+u \texttt{NSObject}-u oslobađa memoriju (primjerice koristeći C-ovu funkciju
+\texttt{free()}).  (Zanimljivo je i to da svaka metoda koja u nazivu nema
+\texttt{init}, \texttt{create} odnosno \texttt{new} mora vratiti objekt
+koji će biti \texttt{autorelease}-an, C tip podataka ili ništa; ako
+naziv metode počinje s nečime od navedenog, tada objekt po konvenciji također
+treba imati brojač referenci postavljen na 1, ali bez automatskog oslobađanja.
+Ukoliko vraćeni objekt nije novostvoren, onda mu se u principu ne dira
+\textit{reference counter}.)
+
+Svaka instanca klase je definirana kao C struktura koja sadrži pokazivač
+na instancu klase \texttt{Class}. Ta instanca sadrži metode klase ("statičke
+metode"), te dodatne pomoćne varijable. Pokazivač do klasnog objekta moguće
+je dobiti i pozivom na C funkciju \texttt{NSClassFromString()}. Slanjem
+metode \texttt{alloc} (ekvivalent \texttt{calloc()}) i zatim \texttt{init}
+(ekvivalent tijela C++ konstruktora), moguće je instancirati novu klasu
+koristeći naziv klase zapisan u string.
+
+Štoviše, moguće je dinamički graditi i selektore koristeći
+\texttt{NSSelectorFromString()}, a čak i (uz dovoljno niski pristup) graditi
+i bilo kakav niz argumenata koji bi stali u C-ov konstrukt "\texttt{...}"
+(često opisno zvano "tri-točkice"), odnosno u \textit{variadic arguments}.
 
+%%
+\section{Biblioteka Foundation}
+
+Sam jezik i njegov \textit{runtime} ne koriste previše bez osnovnih klasa
+koje mogu u obliku objekata umjesto nizova bajtova sadržavati stringove i
+nizove, odnosno (na nešto višoj razini) sadržavati setove i asocijativna
+polja.
+
+Biblioteka Foundation implementirana je nekoliko puta tijekom vremena:
+originalna NeXTova biblioteka je danas dio sustava Cocoa pod Mac OS X,
+još u 1990ima Foundation je implementiran i kao dio sustava GNUstep pod
+slobodnim operacijskim sustavima (GNU/Linux, FreeBSD), a u kasnim
+2000ima pojavljuje se i Cocotron koji primarno cilja Windows sustave.
+
+Klasa \texttt{NSString} enkapsulira \textit{unicode} stringove. To znači
+da dok god programer ostaje u svijetu \texttt{NSString}, ne mora brinuti o
+načinu enkodiranja niza \textit{unicode} kodnih točaka; tek pri uvođenju
+bajtova u ili izvozu bajtova iz ove klase potrebno je brinuti o načinu
+kodiranja \engl{encoding}. Tipično će se izvesti kao \texttt{UTF-8}.
+
+Zanimljivo je da ta klasa nudi i neke neočekivane dodatne metode koje uistinu
+olakšaju kodiranje aplikacija; primjerice, \texttt{lastPathComponent} vraća
+zadnji element UNIX staze -- korisno za dohvat naziva datoteke. Također,
+\texttt{stringByDeletingPathExtension} vraća novi string u kojem je izbrisana
+ekstenzija datoteke (ako je postojala). Za dohvat C-ovskog stringa najčešće
+se koristi dohvat UTF-8 enkodiranih bajtova kroz metodu \texttt{UTF8String},
+a stvaranje se radi s \texttt{[NSString stringWithUTF8String:string]} ili
+\texttt{[[NSString alloc] initWithUTF8String:string]}. Konstantni
+\texttt{NSString} literal stvara se prefiksiranjem znaka \texttt{@} ispred
+C-ovskog string literala: \texttt{@"primjer"}.
+
+Ovoj klasi nije moguće mijenjati sadržaj; ako se string mora moći mijenjati,
+tada se koristi \texttt{NSMutableString}.
+
+Klasa \texttt{NSArray} opisuje polje. U najnovijoj reviziji jezika moguće
+je stvoriti novi \texttt{NSArray} koristeći sintaksu u redu 1 listinga
+\ref{lst:nsarray}. Odprije podržana varijanta nalazi se u redu 2 i koristi
+obično slanje poruke i C-ove \textit{variadic arguments}.
+
+\begin{lstlisting}[caption=Primjeri za \texttt{NSArray},
+  label=lst:nsarray
+]
+NSArray * a = @[@"a", @"b", @5];
+NSArray * b = [NSArray arrayWithObjects:@"a", @"b", @5, nil];
+\end{lstlisting}
+
+\texttt{NSArray} je ustvari tzv. \textit{class cluster}, odnosno
+pri alokaciji klase ne znamo koju ćemo ustvari klasu dobiti. Definirano je
+samo to da je dobivena klasa podklasa \texttt{NSArray} (kako bi funkcionirala
+metoda \texttt{isKindOfClass:}).
+
+Slično klasi za stringove, \texttt{NSMutableArray} je podklasa koja se
+može mijenjati. Također se radi o \textit{class clusteru}.
+
+Klasa \texttt{NSDictionary} služi za spremanje asocijativnog polja -- mape
+ključeva na vrijednosti. Inicijalizira se koristeći
+\texttt{initWithObjectsAndKeys:}, kao u listingu \ref{lst:nsdictionary}.
+U \texttt{NSMutableDictionary} se vrijednosti postavljaju koristeći 
+\texttt{setValue:forKey:}. Ova metoda je implementirana i u \texttt{NSObject}
+kao alternativni način za pozivanje \textit{setter} metoda.
+
+\begin{lstlisting}[caption=Primjeri za \texttt{NSArray},
+  label=lst:nsarray
+]
+NSDictionary * a = @{@"a" : @"A", @"b", : @5];
+NSDictionary * b = [NSDictionary dictionaryWithObjectsAndKeys:
+                    @"A", @"a", @5, @"b", nil];
+NSMutableDictionary * c = [NSMutableDictionary dictionary];
+[c setValue:@"5" forKey:@"aNumber"];
+\end{lstlisting}
+
+Gore navedene klase mogu se učitati iz posebno formatirane datoteke
+koristeći \texttt{initWithContentsOfURL:}.
+
+Brojevi se u Objective-C objekte pakiraju koristeći \textit{class cluster}
+\texttt{NSNumber}. Objekti se pakiraju metodama poput \texttt{numberWithInt:}.
+Svrha takvog pakiranja je dobivanje pokazivača koji će može smjestiti u
+\texttt{NSDictionary}, \texttt{NSArray} i ostale kolekcije, kao i na druga
+mjesta na kojima se očekuje smještanje pokazivača na Objective-C objekte
+koji mogu primiti poruke tipa \texttt{retain}, \texttt{release} i slično.
+
+Neke od drugih često korištenih klasa u Foundationu su \texttt{NSURL} koji 
+pakira URLove, \texttt{NSURLConnection} i \texttt{NSUndoManager}.
 
+%%
 \section{\textit{Application bundle}}
 
-\section{Arhitektura orijentirana prema dokumentima}
+Aplikacije se na OS X rijetko distribuiraju kao instalacijski paket.
+Obično se distribuiraju kao .zip datoteke ili kao .dmg slika diska. Unutar
+navedenih formata spremaju se mape koje imaju ekstenziju .app.
+
+Operacijski sustav OS X podržava koncept koji se naziva \textit{bundle}.
+To su mape koje operacijski sustav po ekstenziji prepoznaje kao dokumente
+umjesto kao mape, te ih otvara koristeći pojedinu aplikaciju umjesto
+koristeći pretraživač datoteka.
 
+Posebna vrsta \textit{bundlea} jest .app bundle. Radi se o mapi s ekstenzijom
+.app u kojoj se nalazi izvršna datoteka (pod OS X je u formati Mach-O),
+datoteka Info.plist koja određuje atribute aplikacije (što se u nekim drugim 
+sustavima zna spremati u resurse izvršne datoteke). Također, sadrži sve
+druge resurse i nesistemske biblioteke potrebne za izvršavanje aplikacije.
+
+To omogućuje distribuiranje cijele aplikacije kroz "jednu ikonu", a da
+programer i dalje otvara pojedine resurse koristeći klasične POSIX funkcije
+za pristup datotekama bez udara na performanse. Sve slike, baze podataka
+i biblioteke lako su dostupne, a teoretski ih i korisnik može zamijeniti --
+sve bez upotrebe posebnih alata.
+
+%%
 \section{Osnovni koncepti AppKita}
 
+AppKit je osnovna biblioteka za stvaranje grafičkog sučelja na Mac OS X.
+Implementirana je i u već spomenutim sustavima GNUstep i Cocotron.
+
+Glavni objekt u aplikaciji nije prozor, već "glavni izbornik". Pod OS X,
+radi se o traci na vrhu glavnog ekrana. Pod GNUstepom, izbornik ovisno o temi
+može biti uključen u prozore, može lebdjeti kao zasebni prozor ili biti
+globalan kao i pod OS X. Pod Cocotronom, izbornici su uključeni u prozore.
+
+Izbornici su implementirani kroz klasu \texttt{NSMenu}, a stavke na njima
+kroz \texttt{NSMenuItem}.
+
+Ostalo sučelje u principu zahtjevaju postojanje prozora. Prozori su 
+reprezentirani kroz klasu \texttt{NSWindow} odnosno podklase poput 
+\texttt{NSPanel}. Unutar prozora, postoji glavni sadržajni pogled 
+\engl{content view}.
+
+Pogledi \engl{views} su osnovni elementi sučelja reprezentirani kroz klasu
+\texttt{NSView}, a reprezentiraju pravokutnu površinu unutar prozora ili
+unutar drugog pogleda.
+
+Podklasiranjem se dolazi do tipki \texttt{NSButton} (što uključuje i
+\textit{checkbox}, \textit{radio button}, itd.), do okvira za unos teksta
+\texttt{NSTextField}, područja za uređivanje teksta \texttt{NSTextView},
+okvira s tabovima \texttt{NSTabView}, tablice sa stupcima 
+\texttt{NSTableView}, itd.
+
+Sadržajni pogled unutar prozora uvijek poprima veličinu prozor, dok je osnovni 
+koncept promjene veličine pogleda u odnosu na roditeljski pogled nazvan
+"opruge i podupirači" \engl{springs and struts}. U svakom smjeru (iznad,
+ispod, lijevo, desno) može se odrediti da li je promjena udaljenosti u odnosu
+na roditelja fiksna ili dinamična; dodatno, za širinu i visinu također se
+određuje da li je promjena fiksna ili dinamična. Koristeći ova svojstva, te
+uz kvalitetnu hijerarhiju pogleda, može se dobiti kvalitetno korisničko 
+sučelje koje na adekvatan način mijenja veličinu, a sve bez pisanja i jednog
+retka koda.
+
+Gradnja korisničkog sučelja u osnovi se radi kroz Interface Builder. Radi se
+o alatu koji je odnedavno ugrađen u integrirano razvojno okruženje Xcode,
+a koje producira .xib datoteke. Navedene datoteke prevode se u .nib datoteke,
+a reprezentiraju serijalizirano stablo objekata, uključujući objekte
+grafičkog sučelja.
+
+.xib datoteke mogu zalijepiti dodatna svojstva i veze na jedan vlasnički 
+objekt te dodatne veze prema drugim metaobjektima \engl{placeholder objects} 
+poput \texttt{NSApplication} ili \texttt{NSFirstResponder}. Za sve ostale 
+objekte, lijepe se svojstva i veze između objekata prema potrebi. Objekti
+se pri učitavanju prvo deserijaliziraju, zatim im se postave međusobne veze,
+te se konačno objektima poziva metoda \texttt{awakeFromNib}, ako postoji.
+
+Zadnja bitna stvar su \texttt{NSArrayController} i ostali kontroler-objekti,
+te povezivanje \engl{binding} objekata s kontrolerima. Takozvani \textit{Cocoa
+Bindings} koristi tehniku \textit{key-value observing} radi automatskog
+slanja notifikacija u kontrolerima odnosno u elementima sučelja da se dogodila
+promjena nekog svojstva. To se postiže određenim \textit{runtime} promjenama
+poziva \textit{setter} metoda (odnosno zakrpavanjem istih), iako to programer
+ne primijeti kao zakrpavanje; KVO se jednostavno događa.
+
+Zatim, kada se promjena dogodi, koristeći \textit{key-value coding} u koji
+spadaju \texttt{valueForKey:} i prethodno spomenuti \texttt{setValue:forKey:}
+postavlja se nova vrijednost drugog atributa, time sinkronizirajući 
+vrijednosti u dva povezana objekta.
+
+%%
+\section{Arhitektura orijentirana prema dokumentima}
+
+Jedna od posebnosti Cocoa i ostalih okruženja izvedenih iz OPENSTEPa (poput
+GNUstep i Cocotron) jest i arhitektura orijentirana prema dokumentima
+\engl{document-oriented architecture}.
+
+Pri otvaranju dokumenta, \textit{singleton} objekt klase
+\texttt{NSApplication} koristi \textit{singleton} objekt klase 
+\texttt{NSDocumentController}. Taj objekt prema zatraženoj radnji može
+ili stvarati novi dokument određenog tipa, ili otvarati postojeći dokument.
+
+Pri stvaranju ili otvaranju dokumenta potrebno je znati kojeg tipa će biti
+taj dokument. To se može (pri otvaranju) saznati iz ekstenzije. U datoteci
+Info.plist u \textit{application bundleu} nalazi se popis podržanih ekstenzija
+mapiranih na klase kojima se ta datoteka može otvoriti. (U vlastitoj podklasi
+\texttt{NSDocumentController} programer može napraviti drugačije otvaranje
+dokumenta, ili možda i zabraniti otvaranje dodatnog dokumenta.)
+
+Otvaranje dokumenta \texttt{NSDocumentController} vrši instanciranjem klase
+za rukovanje određenim tipom dokumenta. Ta klasa može instancirati
+\texttt{NSWindowController} za rukovanje prozorom, može učitati .nib datoteku
+kojoj je vlasnik ta klasa, ili učiniti nešto treće za inicijalizaciju.
+Cilj je da klasa otvori prozor.
+
+Navedena klasa je podklasa klase \texttt{NSDocument}. Ove klase implementiraju
+nekoliko metoda koje služe spremanju i učitavanju datoteka i 
+\textit{bundleova}. Najjednostavnije varijante, posebno za male datoteke koje 
+se u potpunosti mogu lako serijalizirati, su \texttt{dataOfType:error:}
+pozivom na koju pozivatelj može od dokumenta zatražiti podatke za spremanje
+na disk, te \texttt{readFromData:ofType:error:} pozivom na koju pozivatelj
+može od dokumenta zatražiti učitavanje podataka. Učitavanje i spremanje se 
+kod ovih dviju metoda radi iz instanci klasa \texttt{NSData} -- nizovi bajtova
+koje pozivatelj učitava s diska ili iz drugog izvora i nudi klasi na daljnje
+procesiranje.
+
+U slučaju potrebe, pozivatelj može pružati i URL i druge objekte koji
+reprezentiraju datoteke, te dokument može učitati podatke i na drugi način.
+
+Svaki dokument prati koju datoteku je otvorio. Prijedljuje do svojstvo i 
+prozoru, a to omogućava navođenje naziva datoteke u naslovnoj traci,
+kao i klikanje desnim klikom na naziv datoteke kako bi se u iskočnom
+izborniku pojavila staza do datoteke.
+
+Usko vezana za dokumentima orijentiranu arhitekturu je i klasa 
+\texttt{NSUndoManager}. Ova klasa vezana je uz svaki \texttt{NSDocument},
+a dokumentima je izrazito zanimljiva zbog automatskog praćenja da li je
+u dokumentu došlo do promjena (odnosno treba li omogućiti spremanje,
+treba li korisniku preporučiti da ne mijenja dokument jer je zaključan za
+promjene, i slično). Korisniku je klasa zanimljiva jer omogućava vraćanje
+radnji unazad. Programer to čini tako da po promjeni u vezani \textit{undo
+manager} registrira zahtjev za dodavanjem "invokacije" na stog. Invokacija
+sadrži odredišni objekt, selektor i sve argumente koji će se pozvati za
+poništavanje željene radnje. (Metoda koja se izvršava za poništavanje dužna
+je također registrirati radnju za vraćanje, a koja će se umjesto na 
+\textit{undo} stog dodati na \textit{redo} stog.)
+
+Prednost dizajna aplikacije koristeći dokumentima orijentiranu arhitekturu 
+iskazuje se u mogućnosti da operacijski sustav može prepoznati neke od detalja
+rada aplikacije, te bez intervencije programera u novoj verziji operacijskog
+sustava izmijeni dio ponašanja aplikacije. Primjer toga daje se u 
+odjeljku \ref{lion}.
+
+\section{Izmjene dokumentne arhitekture u sustavima Lion i 
+Mountain Lion} 
+\label{lion}
+
+Ukoliko je programer valjano izradio aplikaciju koristeći dokumentima
+orijentiranu arhitekturu, uključujući korištenje \texttt{NSUndoManager},
+bez dodatnog truda je dobio sljedeće ponašanje:
+
+\begin{itemize}
+\item Korisnik ne mora razmišljati o spremanju. Spremanje se radi automatski
+pri izlasku iz aplikacije, pri zatvaranju dokumenta, te pri prebacivanju
+fokusa na drugu aplikaciju.
+\item Odabirom opcije Save korisnik ustvari traži izradu \textit{checkpointa}.
+\item Korisnik dobiva mogućnost pretraživanja starih verzija dokumenta po
+\textit{checkpointima} koristeći sučelje koje se pojavljuje desno od
+imena datoteke. Kroz isto sučelje može odabrati i "Lock".
+\item Od Mountain Liona, spremanje je moguće u iCloud (ako se aplikacija 
+distribuira kroz Mac App Store).
+\item Moguće je lako dupliciranje koristeći odabir komande Duplicate. To je
+preferirana zamjena za Save As.
+\item Od Liona, ako se dokument otvara kroz Finder, pojavljuju se male i
+brze animacije otvaranja i zatvaranja dokumenta, radi poboljšanja
+korisničkog iskustva.
+\end{itemize}
+
+Čim se u pojedinoj klasi \texttt{NSDocument} doda klasna metoda
+\texttt{autosavesInPlace} koja vraća \textit{boolean} vrijednost
+\texttt{YES}, iz izbornika s naslovom "File" uklanjaju se stavke
+"Save", "Save As" i zamjenjuju stavkama "Save A Version", "Duplicate" i
+"Revert To".
+
+Izuzetno je korisno to da se navedene promjene događaju "magično", ali
+istovremeno sve je promjene moguće shvatiti, ali i spriječiti. Korisnik
+dobiva sustav u kojem, nakon što programer doda jednu metodu, odjednom
+ne mora brinuti o spremanju već to sustav u potpunosti radi za njega.
+A u slučaju potrebe vraćanja na stariju verziju, korisnik i dalje može doći
+do nje na jednostavan način.
+
 %%%%%%%%%%%%%%%%%%%%%%
 % Biblioteka libclang
 \chapter{Biblioteka libclang}
 
+Preferirani prevoditelj za programski jezik C koji se koristi u projektu
+LLVM zove se Clang. Po prelasku centralnog projekta GCC kojeg održava
+Free Software Foundation na licencu GPLv3, Apple je odlučio prestati
+korištenje novijih verzija. Apple je ostao na verziji 4.2.1. Izlaskom
+Xcode 4, prelaze na Clang.
+
+Interna arhitektura Clanga je izuzetno moderna. Primjerice, leksička
+i sintaksna analiza je izdvojena od faze kompajliranja. Provođenje
+leksičke i sintaksne analize moguće je, umjesto kroz prevoditelj, obavljati
+kroz izdvojenu biblioteku "libclang".
+
+Osim dohvaćanja rezultata leksičke, sintaksne i semantičke analize, kroz
+libclang moguće je vrlo detaljno dohvatiti i dijagnostičke poruke. Uz
+dubok pristup u apstraktno sintaksno stablo, programeru se omogućava analiza
+svakog simbola u datoteci (doznavanje što je ispod kursora), koreliranje
+upotrebe simbola s njegovom deklaracijom (primjerice, moguće je saznati
+gdje je deklarirana varijabla koja se nalazi ispod kursora, te saznati gdje
+se sve koristi), i slično.
+
+Konačno, ono što libclang čini idealnim za upotrebu u integriranim razvojnim
+sučeljima ili u tekst editorima jest lagana upotreba za kolorizaciju,
+te API za dohvat rezultata za \textit{autocomplete}.
+
+\section{Inicijalizacija i parsiranje}
+Prva radnja koju je potrebno obaviti jest kreiranje indeksa. Indeks je
+set prijevodnih jedinica \engl{translation units} koje bi po povezivanju
+činile jedan izvršni modul, primjerice izvršnu datoteku ili biblioteku.
+Indeks bi reprezentirao jedan projekt.
+
+Po kreiranju indeksa, potrebno je u indeks dodati bar jednu prijevodnu
+jedinicu. Prilikom dodavanja indeksa potrebno je propustiti sve opcije 
+komandne linije koje bi se propuštale u prevoditelja. Ovime se vrši
+leksička, sintaksna i semantička analiza prijevodne jedinice, a i povezivanje
+radi krosreferenciranja između prijevodnih jedinica u kompleksnijem projektu. 
+Pri potrebi ponovnog parsiranja, možemo upotrijebiti bržu funkciju za ponovno
+parsiranje. 
+
+Sve opisano se može vidjeti u listingu \ref{lst:libclanginit}.
+
+\begin{lstlisting}[caption=Inicijalizacija i parsiranje u libclang,
+  label=lst:libclanginit
+]
+// kreiranje indeksa
+CXIndex clangIndex = clang_createIndex(0, 0);
+
+// inicijalno parsiranje
+size_t argCount = 1;
+char * args = { "-x objective-c" };
+CXTranslationUnit clangTranslationUnit =
+    clang_parseTranslationUnit(clangIndex,
+                               "/staza/do/objectivec/datoteke.m",
+                               args, argCount,
+                               NULL, 0,
+                               clang_defaultEditingTranslationUnitOptions());
+
+// dopunjavanje
+struct CXUnsavedFile unsavedFile;
+unsavedFile.Contents = 
+    "#include <stdio.h>\n"
+    "int main()\n"
+    "{"
+    "    printf(\"Hello world\n\");\n;";
+    "    return 0;"
+    "}";
+unsavedFile.Filename = "/staza/do/objectivec/datoteke.m";
+unsavedFile.Length = strlen(unsavedFile.Contents);
+clang_reparseTranslationUnit(
+    clangTranslationUnit,
+    1, &unsavedFile, 
+    clang_defaultReparseOptions(clangTranslationUnit));
+
+// oslobadjanje memorije
+clang_disposeIndex(clangIndex);
+clang_disposeTranslationUnit(clangTranslationUnit);
+\end{lstlisting}
+
+\section{Prolazak po \textit{tokenima}}
+Tokeni ili simboli su rezultat leksičke analize.
+
+Prije prolaska po tokenima, potrebno je tokenizirati prijevodnu jedinicu.
+To se vrši s \texttt{clang\_tokenize()}. Kao raspon koji tokeniziramo
+gotovo sigurno navodimo kompletnu datoteku.
+
+Ovdje dolazimo do zanimljivosti: kako jedinstveno opisati svaku lokaciju
+i raspon unutar jednog indeksa? libclang to čini koristeći strukture nazvane
+\texttt{CXSourceLocation} i \texttt{CXSourceRange}. Jedinstveno označavanje
+datoteke na koju se lokacija odnosno raspon odnosi vrši se koristeći 
+strukturu \texttt{CXFile}. 
+
+Po tokenizaciji, kao rezultat dobivamo pokazivač na polje struktura
+\texttt{CXToken} te broj elemenata u navedenoj strukturi. Za prolazak se
+stoga koristi jednostavna \texttt{for} petlja kao u listingu
+\ref{lst:libclangtokeni}.
+
+\begin{lstlisting}[caption=Prolazak po tokenima,
+  label=lst:libclangtokeni,
+  float=htbp % http://tex.stackexchange.com/a/2282/25747
+]
+// kreiranje 'entireFileRange' kako bi tokenizirali cijelu datoteku
+CXFile file = clang_getFile(clangTranslationUnit, 
+                            "/staza/do/objectivec/datoteke.m");
+CXSourceLocation start = clang_getLocationForOffset(clangTranslationUnit, 
+                                                    file, 0);
+CXSourceLocation end = clang_getLocationForOffset(clangTranslationUnit, 
+                                                  file,
+                                                  strlen(contents));
+CXSourceRange entireFileRange = clang_getRange(start, end);
+
+// tokeniziranje
+CXToken * tokens;
+unsigned int numTokens;
+clang_tokenize(self.codeCompletionTranslationUnit, entireFileRange, 
+               &tokens, &numTokens);
+
+// prolazak po tokenima
+for(int i = 0; i < numTokens; i++)
+{
+    CXToken token = tokens[i];
+
+    // rad s tokenom ... npr:
+    CXTokenKind kind = clang_getTokenKind(token);
+    switch(kind)
+    {
+        case CXToken_Keyword:
+        ......
+        break;
+    }
+
+    CXSourceRange range = clang_getTokenExtent(clangTranslationUnit, token);    
+    CXSourceLocation start = clang_getRangeStart(range);
+    CXSourceLocation end = clang_getRangeEnd(range);
+    
+    unsigned int startOffset, endOffset;
+    clang_getSpellingLocation(start, file, NULL, NULL, &startOffset);
+    clang_getSpellingLocation(end, file, NULL, NULL, &endOffset);
+
+    // ....
+}
+\end{lstlisting}
+
+
+\section{Prolazak po kursorima}
+Prolazak po kursorima, rezultatima sintaksne i semantičke analize, je
+kompleksniji nego prolazak po tokenima.
+
+Kursori označavaju jedan čvor u apstraktnom sintaksnom stablu kombiniran
+s nešto semantičke analize. S obzirom da se radi o stablu, način za prolazak
+kroz kursore uključuje rekurziju. Uvodi se koncept posjetitelja 
+\engl{visitor}, \textit{callback} funkcije koja se poziva kako bi pozvala
+pojedine čvorove stabla odnosno tokene. Pri svakom posjetu, može se zatražiti
+prekid posjećivanja, nastavak posjećivanja na istoj razini ili ulazak na
+dublju razinu.
+
+Koncept razine se uvodi kako bi se istovremeno omogućilo razumijevanje 
+naredbi na višoj razini ("ovo je deklaracija varijable") kao i na nižoj
+razini ("ovo je naziv tipa podataka, naziv varijable, znak jednakosti, te
+numerička vrijednost").
+
+Primjer se može vidjeti u listingu \ref{lst:libclangkursori}.
+
+\begin{lstlisting}[caption=Prolazak po kursorima,
+  label=lst:libclangkursori,
+  float=htbp % http://tex.stackexchange.com/a/2282/25747
+]
+// pozivanje posjetitelja
+CXCursor korijen = clang_getTranslationUnitCursor(clangTranslationUnit);
+void * dodatniPodatak = NULL;
+clang_visitChildren(korijen, childVisitor, dodatniPodatak);
+
+// posjetitelj
+enum CXChildVisitResult childVisitor(CXCursor cursor,
+                                     CXCursor parent,
+                                     CXClientData client_data)
+{
+    enum CXCursorKind cursorKind = clang_getCursorKind(cursor);
+    CXFile file = clang_getFile(clangTranslationUnit, 
+                                "/staza/do/objectivec/datoteke.m");
+
+    CXSourceRange range = clang_getCursorExtent(cursor);
+    
+    CXSourceLocation start = clang_getRangeStart(range);
+    CXSourceLocation end = clang_getRangeEnd(range);
+
+    unsigned int startOffset;
+    unsigned int endOffset;
+    CXFile startFile;
+    CXFile endFile;
+    clang_getSpellingLocation(start, &startFile, NULL, NULL, &startOffset);
+    clang_getSpellingLocation(end, &endFile, NULL, NULL, &endOffset);
+    if(startFile != file || endFile != file)
+        // za kolorizaciju ne zelimo analizirati kursore iz drugih datoteka,
+        // primjerice onih ukljucenih (#include) u trenutnu prijevodnu
+        // jedinicu
+        return CXChildVisit_Continue;
+
+    enum CXChildVisitResult result = CXChildVisit_Continue;
+    enum Boja boja = BOJA_BEZ_PROMJENE;
+    switch(cursorKind)
+    {
+        case CXCursor_CXXMethod:
+            result = CXChildVisit_Recurse;
+            break;
+        case CXCursor_FieldDecl:
+            result = CXChildVisit_Recurse;
+            break;
+        ...
+        ...
+        ...
+        case CXCursor_TypeRef:
+            c = BOJA_NARANCASTA;
+            break;
+        ...
+        ...
+        default:
+            
+    }
+
+}
+ \end{lstlisting}
+\section{Autokompletiranje}
+
+
 %%%%%%%%%%%%%%%%%
 % Pregled aplikacije
 \chapter{Pregled aplikacije}
 
+"Editor Teksta" je minimalistički uređivač teksta s podrškom za kolorizaciju
+sintakse. Izgrađen je koristeći dokumentnu arhitekturu sustava Cocoa,
+a za obradu izvornog koda i bojanje sintakse koristi libclang.
+
 %%%%%%%%%%%
 % Zaključak
 \chapter{Zaključak}