#ifndef KADU_MISC_H
#define KADU_MISC_H

#include <qcstring.h>
#include <qdatetime.h>
#include <qdialog.h>
#include <qfiledialog.h>
#include <qfont.h>
#include <qfontinfo.h>
#include <qiconset.h>
#include <qimage.h>
#include <qlabel.h>
#include <qmap.h>
#include <qpair.h>
#include <qpixmap.h>
#include <qstringlist.h>
#include <qsocket.h>
#include <qstring.h>
#include <qtextbrowser.h>
#include <qtooltip.h>
#include <qvaluelist.h>
#include <qvariant.h>

#include <inttypes.h>

#include "config_file.h"
#include "gadu.h"

class QComboBox;
class QLineEdit;
class QMenuData;

/**
	\fn QString ggPath(const QString &subpath="")
	Zmienia ścieżkę relatywną do katalogu z ustawieniami gg
	na ścieżkę bezwzgledną uwzględniając zmienne środowiskowe
	\c $HOME i \c $CONFIG_DIR.
	Funkcja ta jest przydatna, gdy chcemy się odwołać do jakiegoś
	pliku/katalogu znajdującego się w katalogu ustawień aktualnej
	sesji Kadu.
	\param subpath ścieżka relatywna do katalogu z ustawieniami gg
	\return ścieżkę bezwzględną do pliku.
	
	<b>Przykład:</b>
	\code
	MessageBox::msg(ggPath("kadu.conf"));
	\endcode
	Wyświetlone zostanie okienko z pełną ścieżką do pliku konfiguracyjnego Kadu.
**/
QString ggPath(const QString &subpath="");

/**
	\fn QString dataPath(const QString &f = "", const char *argv0 = 0)
	Zwraca bezwzględną ścieżkę do danego pliku.
	Jeżeli drugi parametr jest różny od 0, to funkcja próbuje najpierw ustalić
	ścieżkę na podstawie \arg argv0, które ma być równe argv[0], oraz zmiennej PATH.
	\param f nazwa pliku (ścieżka relatywna do katalogu z danymi Kadu) do którego
			ma zostać zwrócona pełna, bezwzględna ścieżka.
	\param argv0 nazwa uruchomionego programu. Może to być zarówno '<i>kadu</i>',
			jak i '<i>kadu-kopia2</i>'. Domyślnie jest równy 0.
	\return ścieżkę bezwzględną do pliku.
**/
QString dataPath(const QString &f = "", const char *argv0 = 0);

class UserListElement;

/**
	\fn QString cp2unicode(const unsigned char *buf)
	Podmienia w danym łańcuchu znaki z kodowania CP1250
	na kodowanie Unicode.
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QString cp2unicode(const unsigned char *);

/**
	\fn QCString unicode2cp(const QString &buf)
	Podmienia w danym łańcuchu znaki z kodowania Unicode
	na kodowanie CP1250.
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QCString unicode2cp(const QString &);

/**
	\fn QString latin2unicode(const unsigned char *buf)
	Podmienia w danym łańcuchu znaki z kodowania Latin2
	na kodowanie Unicode.
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QString latin2unicode(const unsigned char *);

/**
	\fn QCString unicode2latin(const QString &buf)
	Podmienia w danym łańcuchu znaki z kodowania Latin2
	na kodowanie Unicode.
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QCString unicode2latin(const QString &buf);

/**
	\fn QString unicode2std(const QString &buf)
	Podmienia w danym łańcuchu polskie znaki z kodowania Unicode
	na ich odpowiedniki w kodowaniu ISO8859-2, czyli zmienia
	\a ń na \a n, \a ó na \a o, \a ś na s, itd.
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QString unicode2std(const QString &);

/**
	\fn QString unicodeUrl2latinUrl(const QString &buf)
	Zamienia kodowanie polskich znaków z utf-8 na kodowanie latin-2
	przy pomocy QUrl::encode.
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QString unicodeUrl2latinUrl(const QString &buf);

/**
	\fn QString unicode2latinUrl(const QString &buf)
	Zamienia polskie znaki na format latin2 "URL" (czyli do postaci %XY,
	akceptowanej przez adresy URL).
	\param buf łańcuch znaków do przekodowania
	\return przekodowany łańcuch.
**/
QString unicode2latinUrl(const QString &buf);

/**
	\fn QString printDateTime(const QDateTime &datetime)
	Formatuje datę i czas do postaci czytelnej człowiekowi,
	czyli <tt>HH:MM:SS (DD.MM.YYYY)</tt>.
	\param datetime konkretna data, którą należy sformatować
	\return sformatowaną datę.
**/
QString printDateTime(const QDateTime &datetime);

/**
	\fn QString timestamp(time_t customtime = 0)
	Formatuje stempel czasowy w postaci 2 dat: aktualna oraz podana.
	Ma on postać: <tt>HH:MM:SS (DD.MM.YYYY) /S HH:MM:SS (DD.MM.YYYY)</tt>,
	gdzie pierwsza data oznacza aktualną datę pobieraną podczas wykonywania tej funkcji,
	a druga data to data podana jako argument i sformatowatowana przez funkcję unicode2latinUrl.
	Znacznik \c /S jest zwykłym łańcuchem '/S'.
	\param customtime czas podany w formie sekund od początku roku 1970 (tzw. '<I>unixtime</i>'),
			który jest sformatowany i zwrócony jako druga data.
	\return sformatowany stempel czasowy
**/
QString timestamp(time_t = 0);

/**
	\fn QDateTime currentDateTime()
	Funkcja służąca łatwemu pobieraniu aktualnej daty.
	\return aktualną datę.
**/
QDateTime currentDateTime();

/**
	\fn QString pwHash(const QString &tekst)
	Funkcja hashująca zadany łańcuch tak, aby nie był od łatwy do odczytania
	dla człowieka, bez uprzedniego potraktowania go w odpowiedni sposób.
	\param tekst łańcuch który ma zostać zahashowany
	\return zahashowany łańcuch
**/
QString pwHash(const QString &tekst);

/**
	\fn QString translateLanguage(const QApplication *application, const QString &locale, const bool l2n)
	Tłumaczy nazwy skrótowe języków na ich pełne nazwy i vice versa, czyli przykładowo
	\c pl przetłumaczy na \c Polski, a \c Polski przetłumaczy na \c pl.
	Jeśli podane wyrażenie nie może zostać odnalezione w tablicy tyłumaczeń, wtedy zwracany jest
	odpowiednia nazwa dla języka angielskiego.
	\param application obiekt aplikacji Qt, który ma przetłumaczyć. Zwykle jest to \c qApp
	\param locale wyrażenie, które ma zostać odpowiednio przetłumaczone. Może to być:
			\c pl, \c en, \c de, \c it, ale również:
			\c Polski, \c Angielski, \c Niemiecki, \c Włoski
	\param l2n określa, czy parametr \a locale jest wersją 2-literową (\c true), czy pełną nazwą (\c false)
	\return słowo odpowiadające podanemu argumentowi \a locale.
**/
QString translateLanguage(const QApplication *application, const QString &locale, const bool l2n);

/**
	\fn void openWebBrowser(const QString &link)
	Otwiera domyślną przeglądarkę i wybiera w niej podany adres.
	\param link adres URL, który ma być otwarty w przeglądarce
**/
void openWebBrowser(const QString &link);

/**
	\fn QString formatGGMessage(const QString &msg, int formats_length, void *formats, UinType sender)
	Formatuje wiadomość protokołu GG do postaci HTML (pogróbienie, kursywa, podkreślenie, kolor).
	\param msg treść wiadomości
	\param formats_length długość parametrów formatujących (szczegóły w dokumentacji libgadu)
	\param formats wskaźnik do struktur formatujących (szczegóły w dokumentacji libgadu)
	\param sender UIN kontaktu, który ma być użyty do sformatowania wiadomości (przychodzącej)
	\return gotową wiadomość sformatowaną w HTMLu.
**/
QString formatGGMessage(const QString &msg, unsigned int formats_length, void *formats, UinType sender);

/**
	\fn QString unformatGGMessage(const QString &msg, int &formats_length, void *&formats)
	Formatuje wiadomość z postaci HTML do formatu akceptowanego przez protokół GG.
	\param msg treść wiadomości ze znacznikami HTML
	\param formats_length zmienna typu integer, do której zapisana zostanie długość
			parametrów formatujących (szczegóły w dokumentacji libgadu)
	\param formats wskaźnik, pod którym zapisane zostaną struktury formatujące
			wiadomość (szczegóły w dokumentacji libgadu)
	\return treść wiadomości z usuniętymi znacznikami HTML (są one teraz zakodowane
			w \a formats i \a formats_length ).
**/
QString unformatGGMessage(const QString &msg, unsigned int &formats_length, void *&formats);

/**
	\fn QString parse(const QString &s, const UserListElement &ule, bool escape = true)
	Podmienia odpowiednie znaczniki w danym łańcuchu według danych podanego kontaktu.
	Dozwolone są następujące znaczniki podstawowe:
	\arg \c %%s status
	\arg \c %%t status w orginalnej (nie przetłumaczonej) formie.
	\arg \c %%d opis (lub pusty łańcuch jeśli opisu nie ma)
	\arg \c %%i adres IP (jeśli znany, inaczej pusty łańcuch)
	\arg \c %%v adres DNS (jeśli znany, inaczej pusty łańcuch)
	\arg \c %%o jeśli kontakt ma użytkownika Kadu na liście, to ten znacznik podmieniany jest na pojedynczą spację
	\arg \c %%p port (jeśli znany, inaczej pusty łańcuch)
	\arg \c %%u numer UIN
	\arg \c %%n pseudonim
	\arg \c %%a nazwa wyświetlana
	\arg \c %%f imię
	\arg \c %%r nazwisko
	\arg \c %%m numer telefonu komórkowego
	\arg \c %%g grupa (lub kilka grup oddzielonych przecinkiem)
	\arg \c %%e adres e-mail
	\arg \c %%x maksymalny rozmiar obrazka w KB
	\arg \c %%% pojedynczy znak '%'

	Ponadto można stosować nawiasy \c [] i \c {}, oraz apostrofy: \c `'.

	Nawiasy kwadratowe pozwalają na używanie swego rodzaju instrukcji warunkowej,
	która sprawdza czy wszystkie (bez wyjątku) znaczniki zawarte pomiędzy tymi
	nawiasami zwróciły wartość niepustą. Jeśli tak, to w miejsce nawiasów wstawiany
	jest po prostu łańcuch zawarty między nimi (z podmienionymi już znacznikami),
	jeśli natomiast któryś ze znaczników zwrócił wartość pustą (np. %o, co oznaczało
	by że kontakt nie ma użytkownika Kadu na liście), to w miejsce nawiasów wstawiana
	jest wartość pusta.

	Nawiasy klamrowe natomiast sprawdzają, czy nazwa pliku - podana jako pierwszy wyraz zawarty
	w tych nawiasach - istnieje. Jeśli tak, to w miejsce tych nawiasów wstawiany jest cały łańcuch
	między nimi zawarty, za wyjątkiem tej pierwszej nazwy pliku (i odstępu po niej). Jeśli natomiast
	plik nie istnieje, to wstawiany jest pusty łańcuch.

	Wreszcie apostrofy ` i '. Dzięki nim można wykonać polecenie w powłoce systemu, a to co zwróci
	ta komenda, zostanie wstawione w miejsce całego wyrażenia między apostrofami (łącznie z nimi samymi).

	\param s łańcuch ze znacznikami do podmiany
	\param ule obiekt reprezentujący kontakt, którego dane będą podstawiane pod znaczniki
	\param escape wartość logiczna decydująca o tym, czy znaczniki HTML mają zostać zinterpretowane (\c false)
			czy też potraktować je jako zwykły tekst (\c true).
	\return łańcuch z podstawionymi danymi zamiast znaczników
**/
QString parse(const QString &s, const UserListElement &ule, bool escape = true);

/**
	\fn void stringHeapSort(QStringList &c)
	\internal
	Funkcja sortująca odpowiednio listę łańcuchów.
	\todo Jakie to dokładnie sortowanie?
**/
void stringHeapSort(QStringList &c);

/**
	\fn QStringList toStringList(const QString &e1, const QString &e2=QString(), const QString &e3=QString(), const QString &e4=QString(), const QString &e5=QString())
	Łączy dowolną liczbę (nie większą niż 5) łańcuchów QString w jedną listę QStringList.
	\param e1 pierwszy łańcuch, wymagany
	\param e2 drugi łańcuch opcjonalny
	\param e3 trzeci łańcuch opcjonalny
	\param e4 czwarty łańcuch opcjonalny
	\param e5 piąty łańcuch opcjonalny
	\return obiekt reprezentujący listę podanych łańcuchów
**/
QStringList toStringList(const QString &e1, const QString &e2=QString(), const QString &e3=QString(), const QString &e4=QString(), const QString &e5=QString());

/**
	\fn void saveGeometry(const QWidget *w, const QString &section, const QString &name)
	Zapisuje wymiary i położenie wskazanego okna do danej sekcji konfiguracyjnej,
	do klucza o podanej nazwie.
	\param w wskaźnik do obiektu, którego wymiary i położenie mają zostać zapisane
	\param section sekcja pliku konfiguracyjnego, w której ma się znaleźć wpis
	\param name nazwa klucza, w jakim mają być zapisane te dane
**/
void saveGeometry(const QWidget *w, const QString &section, const QString &name);

/**
	\fn void loadGeometry(QWidget *w, const QString &section, const QString &name, int defaultX, int defaultY, int defaultWidth, int defaultHeight)
	Ładuje wymiary i położenie z podanej sekcji i klucza i aplikuje je do podanego okna.
	\param w wskaźnik do obiektu, do którego odczytane wymiary i położenie mają zostać zastosowane
	\param section sekcja pliku konfiguracyjnego, z którego dane będą czytane
	\param name nazwa klucza, z którego dane będą czytane
	\param defaultX domyślna wartość pozycji lewego górnego rogu okna w poziomie (gdy brakuje wpisu w pliku konfiguracyjnym)
	\param defaultY domyślna wartość pozycji lewego górnego rogu okna w pionie (gdy brakuje wpisu w pliku konfiguracyjnym)
	\param defaultWidth domyślna wartość szerokości okna (gdy brakuje wpisu w pliku konfiguracyjnym)
	\param defaultHeight domyślna wartość wysokości okna (gdy brakuje wpisu w pliku konfiguracyjnym)
**/
void loadGeometry(QWidget *w, const QString &section, const QString &name, int defaultX, int defaultY, int defaultWidth, int defaultHeight);

/**
	\fn QString toPlainText(const QString &text)
	Usuwa znaki nowego wiersza, oraz tagi HTMLa (wszystko co da się dopasować jako wyrażenie regularne: \c <.*> ).
	\param text łańcuch do przetworzenia
	\return łańcuch z usuniętymi odpowiednimi znakami.
**/
QString toPlainText(const QString &text);

/**
	\var extern QFont *defaultFont
	Domyślna czcionka Kadu.
**/
extern QFont *defaultFont;

/**
	\var extern QFontInfo *defaultFontInfo
	Wskaźnik do obiekt zawierającego informacje dotyczące domyślnej czcionki Kadu
**/
extern QFontInfo *defaultFontInfo;

/**
	\var extern QTextCodec *codec_cp1250
	Wskaźnik do kodeka CP1250.
**/
extern QTextCodec *codec_cp1250;

/**
	\var extern QTextCodec *codec_latin2
	Wskaźnik do kodeka Latin2.
**/
extern QTextCodec *codec_latin2;

/**
	Klasa reprezentująca okno wybierania opisów do statusów.
	\class ChooseDescription
	\brief Okno wyboru opisu
**/
class ChooseDescription : public QDialog
{
	Q_OBJECT
	public:
		/**
			\fn ChooseDescription(int nr, QWidget * parent=0, const char * name=0)
			Konstruktor tworzący okno, wczytujący ostatnio ustawiane opisy,
			oraz ustawiający odpowiednią dla statusu ikonę w tym oknie.
			\param nr numer statusu, gdzie:
				\arg \c 1 oznacza status <tt>Dostępny z opisem</tt>
				\arg \c 3 oznacza status <tt>Zajęty z opisem</tt>
				\arg \c 5 oznacza status <tt>Ukryty z opisem</tt>
				\arg \c 7 oznacza status <tt>Niedostępny z opisem</tt>
				\arg <tt>Każdy inny</tt> oznacza status <tt>Niedostępny z opisem</tt>
			\param parent rodzic kontrolki (domyślnie: 0)
			\param name nazwa kontrolki (domyślnie: 0)
		**/
		ChooseDescription ( int nr, QWidget * parent=0, const char * name=0);

		/**
			\fn virtual ~ChooseDescription()
			Domyślny destruktor. Ustawia opis (jeśli kliknięto OK).
		**/
		virtual ~ChooseDescription();

		/**
			\fn void getDescription(QString &dest)
			Funkcja służąca do odczytu treści z pola edycji opisu.
			\param dest obiekt klasy QString, pod którym zapisana zostanie treść
			\warning funkcja nie zwraca łańcucha, a zapisuje go do podanego parametru
		**/
		void getDescription(QString &);

	private:
		QComboBox *desc;
		QLabel *l_yetlen;

	private slots:
		void okbtnPressed();
		void cancelbtnPressed();
		void updateYetLen(const QString&);
};

/**
	Klasa bardzo pomocna, gdy chcemy, aby Kadu udawało przez chwilę przeglądarkę WWW.
	Pozwala na stosunkowo łatwy odczyt danych ze stron, ale także bardziej zaawansowane
	operacje, jak logowanie na stronach metodą POST, czy też poprzez ciasteczka.
	\class HttpClient
	\brief Klient stron WWW
**/
class HttpClient : public QObject
{
	Q_OBJECT

	private:
		QSocket Socket;
		QString Host;
		QString Referer;
		QString Path;
		QByteArray Data;
		QByteArray PostData;
		int StatusCode;
		bool HeaderParsed;

		unsigned int ContentLength;
		bool ContentLengthNotFound;

		QMap<QString, QString> Cookies;

	private slots:
		void onConnected();
		void onReadyRead();
		void onConnectionClosed();

	public slots:
		/**
			\fn void setHost(const QString &host)
			Ustawia adres serwera, z którego będziemy czytać stronę.
			\param host adres hosta w postaci łańcucha
		**/
		void setHost(const QString &host);

		/**
			\fn void get(const QString &path)
			Wysyła zapytanie GET do ustawionego wcześniej serwera.
			\param path ścieżka do dokumentu, który chcemy pobrać z serwera

			<b>Przykład:</b>
			\code
			http_client->get("/galeria/index.html");
			\endcode
		**/
		void get(const QString &path);

		/**
			\fn void post(const QString &path, const QByteArray &data)
			Wysyła do serwera zapytanie typu POST, dodając do niego
			odpowiednie dane.
			\param path ścieżka do dokumentu, który chcemy pobrać z serwera
			\param data parametry, które są przekazane do serwera - zwykle zawierają
					wartości zmiennych z form na uprzednio pobranej stronie.
		**/
		void post(const QString &path, const QByteArray &data);

		/**
			\overload void post(const QString &path, const QString &data)
		**/
		void post(const QString &path, const QString &data);

	public:
		/**
			\fn HttpClient()
			Standardowy konstruktor.
		**/
		HttpClient();

		/**
			\fn int status() const
			\return kod aktualnego statu klienta WWW, zgodny z protokołem HTTP (302, 500, itd).
		**/
		int status() const;

		/**
			\fn const QByteArray &data() const
			Funkcja dająca dostęp do danych reprezentujących kod pobranej strony.
			\return treść pobranej strony.
		**/
		const QByteArray &data() const;

		/**
			\fn static QString encode(const QString &text)
			Zamienia znaki nieakceptowalne w adresie strony na ich odpowiedniki w formie %XY.
			\param text łańcuch reprezentujący adres strony, zawierający spacje, itp
			\return sformatowany łańcuch.
		**/
		static QString encode(const QString &text);

		/**
			\fn const QString &cookie(const QString &name) const
			Funkcja dająca dostęp do danych zawartych w tzw. ciasteczkach.
			\param name nazwa ciasteczka
			\return wartość dla danego ciasteczka.
		**/
		const QString &cookie(const QString &name) const;

		/**
			\fn const QString &cookie(const QString &name) const
			Funkcja dająca dostęp do danych zawartych w tzw. ciasteczkach.
			\return obiekt klasy QMap zawierający sparowane nazwy ciasteczek z ich wartościami.
		**/
		const QMap<QString, QString> &cookies() const;

		/**
			\fn void setCookie(const QString &name, const QString &value)
			Ustawia wartość danego ciasteczka.
			\param name nazwa ciasteczka
			\param value wartość dla danego ciasteczka
		**/
		void setCookie(const QString &name, const QString &value);

	signals:
		/**
			\fn void finished()
			Sygnał emitowany, gdy zapytanie zostanie sfinalizowane.
		**/
		void finished();

		/**
			\fn void redirected(QString link)
			Sygnał emitowany, gdy klient HTTP zostanie przekierowany przez serwer hosta
			na inny adres.
			\param link adres strony na jaki klient został przekierowany
		**/
		void redirected(QString link);

		/**
			\fn void error()
			Sygnał emitowany, gdy wystąpił błąd podczas próby sfninaliowania zapytania.
		**/
		void error();
};

/**
	Klasa reprezentująca dokument HTML. Przechowuje
	listę elementów. Element może być tagiem HTML
	albo kawałkiem tekstu.
	\class HtmlDocument
	\brief Dokument HTML
**/
class HtmlDocument
{
	private:
		/**
			Struktura reprezentująca pojedynczy element dokumentu.
			\struct Element
			\brief Element dokumentu
		**/
		struct Element
		{
			QString text; /*!< treść elementu */
			bool tag; /*!< oznacza, czy element jest takiem HTML, czy zwykłym tekstem */
		};
		QValueList<Element> Elements;
		void addElement(Element e);

	public:
		/**
			\fn static void escapeText(QString& text)
			Zamienia znaki interpretowane przez przeglądarki HTML (tj. \c < , \c > , itd.)
			na ich odpowiedniki zakodowane w HTML (tj. \c &lt; , \c &gt; , itd.).
			\param text obiekt klasy QString zawierający znaki do podmiany
			\warning funkcja nie zwraca łańcucha z podmienionymi znakami,
					a zapisuje go od od razu do podanego obiektu, zmieniając jego zawartość.
		**/
		static void escapeText(QString& text);

		/**
			\fn static void unescapeText(QString& text)
			Zamienia znaki zakodowane w HTML (tj. \c &lt; , \c &gt; , itd.)
			na ich odpowiedniki interpretowane przez przeglądarki HTML (tj. \c < , \c > , itd.).
			\param text obiekt klasy QString zawierający znaki do podmiany
			\warning funkcja nie zwraca łańcucha z podmienionymi znakami,
					a zapisuje go od od razu do podanego obiektu, zmieniając jego zawartość.
		**/
		static void unescapeText(QString& text);

		/**
			\fn void addTag(const QString &text)
			Dodaje podany tekst do listy elementów jako
			tag HTML.
			\param text tekst do dodania
		**/
		void addTag(const QString &text);

		/**
			\fn void addText(const QString &text)
			Dodaje podany tekst do listy elementów jako
			zwykły tekst.
			\param text tekst do dodania
		**/
		void addText(const QString &text);

		/**
			\fn void insertTag(const int pos,const QString &text)
			Wstawia podany tekst do listy elementów jako
			tag HTML przed innym elementem.
			\param pos indeks elementu, przed którym wstawiamy
			\param text tekst do dodania
		**/
		void insertTag(const int pos,const QString &text);

		/**
			\fn void insertText(const int pos,const QString &text)
			Wstawia podany tekst do listy elementów jako
			zwykly tekst przed innym elementem.
			\param pos indeks elementu, przed którym wstawiamy
			\param text tekst do dodania
		**/
		void insertText(const int pos,const QString &text);

		/**
			\fn void parseHtml(const QString& html)
			Parsuje podany napis zgodny ze strukturą HTML
			i otrzymane dane przypisuje do dokumentu.
			@param html napis do skonwertowania
		**/
		void parseHtml(const QString& html);

		/**
			\fn QString generateHtml() const
			Na podstawie zawartości dokumentu generuje
			napis zgodny ze strukturą HTML. Znaki specjalne
			wchodzące w skład elementów nie będących tagami
			HTML są escapowane.
			\return zawartość dokumentu w formacie HTML.
		**/
		QString generateHtml() const;

		/**
			\fn int countElements() const
			\return ilość elementów wchodzących w skład
			dokumentu.
		**/
		int countElements() const;

		/**
			\fn bool isTagElement(int index) const
			Sprawdza czy element o podanym indeksie jest
			tagiem HTML czy zwykłym tekstem.
			\return \c true jeśli jest tagiem HTML, lub \c false gdy jest zwykłym tekstem.
		**/
		bool isTagElement(int index) const;

		/**
			\fn const QString &elementText(int index) const
			\return tekst elementu o podanym indeksie.
		**/
		const QString &elementText(int index) const;

		/**
			\overload QString &elementText(int index)
		**/
		QString &elementText(int index);

		/**
			\fn void setElementValue(int index,const QString& text,bool tag=false)
			Ustawia tekst i typ elementu o podanym indeksie.
			\param index indeks pozycji elementu
			\param text treść elementu
			\param tag czy element ma być interpretowany jako tag HTML (\c true ),
				czy jako zwykły tekst (\c false ). Domyślnie: \c false.
		**/
		void setElementValue(int index,const QString& text,bool tag=false);

		/**
			\fn void splitElement(int& index,int start,int length)
			Wydziela z elementu podany fragment tekstu.
			Element może pozostać jeden albo
			ulec podzieleniu na dwa lub nawet trzy elementy.
			\param index indeks pozycji elementu który będziemy dzielić
			\param start numer znaku, od którego zaczynać ma się wydzielony element
			\param length liczba znaków wchodzących w wydzielony element, poczynając od pozycji \c start
			\note Funkcja zmienia wartość argumentu index, aby
			indeks wydzielonego elementu był aktualny.
		**/
		void splitElement(int& index,int start,int length);

		/**
			\fn void convertUrlsToHtml()
			Skanuje tekst dokumentu w poszukiwaniu adresów WWW,
			np. "www.kadu.net" i zmienia je w linki HTML.
		**/
		void convertUrlsToHtml();
};

/*
	nie używane - patrz opis w pliku .cpp

HtmlDocument GGMessageToHtmlDocument(const QString &msg, int formats_length, void *formats);
void HtmlDocumentToGGMessage(HtmlDocument &htmldoc, QString &msg,
	int &formats_length, void *&formats);
*/

/**
	Klasa reprezentująca kontrolki obrazków.
	\class ImageWidget
	\brief Obrazki
**/
class ImageWidget : public QWidget
{
	Q_OBJECT

	private:
		QImage Image;

	protected:
		/**
			\fn virtual void paintEvent(QPaintEvent *e)
			Funkcja rysująca tą kontrolkę.
			\param e wskaźnik do obiektu reprezentującego zdarzenie rysowania.
		**/
		virtual void paintEvent(QPaintEvent *e);

	public:
		/**
			\fn ImageWidget(QWidget *parent)
			Konstruktor tworzący kontrolkę w innej - podanej kontrolce.
			\param parent kontrolka, w której należy obsadzić
		**/
		ImageWidget(QWidget *parent);

		/**
			\overload ImageWidget(QWidget *parent,const QByteArray &image)
			Konstruktor tworzący kontrolkę w innej - podanej kontrolce,
			oraz rysujący od razu dany obrazek.
			\param parent kontrolka, w której należy obsadzić
			\param image dane zawierające obrazek
		**/
		ImageWidget(QWidget *parent,const QByteArray &image);

		/**
			\fn void setImage(const QByteArray &image)
			Ustawia obrazek kontrolki na zadany.
			\param image dane zawierające obrazek.
		**/
		void setImage(const QByteArray &image);

		/**
			\overload void setImage(const QPixmap &image)
		**/
		void setImage(const QPixmap &image);
};

/**
	Klasa reprezentująca okienko z obrazkiem i polem edycji.
	Jest ona używana do wyświetlania obrazka z bramki SMS Idei,
	aby użytkownik mógł odczytać z niego treść i wpisać ją do pola edycji.
	\brief Odczytywanie treści z obrazka WWW
	\class TokenDialog
**/
class TokenDialog : public QDialog
{
	Q_OBJECT

	public:
		/**
			\fn TokenDialog(QPixmap tokenImage, QDialog *parent = 0, const char *name = 0)
			Konstruktor tworzący okienko wraz z gotowym obrazkiem.
			\param tokenImage obrazek do wyświetlenia
			\param parent rodzic kontrolki (domyślnie: 0)
			\param name nazwa kontrolki (domyślnie: 0)
		**/
		TokenDialog(QPixmap tokenImage, QDialog *parent = 0, const char *name = 0);

		/**
			\fn void getValue(QString &tokenValue)
			Pobiera treść pola edycji spod obrazka.
			\param tokenValue obiekt klasy QString, pod którym zostanie zapisana pobrana treść.
		**/
		void getValue(QString &tokenValue);

	private:
		QLineEdit *tokenedit;
};

/**
	Klasa zarządzająca stylami wyglądu Kadu.
	\class Themes
	\brief Style Kadu
**/
class Themes : public QObject
{
	Q_OBJECT
	private:
		QStringList ThemesList;
		QStringList ThemesPaths;
		QStringList additional;
		QString ConfigName, Name, ActualTheme;
		QMap<QString, QString> entries;
		QStringList getSubDirs(const QString& path) const;
		QString fixFileName(const QString& path,const QString& fn) const;

	public:
		/**
			\fn Themes(const QString& name, const QString& configname, const char *name=0)
			Konstruktor tworzący grupę styli Kadu.
			\param name nazwa grupy styli (\c emoticons , \c sounds , \c icons )
			\param configname nazwa pliku konfiguracyjnego
			\param name nazwa obiektu (domyślnie: 0)
		**/
		Themes(const QString& name, const QString& configname, const char *name=0);

		/**
			\fn QStringList defaultKaduPathsWithThemes() const
			\return domyślną listę ścieżek, w których Kadu trzyma grupy styli.
		**/
		QStringList defaultKaduPathsWithThemes() const;

		/**
			\fn const QStringList &themes() const
			\return listę styli Kadu.
		**/
		const QStringList &themes() const;

		/**
			\fn const QStringList &themes() const
			\return bierzący styl.
		**/
		const QString &theme() const;

		/**
			\fn const QStringList &paths() const
			\return listę ścieżek, w których Kadu trzyma grupy styli.
		**/
		const QStringList &paths() const;

		/**
			\fn const QStringList &additionalPaths() const
			\return listę dodatkowych ścieżek, w których Kadu trzyma grupy styli.
		**/
		const QStringList &additionalPaths() const;

		/**
			\fn QString themePath(const QString& theme="") const
			Pobiera ścieżkę do danego stylu.
			\param theme nazwa stylu (domyślnie: "", co oznacza styl domyślny)
			\return ścieżkę do katalogu podanego stylu
		**/
		QString themePath(const QString& theme="") const;

		/**
			QString getThemeEntry(const QString& name) const
			Pobiera wartość danego wpisu.
			\param name nazwa klucza, dla którego należy pobrać wpis
			\return wpis z danego stylu, o podanym kluczu
			\todo opisać dokładniej co to za wpisy.
		**/
		QString getThemeEntry(const QString& name) const;

	public slots:
		/**
			\fn void setTheme(const QString& theme)
			Ustawia aktualny styl.
			\param theme styl, który ma być ustawiony
		**/
		void setTheme(const QString& theme);

		/**
			\fn void setPaths(const QStringList& paths)
			Ustawia ścieżki dla styli.
			\param paths lista ścieżek
		**/
		void setPaths(const QStringList& paths);

	signals:
		/**
			\fn void themeChanged(const QString& theme)
			Sygnał emitowany, gdy zmieniony został styl.
			\param theme nazwa nowego stylu
		**/
		void themeChanged(const QString& theme);

		/**
			\fn void pathsChanged(const QStringList& list)
			Sygnał emitowany, gdy ścieżki do styli zostały zmienione.
			\param list lista nowych ścieżek
		**/
		void pathsChanged(const QStringList& list);
};

/**
	Klasa zarządzająca zestawami ikon, oraz samymi ikonami.
	Istnieje globalna zmienna - icons_manager_ptr - tak więc tworzenie
	nowych instancji tego obiektu nie jest potrzebne.
	\class IconsManager
	\brief Menadżer ikon
**/
class IconsManager :public Themes
{
	Q_OBJECT
	public:
		/**
			\fn IconsManager(const QString& name, const QString& configname)
			Konstruktor tworzący grupę styli ikon.
			\param name nazwa grupy
			\param configname nazwa pliku konfiguracyjnego
		**/
		IconsManager(const QString& name, const QString& configname);

		/**
			\fn QString iconPath(const QString &name) const
			Tłumaczy nazwę ikony z zestawu na ścieżkę do niej i na odwrót.
			\param name nazwa ikony z zestawu lub scieżka do pliku
					(jeśli zawiera znak '/' to jest interpretowana jako
					scieżka).
			\return pełną ścieżkę do ikony z aktualnego zestawu,
					lub bezposrednio nazwę jeśli jest to pełna ścieżka.
		**/
		QString iconPath(const QString &name) const;

		/**
			\fn const QPixmap & loadIcon(const QString &name)
			Ładuje ikonę z aktualnego zestawu lub z podanego pliku.
			\param name nazwa ikony z zestawu lub ścieżka do pliku
					(jeśli zawiera znak '/' to jest interpretowana jako
					ścieżka).
			\return obiekt klasy QPixmap reprezentujący daną ikonę.
		**/
		const QPixmap & loadIcon(const QString &name);

		/**
			\fn static void initModule()
			Inicjalizuje moduł menadżera ikon.
		**/
		static void initModule();

		/**
			\fn void registerMenu(QMenuData *menu)
			Rejestruje nowe menu.
			\param menu wskaźnik do obiektu danych dla menu
			\todo opisać dokładniej co to za menu.
		**/
		void registerMenu(QMenuData *menu);

		/**
			\fn void registerMenu(QMenuData *menu)
			Wyrejestruje menu.
			\param menu wskaźnik do obiektu danych menu
			\todo opisać dokładniej co to za menu.
		**/
		void unregisterMenu(QMenuData *menu);

		/**
			\fn void registerMenuItem(QMenuData *menu, const QString &caption, const QString &iconName)
			Rejestruje nowy element w menu.
			\param menu wskaźnik do obiektu danych menu
			\param caption tytuł nowego elementu
			\param iconName nazwa ikony dla nowego elementu
		**/
		void registerMenuItem(QMenuData *menu, const QString &caption, const QString &iconName);

		/**
			\fn void unregisterMenuItem(QMenuData *menu, const QString &caption)
			Wyrejestrowuje element z menu.
			\param menu wskaźnik do obiektu danych menu
			\param caption tytuł elementu
		**/
		void unregisterMenuItem(QMenuData *menu, const QString &caption);

	public slots:
		/**
			\fn void clear()
			Czyści zestaw ikon.
		**/
		void clear();

		/**
			\fn void refreshMenus()
			Odświerza menu.
		**/
		void refreshMenus();

	private:
		QMap<QString, QPixmap> icons;
		
		QValueList<QPair<QMenuData *, QValueList<QPair<QString, QString> > > > menus;

	private slots:
		void selectedPaths(const QStringList& paths);
		void onCreateConfigDialog();
		void onApplyConfigDialog();
};

/**
	\var extern IconsManager *icons_manager_ptr
	Wskaźnik do obiektu generalnego zarządcy ikonek Kadu.
**/
//TODO: po wydaniu 0.4 trzeba zmienić nazwę na icons_manager i wywalić define'a
extern IconsManager *icons_manager_ptr;
/**
	\def icons_manager
	Tymczasowy skrót bezpośrednio do obiektu generalnego zarządcy ikonek Kadu,
	zamiast wskaźnika icons_manager_ptr.
**/
#define icons_manager (*icons_manager_ptr)


/**
	Klasa rozwiazujaca problem z powiadomieniem
	o utworzeniu nowej instancji danej klasy.
	Umieszczamy w klasie publiczna statyczna
	zmienna createNotifier klasy CreateNotifier,
	do ktorej mogą się podłączać pozostałe cześci kodu.
	Przed wyjściem z konstruktora wywołujemy metodę:
	\code createNotifier.notify(this); \endcode
	\class CreateNotifier
	\brief Powiadamianie o nowych instancjach klas
**/
class CreateNotifier : public QObject
{
	Q_OBJECT

	public:
		/**
			\fn void notify(QObject* new_object)
			Emituje sygnał do wszystkich obiektów podłączonych do tego obiektu
			informujący o tym, że dany obiekt został utworzony. Funkcja ta powinna
			być wywołana przez nowotworzony obiekt, w jego konstruktorze.
			\param new_object wskaźnik do obiekty, który został utworzony (zwykle podaje się \c this )
		**/
		void notify(QObject* new_object);

	signals:
		/**
			\fn void objectCreated(QObject* new_object)
			Sygnał emitowany, gdy jakiś obiekt wywoła metodę notify() (zwykle z parametrem \c this ).
			\param new_object wskaźnik do nowoutworzonego obiektu
		**/
		void objectCreated(QObject* new_object);
};

/**
	Klasa zarządzająca obrazkami przesyłanymi przez protokół GG.
	\class GaduImagesManager
	\brief Zarządca obrazków protokołu GG
**/
class GaduImagesManager
{
	private:
		struct ImageToSend
		{
			uint32_t size;
			uint32_t crc32;
			QString file_name;
			QDateTime lastSent;
			char *data;
		};
		QMap<QPair<uint32_t, uint32_t>, ImageToSend> ImagesToSend;//size,crc32 -> 

		struct SavedImage
		{
			uint32_t size;
			uint32_t crc32;
			QString file_name;
		};
		QValueList<SavedImage> SavedImages;

	public:
		/**
			\fn static void setBackgroundsForAnimatedImages(HtmlDocument &doc, const QColor &col)
			Ustawia kolor tła dla animowanych obrazków w danym dokumencie.
			\param doc dokument, w którym kolory zostaną ustawione
			\param col kolor tła
		**/
		static void setBackgroundsForAnimatedImages(HtmlDocument &doc, const QColor &col);

		/**
			\fn static QString loadingImageHtml(UinType uin, uint32_t size, uint32_t crc32)
			Generuje odpowiedni kod HTML, który należy wstawić do okna rozmowy, aby pokazać,
			że obrazek jest w trakcie ładowania (przesyłania), oraz ustawia
			odpowiednie parametry znacznika &lt;img&gt; tak, aby można było potem łatwo
			zidentyfikować, jaki obrazek miał być wstawiony w to miejsce.
			W praktyce daje nam znaną klepsydrę.
			\param uin UIN kontaktu wysyłającego obrazek
			\param size rozmiar obrazka
			\param crc32 suma kontrolna obrazka
			\return łańcuch stanowiący kod HTML
		**/
		static QString loadingImageHtml(UinType uin, uint32_t size, uint32_t crc32);

		/**
			\fn static QString imageHtml(const QString& file_name)
			Generuje kod HTML, który należy wstawić do okna rozmowy,
			aby pokazać w nim obrazek.
			\param file_name nazwa pliku obrazka
			\return łańcuch stanowiący kod HTML
		**/
		static QString imageHtml(const QString& file_name);

		/**
			\fn void addImageToSend(const QString& file_name, uint32_t& size, uint32_t& crc32)
			Dodaje obrazek do listy obrazków, które mają być wysłane z kolejną wiadomością.
			\param file_name nazwa pliku obrazka
			\param size rozmiar obrazka
			\param crc32 suma kontrolna obrazka
		**/
		void addImageToSend(const QString& file_name, uint32_t& size, uint32_t& crc32);

		/**
			\fn void sendImage(UinType uin, uint32_t size, uint32_t crc32)
			Wysyła jeden z obrazków znajdujących się na uprzednio przygotowanej liście.
			\param uin numer UIN do które ma być wysłany obrazek
			\param size rozmiar obrazka, który chcemy wysłać
			\param crc32 suma kontrolna obrazka, który chcemy wysłać
		**/
		void sendImage(UinType uin, uint32_t size, uint32_t crc32);

		/**
			\fn QString getImageToSendFileName(uint32_t size, uint32_t crc32)
			Szuka zakolejkowanego obrazka.
			\return nazwę pliku znalezionego obrazka. Zwraca ciąg pusty,
			jeśli obrazek nie został w tej sesji zakolejkowany do wysłania.
		**/
		QString getImageToSendFileName(uint32_t size, uint32_t crc32);

		/**
			\fn QString saveImage(UinType sender, uint32_t size, uint32_t crc32, const QString& filename, const char* data)
			Zapisuje obrazek w katalogu .gg/images.
			\return pełną ścieżkę do zapisanego obrazka.
		**/
		QString saveImage(UinType sender, uint32_t size, uint32_t crc32, const QString& filename, const char* data);

		/**
			\fn QString getSavedImageFileName(uint32_t size, uint32_t crc32)
			Szuka zapisanego obrazka.
			\return zwraca jego nazwę pliku wraz ze ścieżką. Zwraca ciąg pusty,
			jeśli obrazek nie został w tej sesji zapisany.
		**/
		QString getSavedImageFileName(uint32_t size, uint32_t crc32);

		/**
			\fn QString replaceLoadingImages(const QString& text, UinType sender, uint32_t size, uint32_t crc32)
			Podmienia obrazki klepsydr na właściwy obrazek, o ile został on już w całości pobrany.
			Funkcję tą należy wywołać dla każdego niepowtarzalnego obrazka w treści dokumentu.
			\param text treść dokumentu ze znacznikami HTML oznaczającymi klepsydry
			\param sender UIN kontaktu który przysyła obrazki
			\param size rozmiar obrazka który chcemy wstawić
			\param crc32 suma kontrolna obrazka który chcemy wstawić
			\return treść dokumentu z podmienionymi znacznikami HTML
		**/
		QString replaceLoadingImages(const QString& text, UinType sender, uint32_t size, uint32_t crc32);
};

/**
	\var extern GaduImagesManager gadu_images_manager
	Obiekt zarządzający obrazkami przesyłanymi przez protokół Gadu-Gadu.
**/
extern GaduImagesManager gadu_images_manager;

/**
	Klasa służaca do poglądu obrazków podczas wyboru pliku obrazka.
	\class PixmapPreview
	\brief Podgląd obrazków
**/
class PixmapPreview : public QLabel, public QFilePreview
{
	public:
		/**
			\fn PixmapPreview()
			Domyślny konstruktor.
		**/
		PixmapPreview();

		/**
			\fn void previewUrl(const QUrl& url)
			Ustawia podgląd dla danego pliku.
			\param url adres (ścieżka lokalna lub plik w sieci) pliku obrazka
		**/
		void previewUrl(const QUrl& url);
};

/**
	Klasa reprezentująca okno wyboru obrazka do wstawiania.
	\class ImageDialog
	\brief Okno wyboru obrazka
**/
class ImageDialog : public QFileDialog
{
	public:
		/**
			\fn ImageDialog(QWidget* parent)
			Konstruktor tworzący okno danym rodzicem.
			\param parent rodzic kontrolki
		**/
		ImageDialog(QWidget* parent);
};

/**
	Zmodyfikowany QTextBrowser specjalnie na potrzeby Kadu.
	Kliknięcie na linku otwiera ustawioną w konfiguracji przeglądarkę.
	W menu kontekstowym jest dodatkowa opcja "Kopiuj lokację odnośnika".
	Dodatkowo poprawka błędu w Qt.
	\class KaduTextBrowser
	\brief Wyświetlanie wiadomości
**/
class KaduTextBrowser : public QTextBrowser, QToolTip
{
	Q_OBJECT

	private:
		QString anchor;
		int level;
		/**
			this value stores the current highlighted link
			for use with maybeTip(), or is null
		**/
		QString highlightedlink; 	

	private slots:
		void copyLinkLocation();
		void hyperlinkClicked(const QString& link) const;
		void linkHighlighted(const QString &);
		
	protected:
		/**
			\fn QPopupMenu *createPopupMenu(const QPoint &point)
			Wyświetla menu kontekstowe.
			\param point współrzędne punktu, w którym ma znaleźć się lewy górny róg menu kontekstowego
			\return wskaźnik do obiektu menu
		**/
		QPopupMenu *createPopupMenu(const QPoint &point);

		/**
			\fn virtual void drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph)
			Rysuje zawartość kontrolki (wiadomości, separatory, itp).
			\param p wskaźnik do obiektu rysującego
			\param clipx współrzędne poziome lewego górnego rogu prostokąta który zostanie narysowany
			\param clipy współrzędne pionowe lewego górnego rogu prostokąta który zostanie narysowany
			\param clipw szerokość prostokąta który zostanie narysowany
			\param cliph wysokość prostokąta który zostanie narysowany
		**/
		virtual void drawContents(QPainter * p, int clipx, int clipy, int clipw, int cliph);

		/**
			\fn virtual void maybeTip(const QPoint& point)
			Funkcja wyświetlająca podpowiedź.
			\param point współrzędne określające lewy górny róg podpowiedzi
		**/
		virtual void maybeTip(const QPoint&);

		/**
			\fn virtual void contentsMouseReleaseEvent(QMouseEvent * e)
			Emituje sygnał puszczenia przycisku myszy.
			\param e wskaźnik do obiektu reprezentującego zdarzenie myszy
		**/
		virtual void contentsMouseReleaseEvent(QMouseEvent * e);

	public:
		/**
			\fn KaduTextBrowser(QWidget *parent = 0, const char *name = 0)
			Konstruktor standardowy.
			\param parent rodzic kontrolki (domyślnie: 0)
			\param name nazwa kontrolki (domyślnie: 0)
		**/
		KaduTextBrowser(QWidget *parent = 0, const char *name = 0);

		/**
			\fn void setSource(const QString &name)
			Ustawia źródło danych.
			\param name nazwa źródła danych
			\note Tak na prawdę funkcja ta na obecną chwilę nie robi nic.
		**/
		void setSource(const QString &name);

		/**
			\fn void clear()
			Czyści zawartość.
		**/
		void clear() 
		{ 
			setText("");
			//dla QT<3.2 clear() powodowało błąd 
		}

		/**
			\fn void setFont(const QFont& f)
			Ustawia czcionkę.
			\param f obiekt czcionki do ustawienia
		**/
		void setFont(const QFont& f) 	{ QTextBrowser::setFont(f); }

		/**
			\fn void setMargin(int width)
			Ustawia szerokość marginesu.
			\param width liczba pikseli
		**/
		void setMargin(int width);

	public slots:
		/**
			\fn virtual void copy()
			Kopiuje zaznaczoną część do schowka.
		**/
		virtual void copy();

	signals:
		/**
			\fn void mouseReleased(QMouseEvent *e, KaduTextBrowser *sender)
			Dowolny przycisk myszy został zwolniony.
			\param e wskaźnik do obiektu reprezentującego zdarzenie myszy
			\param sender wskaźnik do obiektu, który wyemitował ten sygnał, czyli \c this
		**/
		void mouseReleased(QMouseEvent *e, KaduTextBrowser *sender);
};

/**
	\fn QValueList<int> toIntList(const QValueList<QVariant> &in)
	Konwertuje całą listę wariantów do listy liczb całkowitych za jednym zamachem.
**/
QValueList<int> toIntList(const QValueList<QVariant> &in);

/**
	\fn QValueList<int> toIntList(const QValueList<QVariant> &in)
	Konwertuje całą listę liczb całkowitych do listy wariantów za jednym zamachem.
**/
QValueList<QVariant> toVariantList(const QValueList<int> &in);

/**
	\fn template<class T, class X> QValueList<T> keys(const QMap<T, X> &m)
	Funkcja ta jest reimplementacją funkcji z Qt - QMap::keys(), w celu
	ominięcia błędu krytycznego w Qt.
**/
template<class T, class X> QValueList<T> keys(const QMap<T, X> &m)
{
#if QT_VERSION < 0x030005
    QValueList<T> ret;
    for(QMap<T,X>::const_iterator it = m.begin(), map_end = m.end(); it != map_end; ++it)
        ret.append(it.key());
    return ret;
#else
    return m.keys();
#endif
}

/**
	\fn template<class T, class X> QValueList<X> values(const QMap<T, X> &m)
	Funkcja ta jest reimplementacją funkcji z Qt - QMap::values(), w celu
	ominięcia błędu krytycznego w Qt.
**/
template<class T, class X> QValueList<X> values(const QMap<T, X> &m)
{
#if QT_VERSION < 0x030005
    QValueList<X> ret;
    for(QMap<T,X>::const_iterator it = m.begin(), map_end = m.end(); it != map_end; ++it)
        ret.append(it.data());
    return ret;
#else
    return m.values();
#endif
}

/**
	\fn QString narg(const QString &s, const QString &arg1, const QString &arg2, const QString &arg3=QString(), const QString &arg4=QString())
	Zastępstwo dla arga z QString, które podmienia kolejne %[1-4] w miejscu.

	W QStringu efektem:
	\code QString("%1 odstęp %2").arg("pierwszy %1 tekst").arg("drugi tekst") \endcode
	jest <tt>"pierwszy drugi tekst tekst odstęp %2"</tt>
	a chcielibyśmy żeby było
	<tt>"pierwszy %1 tekst odstęp drugi tekst"</tt>
	co robi właśnie ta funkcja.
**/
QString narg(const QString &s, const QString &arg1, const QString &arg2,
				const QString &arg3=QString(), const QString &arg4=QString());

/**
	\overload QString narg(const QString &s, const QString &arg1, const QString &arg2, const QString &arg3, const QString &arg4, const QString &arg5, const QString &arg6=QString(), const QString &arg7=QString(),const QString &arg8=QString(), const QString &arg9=QString())
**/
QString narg(const QString &s, const QString &arg1, const QString &arg2,
				const QString &arg3, const QString &arg4,
				const QString &arg5, const QString &arg6=QString(),
				const QString &arg7=QString(),const QString &arg8=QString(),
				const QString &arg9=QString());

/**
	\overload QString narg(const QString &s, const QString **tab, int count)
	Uogólniony narg() na większą liczbę parametrów.
	\param count musi być mniejszy lub równy 9
	\param tab tablica \c count wskaźników do QString
**/
QString narg(const QString &s, const QString **tab, int count);

/**
	\fn void printBacktrace(const QString &header="")
	Wypisuje na wyjściu standardowym tzw. <i>backtrace</i>.
	\param header opcjonalna nazwa nagłówka
**/
void printBacktrace(const QString &header="");

/**
	\def VAR(v,x)
	Definiuje nową zmienną v o takim samym typie jak x jednocześnie inicjując ją wartością x.
**/
#define VAR(v,x)	__typeof(x) v=x

/**
	\def FOREACH(i,c)
	Szybsza w zapisaniu pętla \c for .
**/
#define FOREACH(i,c) for(VAR(i, (c).begin()); i!=(c).end(); ++i)

/**
	\def CONST_FOREACH(i,c)
	Szybsza w zapisaniu pętla \c for , operująca na iteratorach stałych lub dynamicznych, w zależności od wersji Qt.
**/
#if QT_VERSION >= 0x030200
#define CONST_FOREACH(i,c) for(VAR(i, (c).constBegin()), _kadu__##i##__end = (c).constEnd(); i!=_kadu__##i##__end; ++i)
#else
#define CONST_FOREACH(i,c) for(VAR(i, (c).begin()), _kadu__##i##__end = (c).end(); i!=_kadu__##i##__end; ++i)
#endif

#endif
