195640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org#!/usr/bin/env python
295640e3a20adea634b4df4ccf8c93f411184c438joi@chromium.org# Copyright (c) 2012 The Chromium Authors. All rights reserved.
301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Use of this source code is governed by a BSD-style license that can be
401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# found in the LICENSE file.
501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''The 'grit resize' tool.
701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''
801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport getopt
1001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgimport os
1101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
1201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import grd_reader
1301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import pseudo
1401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit import util
15ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.orgfrom grit.format import rc
1601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgfrom grit.format import rc_header
17b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.orgfrom grit.node import include
18b9161407f737461b5db16a29782f8a31d19e602dbenrg@chromium.orgfrom grit.tool import interface
1901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
2101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Template for the .vcproj file, with a couple of [[REPLACEABLE]] parts.
2201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgPROJECT_TEMPLATE = '''\
2301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<?xml version="1.0" encoding="Windows-1252"?>
2401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org<VisualStudioProject
2501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	ProjectType="Visual C++"
2601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	Version="7.10"
2701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	Name="[[DIALOG_NAME]]"
2801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	ProjectGUID="[[PROJECT_GUID]]"
2901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	Keyword="Win32Proj">
3001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	<Platforms>
3101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org		<Platform
3201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			Name="Win32"/>
3301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	</Platforms>
3401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	<Configurations>
3501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org		<Configuration
3601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			Name="Debug|Win32"
3701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			OutputDirectory="Debug"
3801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			IntermediateDirectory="Debug"
3901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			ConfigurationType="1"
4001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			CharacterSet="2">
4101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org		</Configuration>
4201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	</Configurations>
4301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	<References>
4401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	</References>
4501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	<Files>
4601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org		<Filter
4701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			Name="Resource Files"
4801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
4901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
5001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			<File
5101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org				RelativePath=".\[[DIALOG_NAME]].rc">
5201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org			</File>
5301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org		</Filter>
5401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	</Files>
5501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	<Globals>
5601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org	</Globals>
5701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org</VisualStudioProject>'''
5801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
5901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
6001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Template for the .rc file with a couple of [[REPLACEABLE]] parts.
6101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# TODO(joi) Improve this (and the resource.h template) to allow saving and then
6201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# reopening of the RC file in Visual Studio.  Currently you can only open it
6301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# once and change it, then after you close it you won't be able to reopen it.
6401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgRC_TEMPLATE = '''\
6501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// This file is automatically generated by GRIT and intended for editing
6601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// the layout of the dialogs contained in it.  Do not edit anything but the
6701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// dialogs.  Any changes made to translateable portions of the dialogs will
6801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// be ignored by GRIT.
6901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
7001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include "resource.h"
7101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#include <winresrc.h>
7201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#ifdef IDC_STATIC
7301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#undef IDC_STATIC
7401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#endif
7501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define IDC_STATIC (-1)
7601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
7701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgLANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
7801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
7901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#pragma code_page([[CODEPAGE_NUM]])
8001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org[[INCLUDES]]
8201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org[[DIALOGS]]
8401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''
8501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
8701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org# Template for the resource.h file with a couple of [[REPLACEABLE]] parts.
8801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgHEADER_TEMPLATE = '''\
8901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// This file is automatically generated by GRIT.  Do not edit.
9001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
9101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#pragma once
9201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
9301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org// Edit commands
9401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_CLEAR                   0xE120
9501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_CLEAR_ALL               0xE121
9601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_COPY                    0xE122
9701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_CUT                     0xE123
9801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_FIND                    0xE124
9901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_PASTE                   0xE125
10001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_PASTE_LINK              0xE126
10101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_PASTE_SPECIAL           0xE127
10201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_REPEAT                  0xE128
10301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_REPLACE                 0xE129
10401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_SELECT_ALL              0xE12A
10501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_UNDO                    0xE12B
10601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org#define ID_EDIT_REDO                    0xE12C
10701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
10901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org[[DEFINES]]
11001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''
11101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
11201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
11301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgclass ResizeDialog(interface.Tool):
11401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  '''Generates an RC file, header and Visual Studio project that you can use
11501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgwith Visual Studio's GUI resource editor to modify the layout of dialogs for
11601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgthe language of your choice.  You then use the RC file, after you resize the
11701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgdialog, for the language or languages of your choice, using the <skeleton> child
11801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgof the <structure> node for the dialog.  The translateable bits of the dialog
11901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgwill be ignored when you use the <skeleton> node (GRIT will instead use the
12001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgtranslateable bits from the original dialog) but the layout changes you make
12101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgwill be used.  Note that your layout changes must preserve the order of the
12201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgtranslateable elements in the RC file.
12301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgUsage: grit resize [-f BASEFOLDER] [-l LANG] [-e RCENCODING] DIALOGID*
12501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
12601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgArguments:
12701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  DIALOGID        The 'name' attribute of a dialog to output for resizing.  Zero
12801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  or more of these parameters can be used.  If none are
12901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  specified, all dialogs from the input .grd file are output.
13001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgOptions:
13201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  -f BASEFOLDER   The project will be created in a subfolder of BASEFOLDER.
13401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  The name of the subfolder will be the first DIALOGID you
13501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  specify.  Defaults to '.'
13601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
13701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  -l LANG         Specifies that the RC file should contain a dialog translated
13801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  into the language LANG.  The default is a cp1252-representable
13901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  pseudotranslation, because Visual Studio's GUI RC editor only
14001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  supports single-byte encodings.
14101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
14201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  -c CODEPAGE     Code page number to indicate to the RC compiler the encoding
14301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  of the RC file, default is something reasonable for the
14401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  language you selected (but this does not work for every single
14501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  language).  See details on codepages below.  NOTE that you do
14601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  not need to specify the codepage unless the tool complains
14701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  that it's not sure which codepage to use.  See the following
14801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  page for codepage numbers supported by Windows:
14901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  http://www.microsoft.com/globaldev/reference/wincp.mspx
15001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
15101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  -D NAME[=VAL]   Specify a C-preprocessor-like define NAME with optional
15201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  value VAL (defaults to 1) which will be used to control
15301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                  conditional inclusion of resources.
15401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
15501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
15601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgIMPORTANT NOTE:  For now, the tool outputs a UTF-8 encoded file for any language
15701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgthat can not be represented in cp1252 (i.e. anything other than Western
15801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgEuropean languages).  You will need to open this file in a text editor and
15901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgsave it using the codepage indicated in the #pragma code_page(XXXX) command
16001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.orgnear the top of the file, before you open it in Visual Studio.
16101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
16201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org'''
16301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
16401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  # TODO(joi) It would be cool to have this tool note the Perforce revision
16501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  # of the original RC file somewhere, such that the <skeleton> node could warn
16601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  # if the original RC file gets updated without the skeleton file being updated.
16701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
16801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  # TODO(joi) Would be cool to have option to add the files to Perforce
16901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
17001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def __init__(self):
17101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.lang = pseudo.PSEUDO_LANG
17201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.defines = {}
17301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.base_folder = '.'
17401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.codepage_number = 1252
17501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.codepage_number_specified_explicitly = False
17601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
17701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def SetLanguage(self, lang):
17801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Sets the language code to output things in.
17901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
18001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.lang = lang
18101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if not self.codepage_number_specified_explicitly:
18201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      self.codepage_number = util.LanguageToCodepage(lang)
18301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
18401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def GetEncoding(self):
18501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if self.codepage_number == 1200:
18601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      return 'utf_16'
18701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if self.codepage_number == 65001:
18801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      return 'utf_8'
18901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return 'cp%d' % self.codepage_number
19001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
19101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def ShortDescription(self):
19201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    return 'Generate a file where you can resize a given dialog.'
19301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
19401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def Run(self, opts, args):
19501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.SetOptions(opts)
19601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
19701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    own_opts, args = getopt.getopt(args, 'l:f:c:D:')
19801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for key, val in own_opts:
19901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if key == '-l':
20001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.SetLanguage(val)
20101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if key == '-f':
20201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.base_folder = val
20301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if key == '-c':
20401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.codepage_number = int(val)
20501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.codepage_number_specified_explicitly = True
20601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if key == '-D':
20777cbaa8b1f1af05d8ba2c2a951c74e7909318830joi@chromium.org        name, val = util.ParseDefine(val)
20801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        self.defines[name] = val
20901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
21001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    res_tree = grd_reader.Parse(opts.input, debug=opts.extra_verbose)
21101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    res_tree.OnlyTheseTranslations([self.lang])
212ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    res_tree.RunGatherers()
21301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
21401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Dialog IDs are either explicitly listed, or we output all dialogs from the
21501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # .grd file
21601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    dialog_ids = args
21701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if not len(dialog_ids):
21801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      for node in res_tree:
21901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org        if node.name == 'structure' and node.attrs['type'] == 'dialog':
22001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org          dialog_ids.append(node.attrs['name'])
22101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
22201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.Process(res_tree, dialog_ids)
22301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
22401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def Process(self, grd, dialog_ids):
22501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''Outputs an RC file and header file for the dialog 'dialog_id' stored in
22601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    resource tree 'grd', to self.base_folder, as discussed in this class's
22701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    documentation.
22801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
22901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    Arguments:
23001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      grd: grd = grd_reader.Parse(...); grd.RunGatherers()
23101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      dialog_ids: ['IDD_MYDIALOG', 'IDD_OTHERDIALOG']
23201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    '''
233783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org    grd.SetOutputLanguage(self.lang)
234783385ad40d453977d8b9d537e204f851e21591abenrg@chromium.org    grd.SetDefines(self.defines)
23501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
23601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    project_name = dialog_ids[0]
23701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
23801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    dir_path = os.path.join(self.base_folder, project_name)
23901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    if not os.path.isdir(dir_path):
24001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      os.mkdir(dir_path)
24101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
24201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # If this fails then we're not on Windows (or you don't have the required
24301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # win32all Python libraries installed), so what are you doing mucking
24401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # about with RC files anyway? :)
24501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    import pythoncom
24601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
24701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Create the .vcproj file
24801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    project_text = PROJECT_TEMPLATE.replace(
24901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      '[[PROJECT_GUID]]', str(pythoncom.CreateGuid())
25001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      ).replace('[[DIALOG_NAME]]', project_name)
25101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    fname = os.path.join(dir_path, '%s.vcproj' % project_name)
25201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.WriteFile(fname, project_text)
25301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    print "Wrote %s" % fname
25401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
25501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Create the .rc file
25601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Output all <include> nodes since the dialogs might depend on them (e.g.
25701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # for icons and bitmaps).
25801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    include_items = []
259ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    for node in grd.ActiveDescendants():
26001b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      if isinstance(node, include.IncludeNode):
261ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org        include_items.append(rc.FormatInclude(node, self.lang, '.'))
26201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    rc_text = RC_TEMPLATE.replace('[[CODEPAGE_NUM]]',
26301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org                                  str(self.codepage_number))
26401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    rc_text = rc_text.replace('[[INCLUDES]]', ''.join(include_items))
26501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
26601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Then output the dialogs we have been asked to output.
26701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    dialogs = []
26801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    for dialog_id in dialog_ids:
26901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      node = grd.GetNodeById(dialog_id)
270ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      assert node.name == 'structure' and node.attrs['type'] == 'dialog'
27101b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org      # TODO(joi) Add exception handling for better error reporting
272ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org      dialogs.append(rc.FormatStructure(node, self.lang, '.'))
27301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    rc_text = rc_text.replace('[[DIALOGS]]', ''.join(dialogs))
27401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
27501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    fname = os.path.join(dir_path, '%s.rc' % project_name)
27601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.WriteFile(fname, rc_text, self.GetEncoding())
27701b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    print "Wrote %s" % fname
27801b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
27901b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    # Create the resource.h file
280ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    header_defines = ''.join(rc_header.FormatDefines(grd))
281ccda47032903a6550dac2921f88c51b4da55aa36benrg@chromium.org    header_text = HEADER_TEMPLATE.replace('[[DEFINES]]', header_defines)
28201b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    fname = os.path.join(dir_path, 'resource.h')
28301b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    self.WriteFile(fname, header_text)
28401b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org    print "Wrote %s" % fname
28501b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org
28601b3bc768461bd303bff39f8cd1663682254e407joi@chromium.org  def WriteFile(self, filename, contents, encoding='cp1252'):
287b654b234a783f69b237f319c8cbfceb1ad2bb585joi@chromium.org    with open(filename, 'wb') as f:
288b654b234a783f69b237f319c8cbfceb1ad2bb585joi@chromium.org      writer = util.WrapOutputStream(f, encoding)
289b654b234a783f69b237f319c8cbfceb1ad2bb585joi@chromium.org      writer.write(contents)
290