1 #include <QApplication>
2 #include <QString>
3 #include <QProcess>
4 #include <iostream>
5 #include <getopt.h>
6 #include "download.h"
7 #include "resourcemanager.h"
8 #include "viewer.h"
9 #include "config.h"
10 #include "dbus/dbus.h"
11 
12 using namespace std;
13 
14 
print_version()15 static void print_version() {
16 	cout << "katarakt version 0.2" << endl;
17 }
18 
print_help(char * name)19 static void print_help(char *name) {
20 	cout << "Usage:" << endl;
21 	cout << "  " << name << " ([OPTIONS] FILE|(-u URL))*" << endl;
22 	cout << endl;
23 	cout << "Options:" << endl;
24 	cout << "  -u, --url                         Open a URL instead of a local file" << endl;
25 	cout << "  -p, --page NUM                    Start showing page NUM" << endl;
26 	cout << "  -f, --fullscreen                  Start in fullscreen mode" << endl;
27 	cout << "  -q, --quit true|false             Quit on initialization failure" << endl;
28 	cout << "  -s, --single-instance true|false  Whether to have a single instance per file" << endl;
29 	cout << "  --write-default-config FILE       Write the default configuration to FILE and exit" << endl;
30 	cout << "  -v, --version                     Print version information and exit" << endl;
31 	cout << "  -h, --help                        Print this help and exit" << endl;
32 }
33 
main(int argc,char * argv[])34 int main(int argc, char *argv[]) {
35 	QApplication app(argc, argv);
36 
37 	// parse command line options
38 	struct option long_options[] = {
39 		{"url",						no_argument,		NULL,	'u'},
40 		{"page",					required_argument,	NULL,	'p'},
41 		{"fullscreen",				no_argument,		NULL,	'f'},
42 		{"quit",					required_argument,	NULL,	'q'},
43 		{"single-instance",			required_argument,	NULL,	's'},
44 		{"write-default-config",	required_argument,	NULL,	0},
45 		{"help",					no_argument,		NULL,	'h'},
46 		{"version",					no_argument,		NULL,	'v'},
47 		{NULL, 0, NULL, 0}
48 	};
49 	int option_index = 0;
50 	bool download_url = false;
51 	while (1) {
52 		int c = getopt_long(argc, argv, "+up:fq:hs:v", long_options, &option_index);
53 		if (c == -1) {
54 			break;
55 		}
56 		switch (c) {
57 			case 0: {
58 				const char *option_name = long_options[option_index].name;
59 				if (!strcmp(option_name, "write-default-config")) {
60 					CFG::write_defaults(optarg);
61 					return 0;
62 				}
63 				break;
64 			}
65 			case 'u':
66 				download_url = true;
67 				break;
68 			case 'p':
69 				// currently no warning message on wrong input
70 				CFG::get_instance()->set_tmp_value("start_page", atoi(optarg) - 1);
71 				break;
72 			case 'f':
73 				CFG::get_instance()->set_tmp_value("fullscreen", true);
74 				break;
75 			case 'q':
76 				// use locale for everything from the command line
77 				CFG::get_instance()->set_tmp_value("Settings/quit_on_init_fail", QString::fromLocal8Bit(optarg));
78 				break;
79 			case 'h':
80 				print_help(argv[0]);
81 				return 0;
82 			case 's':
83 				// (according to QVariant) any string can be converted to
84 				// bool, so no type check needed here
85 				CFG::get_instance()->set_tmp_value("Settings/single_instance_per_file", QString::fromLocal8Bit(optarg));
86 				break;
87 			case 'c':
88 				CFG::write_defaults(optarg);
89 				return 0;
90 			case 'v':
91 				print_version();
92 				return 0;
93 			default:
94 				// getopt prints an error message
95 				return 1;
96 		}
97 	}
98 
99 	// fork more processes if there are arguments left
100 	if (optind < argc - 1) {
101 		QStringList l;
102 		for (int i = optind + 1; i < argc; i++) {
103 			l << QString::fromLocal8Bit(argv[i]);
104 		}
105 		QProcess::startDetached(QString::fromLocal8Bit(argv[0]), l);
106 	}
107 
108 	QString file;
109 	Download download;
110 	if (argv[optind] != NULL) {
111 		if (download_url) {
112 			file = download.load(QString::fromLocal8Bit(argv[optind]));
113 		} else {
114 			file = QString::fromLocal8Bit(argv[optind]);
115 		}
116 		if (file.isNull()) {
117 			return 1;
118 		}
119 	} else if (CFG::get_instance()->get_most_current_value("Settings/quit_on_init_fail").toBool()) {
120 		print_help(argv[0]);
121 		return 1;
122 	}
123 	// else: opens empty window without file
124 
125 	if (CFG::get_instance()->get_most_current_value("Settings/single_instance_per_file").toBool()) {
126 		if (activate_katarakt_with_file(file)) {
127 			return 0;
128 		}
129 	}
130 
131 	// load stylesheet from config if no stylesheet was specified on the command line
132 	if (app.styleSheet().isEmpty()) {
133 		app.setStyleSheet(CFG::get_instance()->get_value("Settings/stylesheet").toString());
134 	}
135 
136 	Viewer katarakt(file);
137 	if (!katarakt.is_valid()) {
138 		return 1;
139 	}
140 	katarakt.show();
141 
142 	// initialize dbus interfaces
143 	dbus_init(&katarakt);
144 
145 	return app.exec();
146 }
147 
148